2010-11-16 20:22:30 +00:00
|
|
|
#!/usr/bin/python
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# vi:si:et:sw=4:sts=4:ts=4
|
|
|
|
# GPL 2010
|
|
|
|
from __future__ import division, with_statement
|
|
|
|
|
|
|
|
import fractions
|
|
|
|
from glob import glob
|
|
|
|
import json
|
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import sqlite3
|
|
|
|
import subprocess
|
|
|
|
import sys
|
|
|
|
import shutil
|
|
|
|
import tempfile
|
|
|
|
import time
|
|
|
|
|
|
|
|
import ox
|
|
|
|
|
|
|
|
from utils import avinfo, AspectRatio, run_command
|
|
|
|
|
|
|
|
|
2012-02-14 06:38:01 +00:00
|
|
|
def command(program):
|
|
|
|
local = os.path.expanduser('~/.ox/bin/%s' % program)
|
|
|
|
if os.path.exists(local):
|
|
|
|
program = local
|
|
|
|
return program
|
|
|
|
|
2010-11-16 20:22:30 +00:00
|
|
|
def frame(video, target, position):
|
|
|
|
fdir = os.path.dirname(target)
|
|
|
|
if fdir and not os.path.exists(fdir):
|
|
|
|
os.makedirs(fdir)
|
|
|
|
|
2010-12-28 14:14:48 +00:00
|
|
|
'''
|
|
|
|
#oxframe
|
|
|
|
cmd = ['oxframe', '-i', video, '-p', str(position), '-o', target]
|
|
|
|
print cmd
|
|
|
|
r = run_command(cmd)
|
|
|
|
return r == 0
|
|
|
|
'''
|
|
|
|
|
2011-08-23 19:20:01 +00:00
|
|
|
'''
|
2010-11-16 20:22:30 +00:00
|
|
|
#mplayer
|
|
|
|
cwd = os.getcwd()
|
|
|
|
target = os.path.abspath(target)
|
|
|
|
framedir = tempfile.mkdtemp()
|
|
|
|
os.chdir(framedir)
|
|
|
|
cmd = ['mplayer', '-noautosub', video, '-ss', str(position), '-frames', '2', '-vo', 'png:z=9', '-ao', 'null']
|
|
|
|
print cmd
|
|
|
|
r = run_command(cmd)
|
|
|
|
images = glob('%s/*.png' % framedir)
|
|
|
|
if images:
|
|
|
|
shutil.move(images[-1], target)
|
|
|
|
r = 0
|
|
|
|
else:
|
|
|
|
r = 1
|
|
|
|
os.chdir(cwd)
|
|
|
|
shutil.rmtree(framedir)
|
|
|
|
return r == 0
|
2011-08-23 19:20:01 +00:00
|
|
|
'''
|
|
|
|
#ffmpeg
|
2012-02-14 06:38:01 +00:00
|
|
|
cmd = [command('ffmpeg'), '-y', '-ss', str(position), '-i', video, '-an', '-vframes', '1', target]
|
2011-08-23 19:20:01 +00:00
|
|
|
r = run_command(cmd)
|
|
|
|
return r == 0
|
2010-11-16 20:22:30 +00:00
|
|
|
|
2012-01-02 12:32:15 +00:00
|
|
|
def video_cmd(video, target, profile, info):
|
|
|
|
|
2010-11-16 20:22:30 +00:00
|
|
|
if not os.path.exists(target):
|
2011-04-06 14:42:40 +00:00
|
|
|
ox.makedirs(os.path.dirname(target))
|
2011-02-23 11:55:40 +00:00
|
|
|
|
2010-11-16 20:22:30 +00:00
|
|
|
'''
|
|
|
|
look into
|
|
|
|
lag
|
|
|
|
mb_static_threshold
|
|
|
|
qmax/qmin
|
|
|
|
rc_buf_aggressivity=0.95
|
|
|
|
token_partitions=4
|
|
|
|
level / speedlevel
|
|
|
|
bt?
|
|
|
|
'''
|
2011-02-06 12:43:50 +00:00
|
|
|
profile, format = profile.split('.')
|
2011-12-28 15:00:17 +00:00
|
|
|
bpp = 0.17
|
2011-02-06 12:43:50 +00:00
|
|
|
|
2010-11-16 20:22:30 +00:00
|
|
|
if profile == '720p':
|
|
|
|
height = 720
|
|
|
|
|
|
|
|
audiorate = 48000
|
|
|
|
audioquality = 5
|
|
|
|
audiobitrate = None
|
|
|
|
audiochannels = None
|
|
|
|
if profile == '480p':
|
|
|
|
height = 480
|
|
|
|
|
|
|
|
audiorate = 44100
|
2011-02-04 12:17:10 +00:00
|
|
|
audioquality = 3
|
2010-11-16 20:22:30 +00:00
|
|
|
audiobitrate = None
|
|
|
|
audiochannels = 2
|
2012-04-19 16:08:13 +00:00
|
|
|
elif profile == '432p':
|
|
|
|
height = 432
|
|
|
|
audiorate = 44100
|
|
|
|
audioquality = 2
|
|
|
|
audiobitrate = None
|
|
|
|
audiochannels = 2
|
2010-11-16 20:22:30 +00:00
|
|
|
elif profile == '360p':
|
|
|
|
height = 360
|
|
|
|
|
|
|
|
audiorate = 44100
|
|
|
|
audioquality = 1
|
|
|
|
audiobitrate = None
|
|
|
|
audiochannels = 1
|
2012-04-19 16:08:13 +00:00
|
|
|
elif profile == '288p':
|
|
|
|
height = 288
|
|
|
|
|
|
|
|
audiorate = 44100
|
|
|
|
audioquality = 0
|
|
|
|
audiobitrate = None
|
|
|
|
audiochannels = 1
|
2011-02-06 12:49:36 +00:00
|
|
|
elif profile == '240p':
|
|
|
|
height = 240
|
2010-11-16 20:22:30 +00:00
|
|
|
|
|
|
|
audiorate = 44100
|
|
|
|
audioquality = 0
|
|
|
|
audiobitrate = None
|
|
|
|
audiochannels = 1
|
2012-04-19 16:08:13 +00:00
|
|
|
elif profile == '144p':
|
|
|
|
height = 144
|
|
|
|
|
|
|
|
audiorate = 22050
|
|
|
|
audioquality = -1
|
|
|
|
audiobitrate = '22k'
|
|
|
|
audiochannels = 1
|
2010-11-16 20:22:30 +00:00
|
|
|
else:
|
|
|
|
height = 96
|
|
|
|
|
|
|
|
audiorate = 22050
|
|
|
|
audioquality = -1
|
|
|
|
audiobitrate = '22k'
|
|
|
|
audiochannels = 1
|
|
|
|
|
2011-04-06 14:42:40 +00:00
|
|
|
if info['video'] and 'display_aspect_ratio' in info['video'][0]:
|
|
|
|
dar = AspectRatio(info['video'][0]['display_aspect_ratio'])
|
2011-02-23 11:55:40 +00:00
|
|
|
fps = AspectRatio(info['video'][0]['framerate'])
|
|
|
|
width = int(dar * height)
|
|
|
|
width += width % 2
|
2012-01-04 09:04:23 +00:00
|
|
|
extra = []
|
|
|
|
if fps == 50:
|
|
|
|
fps = 25
|
|
|
|
extra += ['-r', '25']
|
|
|
|
if fps == 60:
|
|
|
|
fps = 30
|
|
|
|
extra += ['-r', '30']
|
2011-02-23 11:55:40 +00:00
|
|
|
bitrate = height*width*fps*bpp/1000
|
|
|
|
aspect = dar.ratio
|
|
|
|
#use 1:1 pixel aspect ratio if dar is close to that
|
|
|
|
if abs(width/height - dar) < 0.02:
|
|
|
|
aspect = '%s:%s' % (width, height)
|
|
|
|
|
|
|
|
video_settings = [
|
2012-01-04 09:31:18 +00:00
|
|
|
'-vb', '%dk'%bitrate,
|
2011-02-23 11:55:40 +00:00
|
|
|
'-aspect', aspect,
|
2012-01-05 15:42:45 +00:00
|
|
|
'-g', '%d' % int(fps*5),
|
2012-01-04 15:04:33 +00:00
|
|
|
'-vf', 'yadif,hqdn3d,scale=%s:%s'%(width, height),
|
2012-01-04 09:04:23 +00:00
|
|
|
] + extra
|
2012-03-21 23:17:40 +00:00
|
|
|
if format == 'webm':
|
|
|
|
video_settings += [
|
|
|
|
'-deadline', 'good',
|
|
|
|
'-cpu-used', '0',
|
|
|
|
'-lag-in-frames', '16',
|
|
|
|
'-auto-alt-ref', '1',
|
|
|
|
]
|
2012-06-12 08:46:30 +00:00
|
|
|
video_settings += ['-map', '0:%s,0:0'%info['video'][0]['id']]
|
2011-02-23 11:55:40 +00:00
|
|
|
else:
|
|
|
|
video_settings = ['-vn']
|
2010-11-16 20:22:30 +00:00
|
|
|
|
|
|
|
if info['audio']:
|
2012-06-12 08:46:30 +00:00
|
|
|
n = video_settings == ['-vn'] and 0 or 1
|
|
|
|
video_settings += ['-map', '0:%s,0:%s' % (info['audio'][0]['id'], n)]
|
2010-11-16 20:22:30 +00:00
|
|
|
audio_settings = ['-ar', str(audiorate), '-aq', str(audioquality)]
|
2012-03-21 23:04:35 +00:00
|
|
|
ac = info['audio'][0].get('channels', audiochannels)
|
2012-06-12 12:20:48 +00:00
|
|
|
if ac:
|
|
|
|
ac = min(ac, audiochannels)
|
|
|
|
else:
|
|
|
|
ac = audiochannels
|
2012-03-21 23:04:35 +00:00
|
|
|
audio_settings += ['-ac', str(ac)]
|
2010-11-16 20:22:30 +00:00
|
|
|
if audiobitrate:
|
|
|
|
audio_settings += ['-ab', audiobitrate]
|
|
|
|
audio_settings +=['-acodec', 'libvorbis']
|
|
|
|
else:
|
|
|
|
audio_settings = ['-an']
|
|
|
|
|
2012-02-14 06:38:01 +00:00
|
|
|
cmd = [command('ffmpeg'), '-y', '-i', video, '-threads', '4'] \
|
2010-11-16 20:22:30 +00:00
|
|
|
+ audio_settings \
|
|
|
|
+ video_settings \
|
|
|
|
+ ['-f','webm', target]
|
2012-01-02 12:32:15 +00:00
|
|
|
return cmd
|
|
|
|
|
|
|
|
def video(video, target, profile, info):
|
|
|
|
cmd = video_cmd(video, target, profile, info)
|
2010-11-16 20:22:30 +00:00
|
|
|
#r = run_command(cmd, -1)
|
2010-11-27 12:15:11 +00:00
|
|
|
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
|
2010-11-27 11:59:28 +00:00
|
|
|
'''
|
2010-11-27 12:15:11 +00:00
|
|
|
p = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
2010-11-16 20:22:30 +00:00
|
|
|
line = p.stderr.readline()
|
|
|
|
while line:
|
|
|
|
if line.startswith('frame='):
|
|
|
|
frames = line.split('=')[1].strip().split(' ')[0]
|
|
|
|
line = p.stderr.readline()
|
2010-11-27 11:59:28 +00:00
|
|
|
'''
|
|
|
|
try:
|
|
|
|
p.wait()
|
|
|
|
r = p.returncode
|
2011-12-28 15:00:17 +00:00
|
|
|
print 'Input:\t', video
|
|
|
|
print 'Output:\t', target
|
2010-11-27 11:59:28 +00:00
|
|
|
except KeyboardInterrupt:
|
|
|
|
r = 1
|
2011-12-30 13:17:28 +00:00
|
|
|
if os.path.exists(target):
|
|
|
|
print "\n\ncleanup unfinished encoding:\nremoving", target
|
|
|
|
print "\n"
|
|
|
|
os.unlink(target)
|
2010-11-27 11:59:28 +00:00
|
|
|
sys.exit(1)
|
2010-11-16 20:22:30 +00:00
|
|
|
return r == 0
|