create-sound-files.py 4.01 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
import base64
import mutagen
import mutagen.mp3
import os
import subprocess

from optparse import make_option

from django.core.management.base import BaseCommand, CommandError

from ...models import SoundFile


class Command(BaseCommand):

    option_list = BaseCommand.option_list + (
        make_option('--force',
            action='store_true',
            dest='force',
            default=False,
            help='Create files even if they exist'),
        make_option('--reset-metadata',
            action='store_true',
            dest='reset_metadata',
            default=False,
            help='Reset metadata on all files'),
        make_option('--emission',
            dest='emission',
            metavar='EMISSION',
            default=None,
            help='Process files belonging to emission only'),
        make_option('--episode',
            dest='episode',
            metavar='EPISODE',
            default=None,
            help='Process files belonging to episode only'),
        )

    def handle(self, force, reset_metadata, emission, episode, verbosity, **kwargs):
        self.verbose = (verbosity > 1)

        for soundfile in SoundFile.objects.select_related().exclude(podcastable=False):
            if emission and soundfile.episode.emission.slug != emission:
                continue
            if episode and soundfile.episode.slug != episode:
                continue
fred's avatar
fred committed
47 48
            if soundfile.file is None or not os.path.exists(soundfile.file.path):
                continue
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
            for format in ('ogg', 'mp3'):
                file_path = soundfile.get_format_path(format)
                if not os.path.exists(file_path) or force:
                    self.create(soundfile, format)
                if force or reset_metadata:
                    self.set_metadata(soundfile, format)

    def create(self, soundfile, format):
        file_path = soundfile.get_format_path(format)

        cmd = ['sox', soundfile.file.path, file_path]

        if format == 'ogg':
            cmd[-1:-1] = ['-C', '4'] # q4 (~128kbps)
        elif format == 'mp3':
            cmd[-1:-1] = ['-C', '-4'] # vbr @ ~128kbps

        if self.verbose:
            print 'creating', file_path
            cmd[1:1] = ['--show-progress']
            print '  ', ' '.join(cmd)

        subprocess.call(cmd)

    def set_metadata(self, soundfile, format):
        file_path = soundfile.get_format_path(format)

        if format == 'mp3':
            audio = mutagen.mp3.MP3(file_path, ID3=mutagen.easyid3.EasyID3)
        elif format == 'ogg':
            audio = mutagen.File(file_path)

        if 'comment' in audio:
            del audio['comment']
        if soundfile.fragment is True and soundfile.title:
            audio['title'] = '%s - %s' % (
                    soundfile.episode.title,
                    soundfile.title)
        else:
            audio['title'] = soundfile.episode.title
        audio['album'] = soundfile.episode.emission.title
        audio['artist'] = 'Radio Panik'

        if soundfile.episode.image or soundfile.episode.emission.image:
            image = (soundfile.episode.image or soundfile.episode.emission.image)
            image.file.open()
            if os.path.splitext(image.path)[1].lower() in ('.jpeg', '.jpg'):
                mimetype = 'image/jpeg'
            elif os.path.splitext(image.path)[1].lower() == '.png':
                mimetype = 'image/png'
            else:
                mimetype = None
            if mimetype:
                if format == 'ogg':
                    audio['coverartmime'] = mimetype
                    audio['coverartdescription'] = 'image'
                    audio['coverart'] = base64.encodestring(image.read()).replace('\n', '')
                elif format == 'mp3':
                    audio.save()
                    audio = mutagen.mp3.MP3(file_path)
                    audio.tags.add(mutagen.id3.APIC(
                            encoding=3, description='image',
                            type=3, mime=mimetype, data=image.read()))
            image.close()

        audio.save()