aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mediagoblin/config_spec.ini7
-rw-r--r--mediagoblin/media_types/video/processing.py59
-rw-r--r--mediagoblin/media_types/video/transcoders.py4
-rw-r--r--mediagoblin/media_types/video/util.py60
4 files changed, 110 insertions, 20 deletions
diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini
index a9b0927b..44f6a68f 100644
--- a/mediagoblin/config_spec.ini
+++ b/mediagoblin/config_spec.ini
@@ -103,6 +103,13 @@ vorbis_quality = float(default=0.3)
# Autoplay the video when page is loaded?
auto_play = boolean(default=True)
+[[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)
diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py
index 5b9be242..41929f3d 100644
--- a/mediagoblin/media_types/video/processing.py
+++ b/mediagoblin/media_types/video/processing.py
@@ -23,6 +23,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)
@@ -79,24 +81,43 @@ def process_video(proc_state):
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'])
+
+ metadata = transcoders.VideoTranscoder().discover(queued_filename)
+
+ 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
+ entry.media_files['webm_640'] = medium_filepath
- # Save the width and height of the transcoded video
- entry.media_data_init(
- width=transcoder.dst_data.videowidth,
- height=transcoder.dst_data.videoheight)
+ # 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)
@@ -108,10 +129,10 @@ def process_video(proc_state):
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
diff --git a/mediagoblin/media_types/video/transcoders.py b/mediagoblin/media_types/video/transcoders.py
index 3a6a1c4d..d8290d41 100644
--- a/mediagoblin/media_types/video/transcoders.py
+++ b/mediagoblin/media_types/video/transcoders.py
@@ -700,6 +700,7 @@ class VideoTranscoder:
self._setup()
self._run()
+ # XXX: This could be a static method.
def discover(self, src):
'''
Discover properties about a media file
@@ -820,7 +821,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',
diff --git a/mediagoblin/media_types/video/util.py b/mediagoblin/media_types/video/util.py
new file mode 100644
index 00000000..93f098f7
--- /dev/null
+++ b/mediagoblin/media_types/video/util.py
@@ -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
+