From 33c2bde8803f1bd1fd548b0fb65f600197f61ecb Mon Sep 17 00:00:00 2001 From: mkonecny Date: Thu, 30 Dec 2010 18:17:18 -0500 Subject: [PATCH] began adding basic support for OGG files --- pypo/scripts/cue_file.py | 114 ++++++++++++---------- pypo/tests/campcaster-schedule-insert.php | 13 +++ 2 files changed, 78 insertions(+), 49 deletions(-) diff --git a/pypo/scripts/cue_file.py b/pypo/scripts/cue_file.py index 9d9215903..a5f908528 100755 --- a/pypo/scripts/cue_file.py +++ b/pypo/scripts/cue_file.py @@ -5,20 +5,26 @@ """ cue script that gets called by liquidsoap if a file in the playlist gives orders to cue (in/out). eg: -cue_file:cue_in=120.0,cue_out=110.0:annotate:*** +cue_file:cue_in=90.0,cue_out=110.0:annotate:*** -params: path_to_file, cue_in [float, seconds], cue_out [float, sseconds] +cue_in is number of seconds from the beginning of the file. +cue_out is number of seconds from the end of the file. + +params: path_to_file, cue_in [float, seconds], cue_out [float, seconds] returns: path to the cued temp-file examples: calling: ./cue_file.py /storage/pypo/cache/2010-06-25-15-05-00/35.mp3 10 120.095 returns: /tmp/lstf_UwDKcEngvF +In this example, the first 10 seconds and last 120.095 seconds are cut off. The +middle part of the file is returned. + One thing to mention here: The way pypo (ab)uses liquidsoap can bring in some unwanted effects. liquidsoap is built in a way that it tries to collect the needed files to playout in advance. we 'force' liquidsoap to immediately start playing a newly loaded list, so ls has -no time to prepare the files. If a file is played without cues, this does not afect +no time to prepare the files. If a file is played without cues, this does not affect the playout too much. My testing on a lame VM added a delay of +/- 10ms. If the first file in a playlist is cued, the "mp3cut" command takes time to execute. @@ -43,16 +49,16 @@ from datetime import timedelta import os from mutagen.mp3 import MP3 -import mad +from mutagen.oggvorbis import OggVorbis TEMP_DIR = '/tmp/'; -sys.stderr.write('\n** starting mp3 cutter **\n\n') +sys.stderr.write('\n** starting mp3/ogg cutter **\n\n') try: src = sys.argv[1] except Exception, e: - sys.stderr.write('No file givien. sorry.\n') + sys.stderr.write('No file given. Exiting...\n') sys.exit() try: cue_in = float(sys.argv[2]) @@ -67,59 +73,69 @@ except Exception, e: sys.stderr.write('in: %s - out: %s file: %s \n' % (cue_in, cue_out, src)) dst = TEMP_DIR + 'lstf_' + "".join( [random.choice(string.letters) for i in xrange(10)] ) - -# get length of track -""" -madlib is not accurate enough to get the duration. (only goes to seconds, no ms) -so it is not suitable for relative offsets (eg "play until 10s before the end") -it anyway wuld be better to provide this script with absolute times, like -play from 23.234 to 323.321 -""" -# madlib -#mf = mad.MadFile(src) -#dur = float(float(mf.total_time())/1000) - -# mutagen -audio = MP3(src) -dur = round(audio.info.length, 3) +#TODO, there is no checking whether this randomly generated file name already exists! -sys.stderr.write('duration: ' + str(dur) + '\n') +# get length of track using mutagen. +#audio +#command +if src.endswith('.mp3'): + audio = MP3(src) + dur = round(audio.info.length, 3) -cue_out = round(float(dur) - cue_out, 3) + sys.stderr.write('duration: ' + str(dur) + '\n') -str_cue_in = str(timedelta(seconds=cue_in)).replace(".", "+") # hh:mm:ss+mss, eg 00:00:20+000 -str_cue_out = str(timedelta(seconds=cue_out)).replace(".", "+") # + cue_out = round(float(dur) - cue_out, 3) -""" -now a bit a hackish part, don't know how to do this better... -need to cut the digits after the "+" + str_cue_in = str(timedelta(seconds=cue_in)).replace(".", "+") # hh:mm:ss+mss, eg 00:00:20+000 + str_cue_out = str(timedelta(seconds=cue_out)).replace(".", "+") # -""" -ts = str_cue_in.split("+") -try: - if len(ts[1]) == 6: - ts[1] = ts[1][0:3] - str_cue_in = "%s+%s" % (ts[0], ts[1]) -except Exception, e: - pass + """ + now a bit a hackish part, don't know how to do this better... + need to cut the digits after the "+" -ts = str_cue_out.split("+") -try: - if len(ts[1]) == 6: - ts[1] = ts[1][0:3] - str_cue_out = "%s+%s" % (ts[0], ts[1]) -except Exception, e: - pass + """ + ts = str_cue_in.split("+") + try: + if len(ts[1]) == 6: + ts[1] = ts[1][0:3] + str_cue_in = "%s+%s" % (ts[0], ts[1]) + except Exception, e: + pass + + ts = str_cue_out.split("+") + try: + if len(ts[1]) == 6: + ts[1] = ts[1][0:3] + str_cue_out = "%s+%s" % (ts[0], ts[1]) + except Exception, e: + pass + + sys.stderr.write('in: ' + str_cue_in + '\n') + sys.stderr.write('abs: ' + str(str_cue_out) + '\n\n') + + command = 'mp3cut -o %s -t %s-%s %s' % (dst, str_cue_in, str_cue_out, src) +elif src.endswith('.ogg'): + audio = OggVorbis(src) + dur = audio.info.length + sys.stderr.write('duration: ' + str(dur) + '\n') + + cue_out = float(dur) - cue_out + + #convert input format of ss.mmm to milliseconds and to string< + str_cue_in = str(int(round(cue_in*1000))) + + #convert input format of ss.mmm to milliseconds and to string + str_cue_out = str(int(round(cue_out*1000))) + + command = 'oggCut -s %s -e %s %s %s' % (str_cue_in, str_cue_out, src, dst) +else: + sys.stderr.write('File name with invalid extension. Exiting...\n') + sys.exit() -#sys.stderr.write(str(timedelta(seconds=cue_in)).replace(".", "+") + '\n\n') -sys.stderr.write('in: ' + str_cue_in + '\n') -sys.stderr.write('abs: ' + str(str_cue_out) + '\n\n') -command = 'mp3cut -o %s -t %s-%s %s' % (dst, str_cue_in, str_cue_out, src); sys.stderr.write(command + '\n\n\n') -os.system(command + ' >/dev/null') -#shutil.copy2(src, dst) +os.system(command + ' > /dev/null 2>&1') print dst + "\n"; diff --git a/pypo/tests/campcaster-schedule-insert.php b/pypo/tests/campcaster-schedule-insert.php index 0fa1853e9..a9d5767da 100644 --- a/pypo/tests/campcaster-schedule-insert.php +++ b/pypo/tests/campcaster-schedule-insert.php @@ -42,6 +42,18 @@ $pl = new Playlist(); $pl->create($playlistName); // Add a media clip +$mediaFile = StoredFile::findByOriginalName("ACDC_-_Back_In_Black-sample.ogg"); +if (is_null($mediaFile)) { + echo "Adding test audio clip to the database.\n"; + $v = array("filepath" => __DIR__."/../../audio_samples/OpSound/ACDC_-_Back_In_Black-sample.ogg"); + $mediaFile = StoredFile::Insert($v); + if (PEAR::isError($mediaFile)) { + var_dump($mediaFile); + exit(); + } +} +$pl->addAudioClip($mediaFile->getId()); + $mediaFile = StoredFile::findByOriginalName("Manolo Camp - Morning Coffee.mp3"); if (is_null($mediaFile)) { echo "Adding test audio clip to the database.\n"; @@ -53,6 +65,7 @@ if (is_null($mediaFile)) { } } $pl->addAudioClip($mediaFile->getId()); + $mediaFile = StoredFile::findByOriginalName("Peter Rudenko - Opening.mp3"); if (is_null($mediaFile)) { echo "Adding test audio clip to the database.\n";