From e724c67f058764809df0ee02f6e17cede9885f5c Mon Sep 17 00:00:00 2001 From: j <0x006A@0x2620.org> Date: Tue, 16 Feb 2010 15:43:44 +0530 Subject: [PATCH] extract frames --- oxdb/backend/extract.py | 72 +++++++++++++++++++++++++++++++++++++++++ oxdb/backend/models.py | 31 ++++++++++-------- 2 files changed, 90 insertions(+), 13 deletions(-) create mode 100644 oxdb/backend/extract.py diff --git a/oxdb/backend/extract.py b/oxdb/backend/extract.py new file mode 100644 index 000000000..3bfaf388f --- /dev/null +++ b/oxdb/backend/extract.py @@ -0,0 +1,72 @@ +# -*- coding: utf-8 -*- +# vi:si:et:sw=4:sts=4:ts=4 +# GPL 2010 +from __future__ import division +import re +import os +from os.path import abspath, join, dirname, exists +import shutil +import time +import warnings +import subprocess + +import oxlib +import Image +import simplejson as json + + +img_extension='jpg' + +def run_command(cmd, timeout=10): + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + while timeout > 0: + time.sleep(0.2) + timeout -= 0.2 + if p.poll() != None: + return p.returncode + if p.poll() == None: + os.kill(p.pid, 9) + killedpid, stat = os.waitpid(p.pid, os.WNOHANG) + return p.returncode + +def frame(videoFile, position, baseFolder, width=128, redo=False): + ''' + params: + videoFile + position as float in seconds + baseFolder to write frames to + width of frame + redo boolean to extract file even if it exists + ''' + #not using input file, to slow to extract frame right now + base_size = 320 + frame = os.path.join(baseFolder, "%f.%s.%s" % (position, base_size, img_extension)) + + if exists(videoFile): + if redo or not exists(frame): + if not exists(baseFolder): + os.makedirs(baseFolder) + cmd = ['oggThumb', '-t', str(position), '-n', frame, '-s', '%dx0'%base_size, videoFile] + run_command(cmd) + if width != base_size: + frame_base = frame + frame = os.path.join(baseFolder, "%f.%s.%s" % (position, width, img_extension)) + if not exists(frame): + resize_image(frame_base, frame, width) + return frame + +def resize_image(image_source, image_output, width): + if exists(image_source): + source = Image.open(image_source) + source_width = source.size[0] + source_height = source.size[1] + + height = int(width / (float(source_width) / source_height)) + height = height - height % 2 + + if width < source_width: + resize_method = Image.ANTIALIAS + else: + resize_method = Image.BICUBIC + output = source.resize((width, height), resize_method) + output.save(image_output) diff --git a/oxdb/backend/models.py b/oxdb/backend/models.py index 43cc8eb4b..b36b6cd59 100644 --- a/oxdb/backend/models.py +++ b/oxdb/backend/models.py @@ -20,7 +20,7 @@ from firefogg import Firefogg import managers import load import utils - +import extract class MovieImdb(models.Model): created = models.DateTimeField(auto_now_add=True) @@ -1132,26 +1132,31 @@ class File(models.Model): def extract_video(self): ogg = Firefogg() + source = None + profiles = [] if self.stream_high: - #mid stream - self.stream_mid.name = stream_path(self, 'mid') - self.stream_mid.save() - ogg.encode(self.stream_height.path, self.stream_mid.path, settings.VIDEO_MID) - #low stream - self.stream_low.name = stream_path(self, 'low') - self.stream_low.save() - ogg.encode(self.stream_high.path, self.stream_low.path, settings.VIDEO_LOW) + source = self.stream_high + profiles = ['low', 'mid'] elif self.stream_mid: - self.stream_low.name = stream_path(self, 'low') - self.stream_low.save() - ogg.encode(self.stream_mid.path, self.stream_low.path, settings.VIDEO_LOW) - + source = self.stream_mid + profiles = ['low', ] + for profile in profiles: + output = getattr(self, 'stream_%s'%profile) + output.name = stream_path(self, profile) + output.save() + ogg.encode(source.path, output.path, settings.VIDEO_ENCODING[profile]) + def extract(self): #FIXME: do stuff, like create timeline or create smaller videos etc self.extract_video() self.extract_timeline() return + def frame(self, position, width=128): + videoFile = getattr(self, 'stream_%s'%settings.VIDEO_PROFILE).path + frameFolder = os.path.join(os.path.dirname(videoFile), 'frames') + extract.frame(videoFile, position, frameFolder, width) + def editable(self, user): ''' #FIXME: this should use a queryset!!!