forked from 0x2620/pandora
extract frames
This commit is contained in:
parent
1862befc8f
commit
e724c67f05
2 changed files with 90 additions and 13 deletions
72
oxdb/backend/extract.py
Normal file
72
oxdb/backend/extract.py
Normal file
|
@ -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)
|
|
@ -20,7 +20,7 @@ from firefogg import Firefogg
|
||||||
import managers
|
import managers
|
||||||
import load
|
import load
|
||||||
import utils
|
import utils
|
||||||
|
import extract
|
||||||
|
|
||||||
class MovieImdb(models.Model):
|
class MovieImdb(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
@ -1132,19 +1132,19 @@ class File(models.Model):
|
||||||
|
|
||||||
def extract_video(self):
|
def extract_video(self):
|
||||||
ogg = Firefogg()
|
ogg = Firefogg()
|
||||||
|
source = None
|
||||||
|
profiles = []
|
||||||
if self.stream_high:
|
if self.stream_high:
|
||||||
#mid stream
|
source = self.stream_high
|
||||||
self.stream_mid.name = stream_path(self, 'mid')
|
profiles = ['low', '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)
|
|
||||||
elif self.stream_mid:
|
elif self.stream_mid:
|
||||||
self.stream_low.name = stream_path(self, 'low')
|
source = self.stream_mid
|
||||||
self.stream_low.save()
|
profiles = ['low', ]
|
||||||
ogg.encode(self.stream_mid.path, self.stream_low.path, settings.VIDEO_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):
|
def extract(self):
|
||||||
#FIXME: do stuff, like create timeline or create smaller videos etc
|
#FIXME: do stuff, like create timeline or create smaller videos etc
|
||||||
|
@ -1152,6 +1152,11 @@ class File(models.Model):
|
||||||
self.extract_timeline()
|
self.extract_timeline()
|
||||||
return
|
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):
|
def editable(self, user):
|
||||||
'''
|
'''
|
||||||
#FIXME: this should use a queryset!!!
|
#FIXME: this should use a queryset!!!
|
||||||
|
|
Loading…
Reference in a new issue