1 from __future__ import print_function
10 from django.core.management.base import BaseCommand, CommandError
12 from ...models import SoundFile
15 class Command(BaseCommand):
17 def add_arguments(self, parser):
23 help='Create files even if they exist')
24 parser.add_argument('--reset-metadata',
26 dest='reset_metadata',
28 help='Reset metadata on all files')
29 parser.add_argument('--emission',
33 help='Process files belonging to emission only')
34 parser.add_argument('--episode',
38 help='Process files belonging to episode only')
39 parser.add_argument('--copy',
43 help='Copy initial file')
45 def handle(self, force, reset_metadata, copy, emission, episode, verbosity, **kwargs):
46 self.verbose = (verbosity > 1)
49 for soundfile in SoundFile.objects.select_related().exclude(podcastable=False):
50 if emission and soundfile.episode.emission.slug != emission:
52 if episode and soundfile.episode.slug != episode:
55 if soundfile.file is None or not os.path.exists(soundfile.file.path):
57 except ValueError: # no file associated with it
59 for format in ('ogg', 'mp3'):
60 file_path = soundfile.get_format_path(format)
62 if not os.path.exists(file_path) or force:
63 created = self.create(soundfile, format)
64 if created or reset_metadata:
65 self.set_metadata(soundfile, format)
66 if (force or not soundfile.duration) and os.path.exists(soundfile.get_format_path('ogg')):
67 cmd = ['soxi', '-D', soundfile.get_format_path('ogg')]
68 soundfile.duration = int(float(subprocess.check_output(cmd)))
72 def create(self, soundfile, format):
73 file_path = soundfile.get_format_path(format)
74 if not os.path.exists(os.path.dirname(file_path)):
75 os.mkdir(os.path.dirname(file_path))
77 cmd = ['ffmpeg', '-y', '-i', soundfile.file.path]
79 if self.copy and os.path.splitext(soundfile.file.path)[-1].strip('.') == format:
80 shutil.copy(soundfile.file.path, file_path)
84 cmd.extend(['-q:a', '5'])
86 cmd.extend(['-q:a', '4'])
91 print('creating', file_path)
92 print(' ', ' '.join(cmd))
94 cmd[1:1] = ['-loglevel', 'quiet']
97 return os.path.exists(file_path)
99 def set_metadata(self, soundfile, format):
100 file_path = soundfile.get_format_path(format)
102 audio = mutagen.File(file_path, easy=True)
104 if 'comment' in audio:
106 if soundfile.fragment is True and soundfile.title:
107 audio['title'] = '%s - %s' % (
108 soundfile.episode.title,
111 audio['title'] = soundfile.episode.title
112 audio['album'] = soundfile.episode.emission.title
113 audio['artist'] = 'Radio Panik'
115 if soundfile.episode.image or soundfile.episode.emission.image:
116 image = (soundfile.episode.image or soundfile.episode.emission.image)
118 if os.path.splitext(image.path)[1].lower() in ('.jpeg', '.jpg'):
119 mimetype = 'image/jpeg'
120 elif os.path.splitext(image.path)[1].lower() == '.png':
121 mimetype = 'image/png'
126 audio['coverartmime'] = mimetype
127 audio['coverartdescription'] = 'image'
128 audio['coverart'] = base64.encodebytes(image.read()).replace(b'\n', b'').decode('ascii')
129 elif format == 'mp3':
131 audio = mutagen.mp3.MP3(file_path)
132 audio.tags.add(mutagen.id3.APIC(
133 encoding=3, description='image',
134 type=3, mime=mimetype, data=image.read()))