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
|
# Range: -0.1..1
|
||||||
vorbis_quality = float(default=0.3)
|
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]
|
[media_type:mediagoblin.media_types.audio]
|
||||||
keep_original = boolean(default=True)
|
keep_original = boolean(default=True)
|
||||||
|
@ -24,6 +24,8 @@ from mediagoblin.processing import \
|
|||||||
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
|
from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
|
||||||
|
|
||||||
from . import transcoders
|
from . import transcoders
|
||||||
|
from .util import skip_transcode
|
||||||
|
|
||||||
|
|
||||||
_log = logging.getLogger(__name__)
|
_log = logging.getLogger(__name__)
|
||||||
_log.setLevel(logging.DEBUG)
|
_log.setLevel(logging.DEBUG)
|
||||||
@ -80,24 +82,43 @@ def process_video(entry, workbench=None):
|
|||||||
with tmp_dst:
|
with tmp_dst:
|
||||||
# Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
|
# Transcode queued file to a VP8/vorbis file that fits in a 640x640 square
|
||||||
progress_callback = ProgressCallback(entry)
|
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
|
dimensions = (
|
||||||
_log.debug('Saving medium...')
|
mgg.global_config['media:medium']['max_width'],
|
||||||
mgg.public_store.copy_local_to_storage(tmp_dst.name, medium_filepath)
|
mgg.global_config['media:medium']['max_height'])
|
||||||
_log.debug('Saved medium')
|
|
||||||
|
|
||||||
entry.media_files['webm_640'] = medium_filepath
|
metadata = transcoders.VideoTranscoder().discover(queued_filename)
|
||||||
|
|
||||||
# Save the width and height of the transcoded video
|
if skip_transcode(metadata):
|
||||||
entry.media_data_init(
|
_log.debug('Skipping transcoding')
|
||||||
width=transcoder.dst_data.videowidth,
|
# Just push the submitted file to the tmp_dst
|
||||||
height=transcoder.dst_data.videoheight)
|
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)
|
# Temporary file for the video thumbnail (cleaned up with workbench)
|
||||||
tmp_thumb = NamedTemporaryFile(dir=workbench.dir, suffix='.jpg', delete=False)
|
tmp_thumb = NamedTemporaryFile(dir=workbench.dir, suffix='.jpg', delete=False)
|
||||||
@ -109,10 +130,10 @@ def process_video(entry, workbench=None):
|
|||||||
tmp_thumb.name,
|
tmp_thumb.name,
|
||||||
180)
|
180)
|
||||||
|
|
||||||
# Push the thumbnail to public storage
|
# Push the thumbnail to public storage
|
||||||
_log.debug('Saving thumbnail...')
|
_log.debug('Saving thumbnail...')
|
||||||
mgg.public_store.copy_local_to_storage(tmp_thumb.name, thumbnail_filepath)
|
mgg.public_store.copy_local_to_storage(tmp_thumb.name, thumbnail_filepath)
|
||||||
entry.media_files['thumb'] = thumbnail_filepath
|
entry.media_files['thumb'] = thumbnail_filepath
|
||||||
|
|
||||||
if video_config['keep_original']:
|
if video_config['keep_original']:
|
||||||
# Push original file to public storage
|
# Push original file to public storage
|
||||||
|
@ -673,6 +673,7 @@ class VideoTranscoder:
|
|||||||
self._setup()
|
self._setup()
|
||||||
self._run()
|
self._run()
|
||||||
|
|
||||||
|
# XXX: This could be a static method.
|
||||||
def discover(self, src):
|
def discover(self, src):
|
||||||
'''
|
'''
|
||||||
Discover properties about a media file
|
Discover properties about a media file
|
||||||
@ -793,7 +794,8 @@ class VideoTranscoder:
|
|||||||
self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert')
|
self.audioconvert = gst.element_factory_make('audioconvert', 'audioconvert')
|
||||||
self.pipeline.add(self.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']
|
audiocaps = ['audio/x-raw-float']
|
||||||
self.audiocapsfilter.set_property(
|
self.audiocapsfilter.set_property(
|
||||||
'caps',
|
'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