From b44ec973cc6437d447479624a88491756fa1a4a4 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Fr=C3=A9d=C3=A9ric=20P=C3=A9ters?= Date: Sat, 4 Apr 2020 15:11:59 +0200 Subject: [PATCH] add possibility to request higher quality for some podcasts --- .../management/commands/create-sound-files.py | 32 ++++++++++++++- .../migrations/0015_auto_20200404_1510.py | 40 +++++++++++++++++++ emissions/models.py | 7 ++++ 3 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 emissions/migrations/0015_auto_20200404_1510.py diff --git a/emissions/management/commands/create-sound-files.py b/emissions/management/commands/create-sound-files.py index 4bd0000..e59a9f0 100644 --- a/emissions/management/commands/create-sound-files.py +++ b/emissions/management/commands/create-sound-files.py @@ -12,6 +12,19 @@ from django.core.management.base import BaseCommand, CommandError 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): @@ -107,11 +120,26 @@ class Command(BaseCommand): 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) diff --git a/emissions/migrations/0015_auto_20200404_1510.py b/emissions/migrations/0015_auto_20200404_1510.py new file mode 100644 index 0000000..9cedd94 --- /dev/null +++ b/emissions/migrations/0015_auto_20200404_1510.py @@ -0,0 +1,40 @@ +# -*- 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'), + ), + ] diff --git a/emissions/models.py b/emissions/models.py index cca0771..e4903fa 100644 --- a/emissions/models.py +++ b/emissions/models.py @@ -32,6 +32,11 @@ LICENSES = ( ('artlibre', _('Art Libre')), ) +PODCAST_SOUND_QUALITY_LIST = ( + ('standard', _('Standard')), + ('high', _('High')), +) + class WeekdayMixin(object): DAY_HOUR_START = 5 @@ -131,6 +136,8 @@ class Emission(models.Model): 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) -- 2.39.2