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:
parent
066d49b2c1
commit
5c754fdaee
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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',
|
||||
|
60
mediagoblin/media_types/video/util.py
Normal file
60
mediagoblin/media_types/video/util.py
Normal 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user