From 27bd9b54752d412d9d869dc02a9ed2b4444b9206 Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Wed, 12 Dec 2007 13:58:19 +0000 Subject: [PATCH] extract ogg clips --- oxdbarchive/cache.py | 19 ++- oxdbarchive/controllers.py | 6 +- oxdbarchive/extract.py | 166 ++++++++++++++++++++++ oxdbarchive/model.py | 36 ++++- oxdbarchive/subtitles.py | 114 --------------- oxdbarchive/tools/extract_poster_still.py | 6 +- 6 files changed, 223 insertions(+), 124 deletions(-) create mode 100644 oxdbarchive/extract.py diff --git a/oxdbarchive/cache.py b/oxdbarchive/cache.py index 953f5ef..d771644 100644 --- a/oxdbarchive/cache.py +++ b/oxdbarchive/cache.py @@ -40,7 +40,7 @@ def loadFrame(afile, position): return loadFile(frame) return '' -def loadClip(afile, position): +def loadFlvClip(afile, position): position = basename(position).replace(':', '.') positions = position.split(';') if len(positions) > 1: @@ -50,11 +50,26 @@ def loadClip(afile, position): outpoint = -1 flash = join(afile.frameFolder, '%s.%s' % (position, 'flv')) if not exists(flash): - afile.extractClip(position, outpoint) + afile.extractFlvClip(position, outpoint) if exists(flash): return loadFile(flash) return '' +def loadOggClip(afile, position): + position = basename(position).replace(':', '.') + positions = position.split(';') + if len(positions) > 1: + position = positions[0] + outpoint = positions[1] + else: + outpoint = -1 + clip = join(afile.frameFolder, '%s.%s' % (position, 'ogg')) + if not exists(clip): + afile.extractOggClip(position, outpoint) + if exists(clip): + return loadFile(clip) + return '' + def loadTimeline(afile): timeline = afile.timelineFile if not exists(timeline): diff --git a/oxdbarchive/controllers.py b/oxdbarchive/controllers.py index 6504e2d..b8056c7 100644 --- a/oxdbarchive/controllers.py +++ b/oxdbarchive/controllers.py @@ -43,7 +43,11 @@ class Root(controllers.RootController): if action == 'clip': cherrypy.response.headerMap['Content-Type'] = "video/x-flv" cherrypy.response.headerMap["Expires"] = httpExpires(60*60*24*15) - return f.clip(position) + return f.flvClip(position) + if action == 'ogg': + cherrypy.response.headerMap['Content-Type'] = "video/x-ogg" + cherrypy.response.headerMap["Expires"] = httpExpires(60*60*24*15) + return f.oggClip(position) elif action == 'frame': cherrypy.response.headerMap['Content-Type'] = "image/jpeg" cherrypy.response.headerMap["Expires"] = httpExpires(60*60*24*15) diff --git a/oxdbarchive/extract.py b/oxdbarchive/extract.py new file mode 100644 index 0000000..88288f0 --- /dev/null +++ b/oxdbarchive/extract.py @@ -0,0 +1,166 @@ +# -*- coding: utf-8 -*- +# -*- Mode: Python; -*- +# vi:si:et:sw=2:sts=2:ts=2 + +import re +import os +from os.path import abspath, join, dirname +import shutil +import time + +from subtitles import * + + +def extract_flash_ng(movie_file, flash_file, inpoint, outpoint, width=128, height=96, offset = 0): + ext = movie_file.split('.')[-1] + if ext in ('sub', 'srt'): + print "this is not a movie file, will not try to extract frames" + return + if offset: + print "Inpoint ", inpoint, + inpoint = shift_time(-offset, inpoint) + outpoint = shift_time(-offset, outpoint) + print " becomes ", inpoint + + print "extracting %s -> %s" % (inpoint, outpoint) + duration = time_str2msec(outpoint) - time_str2msec(inpoint) + inpoint = time_str2msec(inpoint) + extractClipScript = abspath(join(dirname(__file__), "tools/extract_clip.py")) + + cmd = '''%s "%s" %s %s %s''' % (extractClipScript, movie_file, flash_file, inpoint, duration) + os.system(cmd.encode('utf-8')) + +def extract_flash(movie_file, flash_file, inpoint, outpoint, width=128, height=96, offset = 0): + import warnings + warnings.filterwarnings("ignore", "tempnam") + ext = movie_file.split('.')[-1] + if ext in ('sub', 'srt', 'mkv'): + print "this is not a movie file, will not try to extract frames" + return + framedir = os.tempnam() + os.mkdir(framedir) + os.chdir(framedir) + if offset: + print "Inpoint ", inpoint, + inpoint = shift_time(-offset, inpoint) + outpoint = shift_time(-offset, outpoint) + print " becomes ", inpoint + print "extracting %s -> %s" % (inpoint, outpoint) + outpoint = float(time_str2msec(outpoint) - time_str2msec(inpoint)) / 1000 + 1 + + audiorate = "44100" + if os.path.exists(movie_file): + mencoder_options = '' + mencoder_options += " '%s'" % movie_file + mencoder_options += " -ss '%s' -endpos %0.2f" % (inpoint, outpoint) + mencoder_options += ' -ovc copy -oac copy -o tempfile.avi ' + mencoder = "mencoder %s >/dev/null 2>&1" % mencoder_options + #print mencoder.encode('utf-8') + os.system(mencoder.encode('utf-8')) + + #create flash file + ffmpeg_options = '' + #ffmpeg_options += " -ss '%s' -t %0.2f" % (inpoint, outpoint) + ffmpeg_options += " -y -i 'tempfile.avi'" + ffmpeg_options += " -ar %s -b 128000 '%s'" % (audiorate, flash_file) + ffmpeg = "ffmpeg %s >/dev/null 2>&1" % ffmpeg_options + #print ffmpeg.encode('utf-8') + os.system(ffmpeg.encode('utf-8')) + else: + print "update the cache %s missing" % movie_file.encode('utf-8') + shutil.rmtree(framedir) + + +def extract_ogg(movie_file, clip_file, inpoint, outpoint, width=128, height=96, offset = 0): + import warnings + warnings.filterwarnings("ignore", "tempnam") + ext = movie_file.split('.')[-1] + if ext in ('sub', 'srt', 'mkv'): + print "this is not a movie file, will not try to extract frames" + return + framedir = os.tempnam() + os.mkdir(framedir) + os.chdir(framedir) + if offset: + print "Inpoint ", inpoint, + inpoint = shift_time(-offset, inpoint) + outpoint = shift_time(-offset, outpoint) + print " becomes ", inpoint + print "extracting %s -> %s" % (inpoint, outpoint) + outpoint = float(time_str2msec(outpoint) - time_str2msec(inpoint)) / 1000 + 1 + + audiorate = "44100" + if os.path.exists(movie_file): + mencoder_options = '' + mencoder_options += " '%s'" % movie_file + mencoder_options += " -ss '%s' -endpos %0.2f" % (inpoint, outpoint) + mencoder_options += ' -ovc copy -oac copy -o tempfile.avi ' + mencoder = "mencoder %s >/dev/null 2>&1" % mencoder_options + #print mencoder.encode('utf-8') + os.system(mencoder.encode('utf-8')) + + #create ogg file + ffmpeg2theora_options = '' + ffmpeg2theora_options += " 'tempfile.avi' -H %s -o '%s'" % (audiorate, flash_file) + ffmpeg2theora = "ffmpeg2theora %s >/dev/null 2>&1" % ffmpeg2theora_options + print ffmpeg2theora.encode('utf-8') + os.system(ffmpeg2theora.encode('utf-8')) + else: + print "update the cache %s missing" % movie_file.encode('utf-8') + shutil.rmtree(framedir) + +def extract_frame(movie_file, timestamp, img_folder, width=128, offset = 0, redo = False): + import warnings + warnings.filterwarnings("ignore", "tempnam") + ext = movie_file.split('.')[-1] + if ext in ('sub', 'srt'): + print "this is not a movie file, will not try to extract frames" + return + framedir = os.tempnam() + + os.mkdir(framedir) + os.chdir(framedir) + if offset: + timestamp_in_file = shift_time(-offset, timestamp) + else: + timestamp_in_file = timestamp + if os.path.exists(movie_file): + mplayer_options = '' + mplayer_options += " '%s'" % movie_file + mplayer_options += " -ss '%s' -frames 2" % (timestamp_in_file) + mplayer_options += " -vo jpeg:quality=90 -vf scale -zoom -xy %d " % width + mplayer_options += " -ao null" + mplayer = "mplayer %s >/dev/null 2>&1" % mplayer_options + frame = os.path.join(img_folder, "%s.%s" % (timestamp.replace(':', '.'), img_extension)) + if redo or not os.path.exists(frame): + print mplayer.encode('utf-8') + os.system (mplayer.encode('utf-8')) + files = os.listdir(framedir) + if files: + print "creating frame ", frame + shutil.move(os.path.join(framedir,files[-1]), frame) + if len(files)>1: + for f in files[:-2]: + print "unlink", f + os.unlink(f) + time.sleep(0.1) + else: + print "update the cache %s missing" % movie_file + shutil.rmtree(framedir) + +def extract_poster_still(movie_file, png_file, inpoint): + ext = movie_file.split('.')[-1] + if ext in ('sub', 'srt'): + print "this is not a movie file, will not try to extract frames" + return + inpoint = time_str2msec(inpoint) + extractClipScript = abspath(join(dirname(__file__), "tools/extract_poster_still.py")) + + cmd = '''%s "%s" "%s" %s''' % (extractClipScript, movie_file, png_file, inpoint) + os.system(cmd.encode('utf-8')) + +def extract_subtitles(movie_file, srt, img_folder, width=128, offset = 0, redo = False): + subtitles = srt2dict(srt) + for k in sorted([int(k) for k in subtitles]): + timestamp = subtitles["%s" % k]['start'] + extract_frame(movie_file, timestamp, img_folder, width, offset, redo) diff --git a/oxdbarchive/model.py b/oxdbarchive/model.py index fcddc2c..1de177d 100644 --- a/oxdbarchive/model.py +++ b/oxdbarchive/model.py @@ -24,6 +24,7 @@ import cache import oxdb_import from oxdb_utils import oxdb_title, oxdb_director, oxdb_id, oxdb_makedir from subtitles import * +from extract import * import midentify @@ -447,8 +448,8 @@ class ArchiveFile(SQLObject): #enable this later #self.extractFrames() #self.extractClips() - - def extractClip(self, inpoint, outpoint=-1, flash_folder=-1): + + def extractFlvClip(self, inpoint, outpoint=-1, flash_folder=-1): if flash_folder == -1: flash_folder = self.frameFolder movie_file = self.mini_movie_file @@ -469,9 +470,30 @@ class ArchiveFile(SQLObject): extract_flash(movie_file, flash_movie, inpoint, outpoint, width, height, offset = 0) #extract_flash_ng(self.absolutePath, flash_movie, inpoint, outpoint, width, height, offset) + def extractOggClip(self, inpoint, outpoint=-1, flash_folder=-1): + if clip_folder == -1: + clip_folder = self.frameFolder + movie_file = self.mini_movie_file + position = inpoint.replace(':', '.') + clip_movie = join(self.frameFolder, '%s.%s' % (position, 'ogg')) + width = 128 + height = int(width / self.frameAspect) + height = height - height % 2 + inpoint = inpoint.replace('.', ':') + if outpoint == -1: + s = self._findSubtitleByStart(inpoint) + if s: + outpoint = s['stop'] + else: + outpoint = shift_time(5000, inpoint) + else: + outpoint = outpoint.replace('.', ':') + extract_ogg(movie_file, clip_movie, inpoint, outpoint, width, height, offset = 0) + + def extractClips(self, img_folder=cache.frame_cache_root): for p in self._startPoints(): - self.extractClip(p) + self.extractFlvClip(p) def extractFrame(self, position, img_folder=-1): if img_folder == -1: @@ -508,6 +530,7 @@ class ArchiveFile(SQLObject): if exists(mini_movie_file) and not force: print "clip exists, skipping extraction", mini_movie_file return + self.extracted = False oxdb_makedir(dirname(mini_movie_file)) options = '' @@ -609,8 +632,11 @@ class ArchiveFile(SQLObject): pixels = self.updatePixels() return pixels - def clip(self, position): - return cache.loadClip(self, position) + def flvClip(self, position): + return cache.loadFlvClip(self, position) + + def oggClip(self, position): + return cache.loadOggClip(self, position) def frame(self, position): return cache.loadFrame(self, position) diff --git a/oxdbarchive/subtitles.py b/oxdbarchive/subtitles.py index 320e997..9a156ed 100644 --- a/oxdbarchive/subtitles.py +++ b/oxdbarchive/subtitles.py @@ -128,120 +128,6 @@ def split_subtitle(subtitles, offset): two[k] = subtitle[k] two = shift_subtitles(-offset, -len(two), two) -def extract_flash_ng(movie_file, flash_file, inpoint, outpoint, width=128, height=96, offset = 0): - ext = movie_file.split('.')[-1] - if ext in ('sub', 'srt'): - print "this is not a movie file, will not try to extract frames" - return - if offset: - print "Inpoint ", inpoint, - inpoint = shift_time(-offset, inpoint) - outpoint = shift_time(-offset, outpoint) - print " becomes ", inpoint - - print "extracting %s -> %s" % (inpoint, outpoint) - duration = time_str2msec(outpoint) - time_str2msec(inpoint) - inpoint = time_str2msec(inpoint) - extractClipScript = abspath(join(dirname(__file__), "tools/extract_clip.py")) - - cmd = '''%s "%s" %s %s %s''' % (extractClipScript, movie_file, flash_file, inpoint, duration) - os.system(cmd.encode('utf-8')) - -def extract_flash(movie_file, flash_file, inpoint, outpoint, width=128, height=96, offset = 0): - import warnings - warnings.filterwarnings("ignore", "tempnam") - ext = movie_file.split('.')[-1] - if ext in ('sub', 'srt', 'mkv'): - print "this is not a movie file, will not try to extract frames" - return - framedir = os.tempnam() - os.mkdir(framedir) - os.chdir(framedir) - if offset: - print "Inpoint ", inpoint, - inpoint = shift_time(-offset, inpoint) - outpoint = shift_time(-offset, outpoint) - print " becomes ", inpoint - print "extracting %s -> %s" % (inpoint, outpoint) - outpoint = float(time_str2msec(outpoint) - time_str2msec(inpoint)) / 1000 + 1 - - audiorate = "44100" - if os.path.exists(movie_file): - mencoder_options = '' - mencoder_options += " '%s'" % movie_file - mencoder_options += " -ss '%s' -endpos %0.2f" % (inpoint, outpoint) - mencoder_options += ' -ovc copy -oac copy -o tempfile.avi ' - mencoder = "mencoder %s >/dev/null 2>&1" % mencoder_options - #print mencoder.encode('utf-8') - os.system(mencoder.encode('utf-8')) - - ffmpeg_options = '' - #ffmpeg_options += " -ss '%s' -t %0.2f" % (inpoint, outpoint) - ffmpeg_options += " -y -i 'tempfile.avi'" - ffmpeg_options += " -ar %s -b 128000 '%s'" % (audiorate, flash_file) - ffmpeg = "ffmpeg %s >/dev/null 2>&1" % ffmpeg_options - #print ffmpeg.encode('utf-8') - os.system(ffmpeg.encode('utf-8')) - else: - print "update the cache %s missing" % movie_file.encode('utf-8') - shutil.rmtree(framedir) - -def extract_frame(movie_file, timestamp, img_folder, width=128, offset = 0, redo = False): - import warnings - warnings.filterwarnings("ignore", "tempnam") - ext = movie_file.split('.')[-1] - if ext in ('sub', 'srt'): - print "this is not a movie file, will not try to extract frames" - return - framedir = os.tempnam() - - os.mkdir(framedir) - os.chdir(framedir) - if offset: - timestamp_in_file = shift_time(-offset, timestamp) - else: - timestamp_in_file = timestamp - if os.path.exists(movie_file): - mplayer_options = '' - mplayer_options += " '%s'" % movie_file - mplayer_options += " -ss '%s' -frames 2" % (timestamp_in_file) - mplayer_options += " -vo jpeg:quality=90 -vf scale -zoom -xy %d " % width - mplayer_options += " -ao null" - mplayer = "mplayer %s >/dev/null 2>&1" % mplayer_options - frame = os.path.join(img_folder, "%s.%s" % (timestamp.replace(':', '.'), img_extension)) - if redo or not os.path.exists(frame): - print mplayer.encode('utf-8') - os.system (mplayer.encode('utf-8')) - files = os.listdir(framedir) - if files: - print "creating frame ", frame - shutil.move(os.path.join(framedir,files[-1]), frame) - if len(files)>1: - for f in files[:-2]: - print "unlink", f - os.unlink(f) - time.sleep(0.1) - else: - print "update the cache %s missing" % movie_file - shutil.rmtree(framedir) - -def extract_poster_still(movie_file, png_file, inpoint): - ext = movie_file.split('.')[-1] - if ext in ('sub', 'srt'): - print "this is not a movie file, will not try to extract frames" - return - inpoint = time_str2msec(inpoint) - extractClipScript = abspath(join(dirname(__file__), "tools/extract_poster_still.py")) - - cmd = '''%s "%s" "%s" %s''' % (extractClipScript, movie_file, png_file, inpoint) - os.system(cmd.encode('utf-8')) - -def extract_subtitles(movie_file, srt, img_folder, width=128, offset = 0, redo = False): - subtitles = srt2dict(srt) - for k in sorted([int(k) for k in subtitles]): - timestamp = subtitles["%s" % k]['start'] - extract_frame(movie_file, timestamp, img_folder, width, offset, redo) - def detectEncoding(fp): bomDict={ # bytepattern : name (0x00, 0x00, 0xFE, 0xFF) : "utf_32_be", diff --git a/oxdbarchive/tools/extract_poster_still.py b/oxdbarchive/tools/extract_poster_still.py index 79d6c6a..e446f3a 100755 --- a/oxdbarchive/tools/extract_poster_still.py +++ b/oxdbarchive/tools/extract_poster_still.py @@ -139,7 +139,7 @@ class PosterStillMplayer: def scaleImage(self, tmpImage): img = Image.open(tmpImage) - output_d = self.scaleto(i.size[0], i.size[1]) + output_d = self.scaleto(img.size[0], img.size[1]) img = img.resize(output_d, Image.ANTIALIAS) img.save(self.png_frame) @@ -158,4 +158,6 @@ if __name__ == "__main__": sys.exit() outputFile = sys.argv[2] offset = int(float(sys.argv[3]) * gst.MSECOND) - f = PosterStill(inputFile, outputFile, offset, height) + #f = PosterStill(inputFile, outputFile, offset, height) + f = PosterStillMplayer(inputFile, outputFile, offset, height) +