public
Last active

  • Download Gist
transcoders.py
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
# GNU MediaGoblin -- federated, autonomous media hosting
# Copyright (C) 2011 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 sys
import logging
 
_log = logging.getLogger(__name__)
logging.basicConfig()
_log.setLevel(logging.DEBUG)
 
try:
import gobject
except:
_log.error('Could not import gobject')
 
try:
import pygst
pygst.require('0.10')
import gst
except:
_log.error('pygst could not be imported')
 
class VideoThumbnailer:
def __init__(self, src, dst):
self._set_up_pass(src, dst)
 
self.loop = gobject.MainLoop()
self.loop.run()
 
def _set_up_pass(self, src, dst):
self.pipeline = gst.Pipeline('TranscodingPipeline')
 
_log.debug('Pipeline: {0}'.format(self.pipeline))
 
self.filesrc = gst.element_factory_make('filesrc', 'filesrc')
self.filesrc.set_property('location', src)
self.pipeline.add(self.filesrc)
 
self.decoder = gst.element_factory_make('decodebin2', 'decoder')
 
self.decoder.connect('new-decoded-pad', self._on_dynamic_pad)
self.pipeline.add(self.decoder)
 
self.ffmpegcolorspace = gst.element_factory_make('ffmpegcolorspace', 'ffmpegcolorspace')
self.pipeline.add(self.ffmpegcolorspace)
 
self.videoscale = gst.element_factory_make('videoscale', 'videoscale')
self.pipeline.add(self.videoscale)
 
self.capsfilter = gst.element_factory_make('capsfilter', 'capsfilter')
self.capsfilter.set_property('caps', gst.caps_from_string('video/x-raw-rgb, width=180, height=100'))
self.pipeline.add(self.capsfilter)
 
self.jpegenc = gst.element_factory_make('jpegenc', 'jpegenc')
self.pipeline.add(self.jpegenc)
 
self.filesink = gst.element_factory_make('filesink', 'filesink')
self.filesink.set_property('location', dst)
self.pipeline.add(self.filesink)
 
# Link all the elements together
self.filesrc.link(self.decoder)
self.ffmpegcolorspace.link(self.videoscale)
self.videoscale.link(self.capsfilter)
self.capsfilter.link(self.jpegenc)
self.jpegenc.link(self.filesink)
 
bus = self.pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', self._on_message)
 
self.pipeline.set_state(gst.STATE_PLAYING)
 
 
def _on_message(self, bus, message):
_log.info((bus, message))
 
t = message.type
 
if t == gst.MESSAGE_EOS:
self.__shutdown()
 
def _on_dynamic_pad(self, dbin, pad, islast):
'''
Callback called when ``decodebin2`` has a pad that we can connect to
'''
pad.link(
self.ffmpegcolorspace.get_pad('sink'))
 
def __shutdown(self):
_log.debug(self.loop)
 
self.pipeline.set_state(gst.STATE_NULL)
 
gobject.idle_add(self.loop.quit)
 
 
if __name__ == '__main__':
VideoThumbnailer('/home/joar/Dropbox/Public/blender/fluid-box.mp4', '/tmp/dest.jpg')
VideoThumbnailer('/home/joar/Dropbox/iPhone/Video 2011-10-05 21 58 03.mov', '/tmp/dest2.jpg')

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.