Commit fb2afd36 authored by fred's avatar fred

command to create ogg and mp3 files (requires sox and mutagen)

parent fc2eacf4
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
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()
......@@ -228,6 +228,23 @@ class SoundFile(models.Model):
fragment = models.BooleanField(default=False)
title = models.CharField(max_length=200)
def get_format_filename(self, format):
return '%s_%05d__%s.%s' % (
self.episode.slug,
self.id,
(self.fragment and '0' or '1'),
format)
def get_format_path(self, format):
if not self.file:
return None
return '%s/%s' % (os.path.dirname(self.file.path), self.get_format_filename(format))
def get_format_url(self, format):
if not self.file:
return None
return '%s/%s' % (os.path.dirname(self.file.url), self.get_format_filename(format))
class NewsCategory(models.Model):
title = models.CharField(max_length=50)
......
import os
from django.template import Library
register = Library()
@register.filter(name='is_format_available')
def is_available(soundfile, format='ogg'):
if soundfile is None:
return False
sound_path = soundfile.get_format_path(format)
if not sound_path:
return False
return os.path.exists(sound_path)
@register.filter(name='format_url')
def format_url(soundfile, format='ogg'):
return soundfile.get_format_url(format)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment