Added option to skip transcoding

- If the video input matches the configurable rules, just copy it to the
  output without transcoding it.
This commit is contained in:
Joar Wandborg 2013-01-22 22:44:19 +01:00
parent 066d49b2c1
commit 5c754fdaee
4 changed files with 109 additions and 20 deletions

View File

@ -97,6 +97,12 @@ vp8_quality = integer(default=8)
# Range: -0.1..1
vorbis_quality = float(default=0.3)
[[skip_transcode]]
mime_types = string_list(default=list("video/webm"))
container_formats = string_list(default=list("Matroska"))
video_codecs = string_list(default=list("VP8 video"))
audio_codecs = string_list(default=list("Vorbis"))
dimensions_match = boolean(default=True)
[media_type:mediagoblin.media_types.audio]
keep_original = boolean(default=True)

View File

@ -24,6 +24,8 @@ from mediagoblin.processing import \
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
from . import transcoders
from .util import skip_transcode
_log = logging.getLogger(__name__)
_log.setLevel(logging.DEBUG)
@ -80,24 +82,43 @@ def process_video(entry, workbench=None):
with tmp_dst:
# Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
progress_callback = ProgressCallback(entry)
transcoder = transcoders.VideoTranscoder()
transcoder.transcode(queued_filename, tmp_dst.name,
vp8_quality=video_config['vp8_quality'],
vp8_threads=video_config['vp8_threads'],
vorbis_quality=video_config['vorbis_quality'],
progress_callback=progress_callback)
# Push transcoded video to public storage
_log.debug('Saving medium...')
mgg.public_store.copy_local_to_storage(tmp_dst.name, medium_filepath)
_log.debug('Saved medium')
dimensions = (
mgg.global_config['media:medium']['max_width'],
mgg.global_config['media:medium']['max_height'])
entry.media_files['webm_640'] = medium_filepath
metadata = transcoders.VideoTranscoder().discover(queued_filename)
# Save the width and height of the transcoded video
entry.media_data_init(
width=transcoder.dst_data.videowidth,
height=transcoder.dst_data.videoheight)
if skip_transcode(metadata):
_log.debug('Skipping transcoding')
# Just push the submitted file to the tmp_dst
open(tmp_dst.name, 'wb').write(open(queued_filename, 'rb').read())
dst_dimensions = metadata['videowidth'], metadata['videoheight']
else:
transcoder = transcoders.VideoTranscoder()
transcoder.transcode(queued_filename, tmp_dst.name,
vp8_quality=video_config['vp8_quality'],
vp8_threads=video_config['vp8_threads'],
vorbis_quality=video_config['vorbis_quality'],
progress_callback=progress_callback,
dimensions=dimensions)
dst_dimensions = transcoder.dst_data.videowidth,\
transcoder.dst_data.videoheight
# Push transcoded video to public storage
_log.debug('Saving medium...')
mgg.public_store.copy_local_to_storage(tmp_dst.name, medium_filepath)
_log.debug('Saved medium')
entry.media_files['webm_640'] = medium_filepath
# Save the width and height of the transcoded video
entry.media_data_init(
width=dst_dimensions[0],
height=dst_dimensions[1])
# Temporary file for the video thumbnail (cleaned up with workbench)
tmp_thumb = NamedTemporaryFile(dir=workbench.dir, suffix='.jpg', delete=False)
@ -109,10 +130,10 @@ def process_video(entry, workbench=None):
tmp_thumb.name,
180)
# Push the thumbnail to public storage
_log.debug('Saving thumbnail...')
mgg.public_store.copy_local_to_storage(tmp_thumb.name, thumbnail_filepath)
entry.media_files['thumb'] = thumbnail_filepath
# Push the thumbnail to public storage
_log.debug('Saving thumbnail...')
mgg.public_store.copy_local_to_storage(tmp_thumb.name, thumbnail_filepath)
entry.media_files['thumb'] = thumbnail_filepath
if video_config['keep_original']:
# Push original file to public storage

View File

@ -673,6 +673,7 @@ class VideoTranscoder:
self._setup()
self._run()
# XXX: This could be a static method.
def discover(self, src):
'''
Discover properties about a media file
@ -793,7 +794,8 @@ class VideoTranscoder:
self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert')
self.pipeline.add(self.audioconvert)
self.audiocapsfilter = gst.element_factory_make('capsfilter', 'audiocapsfilter')
self.audiocapsfilter = gst.element_factory_make('capsfilter',
'audiocapsfilter')
audiocaps = ['audio/x-raw-float']
self.audiocapsfilter.set_property(
'caps',

View File

@ -0,0 +1,60 @@
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
from mediagoblin import mg_globals as mgg
_log = logging.getLogger(__name__)
def skip_transcode(metadata):
'''
Checks video metadata against configuration values for skip_transcode.
Returns True if the video matches the requirements in the configuration.
'''
config = mgg.global_config['media_type:mediagoblin.media_types.video']\
['skip_transcode']
medium_config = mgg.global_config['media:medium']
_log.debug('skip_transcode config: {0}'.format(config))
if config['mime_types'] and metadata.get('mimetype'):
if not metadata['mimetype'] in config['mime_types']:
return False
if config['container_formats'] and metadata['tags'].get('audio-codec'):
if not metadata['tags']['container-format'] in config['container_formats']:
return False
if config['video_codecs'] and metadata['tags'].get('audio-codec'):
if not metadata['tags']['video-codec'] in config['video_codecs']:
return False
if config['audio_codecs'] and metadata['tags'].get('audio-codec'):
if not metadata['tags']['audio-codec'] in config['audio_codecs']:
return False
if config['dimensions_match']:
if not metadata['videoheight'] <= medium_config['max_height']:
return False
if not metadata['videowidth'] <= medium_config['max_width']:
return False
return True