Support libav for video processing
This commit is contained in:
parent
471e0eb820
commit
213fd2ffc7
@ -7,7 +7,7 @@ from PIL import Image
|
|||||||
from PIL.ExifTags import TAGS
|
from PIL.ExifTags import TAGS
|
||||||
import gc
|
import gc
|
||||||
import tempfile
|
import tempfile
|
||||||
import subprocess
|
from VideoToolWrapper import *
|
||||||
|
|
||||||
class Album(object):
|
class Album(object):
|
||||||
def __init__(self, path):
|
def __init__(self, path):
|
||||||
@ -236,11 +236,8 @@ class Photo(object):
|
|||||||
_photo_metadata.subject_distance_range_list = ["Unknown", "Macro", "Close view", "Distant view"]
|
_photo_metadata.subject_distance_range_list = ["Unknown", "Macro", "Close view", "Distant view"]
|
||||||
|
|
||||||
def _video_metadata(self, path, original=True):
|
def _video_metadata(self, path, original=True):
|
||||||
try:
|
p = VideoProbeWrapper().call('-show_format', '-show_streams', '-of', 'json', '-loglevel', '0', path)
|
||||||
p = subprocess.check_output(['/usr/bin/ffprobe', '-show_format', '-show_streams', '-of', 'json', '-loglevel', '0', path])
|
if p == False:
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
self.is_valid = False
|
self.is_valid = False
|
||||||
return
|
return
|
||||||
info = json.loads(p)
|
info = json.loads(p)
|
||||||
@ -330,12 +327,8 @@ class Photo(object):
|
|||||||
|
|
||||||
def _video_thumbnails(self, thumb_path, original_path):
|
def _video_thumbnails(self, thumb_path, original_path):
|
||||||
(tfd, tfn) = tempfile.mkstemp();
|
(tfd, tfn) = tempfile.mkstemp();
|
||||||
try:
|
p = VideoTranscodeWrapper().call('-i', original_path, '-f', 'image2', '-vsync', '1', '-vframes', '1', '-an', '-loglevel', 'quiet', tfn)
|
||||||
subprocess.check_call(['/usr/bin/ffmpeg', '-i', original_path, '-f', 'image2', '-vsync', '1', '-vframes', '1', '-an', '-loglevel', 'quiet', tfn])
|
if p == False:
|
||||||
except KeyboardInterrupt:
|
|
||||||
os.unlink(tfn)
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
message("couldn't extract video frame", os.path.basename(original_path))
|
message("couldn't extract video frame", os.path.basename(original_path))
|
||||||
os.unlink(tfn)
|
os.unlink(tfn)
|
||||||
self.is_valid = False
|
self.is_valid = False
|
||||||
@ -364,7 +357,7 @@ class Photo(object):
|
|||||||
|
|
||||||
def _video_transcode(self, transcode_path, original_path):
|
def _video_transcode(self, transcode_path, original_path):
|
||||||
transcode_path = os.path.join(transcode_path, cache_base(self._path) + '.webm')
|
transcode_path = os.path.join(transcode_path, cache_base(self._path) + '.webm')
|
||||||
transcode_cmd = ['/usr/bin/ffmpeg', '-i', original_path, '-c:v', 'libvpx', '-crf', '10', '-b:v', '800k', '-c:a', 'libvorbis', '-f', 'webm', '-threads', '2', '-loglevel', '0', '-y']
|
transcode_cmd = ['-i', original_path, '-c:v', 'libvpx', '-crf', '10', '-b:v', '800k', '-c:a', 'libvorbis', '-f', 'webm', '-threads', '2', '-loglevel', '0', '-y']
|
||||||
filters = []
|
filters = []
|
||||||
info_string = "%s -> webm" % (os.path.basename(original_path))
|
info_string = "%s -> webm" % (os.path.basename(original_path))
|
||||||
message("transcoding", info_string)
|
message("transcoding", info_string)
|
||||||
@ -384,11 +377,8 @@ class Photo(object):
|
|||||||
transcode_cmd.append('-vf')
|
transcode_cmd.append('-vf')
|
||||||
transcode_cmd.append(','.join(filters))
|
transcode_cmd.append(','.join(filters))
|
||||||
transcode_cmd.append(transcode_path)
|
transcode_cmd.append(transcode_path)
|
||||||
try:
|
p = VideoTranscodeWrapper().call(*transcode_cmd)
|
||||||
subprocess.call(transcode_cmd)
|
if p == False:
|
||||||
except KeyboardInterrupt:
|
|
||||||
raise
|
|
||||||
except:
|
|
||||||
message("transcoding failure", os.path.basename(original_path))
|
message("transcoding failure", os.path.basename(original_path))
|
||||||
try:
|
try:
|
||||||
os.unlink(transcode_path)
|
os.unlink(transcode_path)
|
||||||
|
38
scanner/VideoToolWrapper.py
Normal file
38
scanner/VideoToolWrapper.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
from CachePath import message
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
class VideoToolWrapper(object):
|
||||||
|
def call(self, *args):
|
||||||
|
path = args[-1]
|
||||||
|
for tool in self.wrappers:
|
||||||
|
try:
|
||||||
|
p = subprocess.check_output((tool,) + args)
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
if self.cleanup:
|
||||||
|
self.remove(path)
|
||||||
|
raise
|
||||||
|
except OSError:
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
if self.cleanup:
|
||||||
|
self.remove(path)
|
||||||
|
return False
|
||||||
|
return p
|
||||||
|
return False
|
||||||
|
|
||||||
|
def remove(self, path):
|
||||||
|
try:
|
||||||
|
os.unlink(path)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class VideoTranscodeWrapper(VideoToolWrapper):
|
||||||
|
def __init__(self):
|
||||||
|
self.wrappers = ['avconv', 'ffmpeg']
|
||||||
|
self.cleanup = True
|
||||||
|
|
||||||
|
class VideoProbeWrapper(VideoToolWrapper):
|
||||||
|
def __init__(self):
|
||||||
|
self.wrappers = ['avprobe', 'ffprobe']
|
||||||
|
self.cleanup = False
|
Loading…
Reference in New Issue
Block a user