from ...models import SoundFile
+def get_bitrate(filename):
+ p = subprocess.Popen(['mediainfo', '--Inform=Audio;%BitRate%', filename],
+ close_fds=True,
+ stdin=subprocess.PIPE,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE)
+ stdout, stderr = p.communicate()
+ try:
+ return int(stdout) / 1000
+ except ValueError:
+ return None
+
+
class Command(BaseCommand):
def add_arguments(self, parser):
os.symlink(soundfile.file.path, file_path)
return
+ vorbis_rates = [64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 500]
+ orig_bitrate = get_bitrate(soundfile.file.path)
+ vorbis_q = 5
+ mp3_q = 4
+ if orig_bitrate is not None:
+ if soundfile.episode.emission.podcast_sound_quality == 'high':
+ vorbis_q = 9
+ mp3_q = 9
+ # cap quality to original bitrate (using vorbis quality mapping)
+ for i, rate in enumerate(vorbis_rates):
+ if orig_bitrate < rate:
+ vorbis_q = min((i, vorbis_q))
+ mp3_q = min((i, mp3_q))
+ break
+
cmd = ['ffmpeg', '-y', '-i', soundfile.file.path]
if format == 'ogg':
- cmd.extend(['-q:a', '5'])
+ cmd.extend(['-q:a', str(vorbis_q)])
elif format == 'mp3':
- cmd.extend(['-q:a', '4'])
+ cmd.extend(['-q:a', str(mp3_q)])
cmd.append(file_path)
--- /dev/null
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.24 on 2020-04-04 15:10
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('emissions', '0014_auto_20200329_1519'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='emission',
+ name='podcast_sound_quality',
+ field=models.CharField(choices=[('standard', 'Standard'), ('high', 'High')], default='standard', max_length=20, verbose_name='Podcast sound quality'),
+ ),
+ migrations.AlterField(
+ model_name='emission',
+ name='default_license',
+ field=models.CharField(blank=True, choices=[('', 'Unspecified'), ('cc by', 'Creative Commons Attribution'), ('cc by-sa', 'Creative Commons Attribution ShareAlike'), ('cc by-nc', 'Creative Commons Attribution NonCommercial'), ('cc by-nd', 'Creative Commons Attribution NoDerivs'), ('cc by-nc-sa', 'Creative Commons Attribution NonCommercial ShareAlike'), ('cc by-nc-nd', 'Creative Commons Attribution NonCommercial NoDerivs'), ('cc0 / pd', 'Creative Commons Zero / Public Domain'), ('artlibre', 'Art Libre')], default='', max_length=20, verbose_name='Default license for podcasts'),
+ ),
+ migrations.AlterField(
+ model_name='focus',
+ name='current',
+ field=models.BooleanField(default=True, verbose_name='Current'),
+ ),
+ migrations.AlterField(
+ model_name='playlistelement',
+ name='notes',
+ field=models.CharField(blank=True, default='', max_length=200, verbose_name='Notes'),
+ ),
+ migrations.AlterField(
+ model_name='soundfile',
+ name='license',
+ field=models.CharField(blank=True, choices=[('', 'Unspecified'), ('cc by', 'Creative Commons Attribution'), ('cc by-sa', 'Creative Commons Attribution ShareAlike'), ('cc by-nc', 'Creative Commons Attribution NonCommercial'), ('cc by-nd', 'Creative Commons Attribution NoDerivs'), ('cc by-nc-sa', 'Creative Commons Attribution NonCommercial ShareAlike'), ('cc by-nc-nd', 'Creative Commons Attribution NonCommercial NoDerivs'), ('cc0 / pd', 'Creative Commons Zero / Public Domain'), ('artlibre', 'Art Libre')], default='', max_length=20, verbose_name='License'),
+ ),
+ ]
('artlibre', _('Art Libre')),
)
+PODCAST_SOUND_QUALITY_LIST = (
+ ('standard', _('Standard')),
+ ('high', _('High')),
+)
+
class WeekdayMixin(object):
DAY_HOUR_START = 5
default_license = models.CharField(_('Default license for podcasts'),
max_length=20, blank=True, default='', choices=LICENSES)
+ podcast_sound_quality = models.CharField(_('Podcast sound quality'),
+ max_length=20, default='standard', choices=PODCAST_SOUND_QUALITY_LIST)
email = models.EmailField(_('Email'), max_length=254, null=True, blank=True)
website = models.URLField(_('Website'), null=True, blank=True)