def __init__(self, FILECHOSEN, FILENAME, CONTAINERCHOICE, AUDIOCODECVALUE, VIDEOCODECVALUE): gobject.GObject.__init__(self) # create a dictionay taking the Codec/Container values and mapping them with plugin names # No asfmux atm, hopefully Soc will solve that # Choose plugin based on Codec Name audiocaps = codecfinder.codecmap[AUDIOCODECVALUE] videocaps = codecfinder.codecmap[VIDEOCODECVALUE] self.AudioEncoderPlugin = codecfinder.get_audio_encoder_element(audiocaps) self.VideoEncoderPlugin = codecfinder.get_video_encoder_element(videocaps) # print "Audio encoder plugin is " + self.AudioEncoderPlugin # print "Video encoder plugin is " + self.VideoEncoderPlugin # Choose plugin and file suffix based on Container name containercaps = codecfinder.containermap[CONTAINERCHOICE] self.ContainerFormatPlugin = codecfinder.get_muxer_element(containercaps) # print "Container muxer is " + self.ContainerFormatPlugin self.ContainerFormatSuffix = codecfinder.csuffixmap[CONTAINERCHOICE] # Remove suffix from inbound filename so we can reuse it together with suffix to create outbound filename self.FileNameOnly = os.path.splitext(os.path.basename(FILENAME))[0] self.VideoDirectory = glib.get_user_special_dir(glib.USER_DIRECTORY_VIDEOS) CheckDir = os.path.isdir(self.VideoDirectory) if CheckDir == (False): os.mkdir(self.VideoDirectory) # elif CheckDir == (True): # print "Videos directory exist" # print self.VideoDirectory # create a variable with a timestamp code timeget = datetime.datetime.now() text = timeget.strftime("-%H%M%S-%d%m%Y") self.timestamp = str(text) self.pipeline = gst.Pipeline("TranscodingPipeline") self.pipeline.set_state(gst.STATE_PAUSED) self.uridecoder = gst.element_factory_make("uridecodebin", "uridecoder") self.uridecoder.set_property("uri", FILECHOSEN) # print "File loaded " + FILECHOSEN self.uridecoder.connect("pad-added", self.OnDynamicPad) self.pipeline.add(self.uridecoder) self.containermuxer = gst.element_factory_make(self.ContainerFormatPlugin, "containermuxer") self.pipeline.add(self.containermuxer) self.transcodefileoutput = gst.element_factory_make("filesink", "transcodefileoutput") self.transcodefileoutput.set_property("location", (self.VideoDirectory+self.FileNameOnly+self.timestamp+self.ContainerFormatSuffix)) self.pipeline.add(self.transcodefileoutput) self.containermuxer.link(self.transcodefileoutput) self.uridecoder.set_state(gst.STATE_PAUSED) self.BusMessages = self.BusWatcher() self.uridecoder.connect("no-more-pads", self.noMorePads) # we need to wait on this one before going further
def check_for_elements(self): if self.container==False: containerstatus=True videostatus=True else: containerchoice = self.builder.get_object ("containerchoice").get_active_text () containerstatus = codecfinder.get_muxer_element(codecfinder.containermap[containerchoice]) if self.havevideo: if self.videopasstoggle != True: if self.VideoCodec == "novid": videostatus=True else: videostatus = codecfinder.get_video_encoder_element(self.VideoCodec) else: videostatus=True if self.haveaudio: if self.audiopasstoggle != True: audiostatus = codecfinder.get_audio_encoder_element(self.AudioCodec) else: audiostatus=True else: audiostatus=True if self.havevideo == False: # this flags help check if input is audio-only file videostatus=True if not containerstatus or not videostatus or not audiostatus: self.missingtoggle=True fail_info = [] if self.containertoggle==True: audiostatus=True videostatus=True if containerstatus == False: fail_info.append(gst.caps_from_string(codecfinder.containermap[containerchoice])) if audiostatus == False: fail_info.append(self.AudioCodec) if videostatus == False: fail_info.append(self.VideoCodec) missing = [] for x in fail_info: missing.append(gst.pbutils.missing_encoder_installer_detail_new(x)) context = gst.pbutils.InstallPluginsContext () context.set_xid(self.TopWindow.get_window().xid) strmissing = str(missing) gst.pbutils.install_plugins_async (missing, context, \ self.donemessage, "NULL")
def check_for_elements(self): containerchoice = self.get_widget ("containerchoice").get_active_text () containerstatus = codecfinder.get_muxer_element(codecfinder.containermap[containerchoice]) audiostatus = codecfinder.get_audio_encoder_element(codecfinder.codecmap[self.AudioCodec]) videostatus = codecfinder.get_video_encoder_element(codecfinder.codecmap[self.VideoCodec]) if not containerstatus or not videostatus or not audiostatus: fail_info = [] if containerstatus == False: fail_info.append(gst.caps_from_string(codecfinder.containermap[containerchoice])) if audiostatus == False: fail_info.append(gst.caps_from_string(codecfinder.codecmap[self.AudioCodec])) if videostatus == False: fail_info.append(gst.caps_from_string (codecfinder.codecmap[self.VideoCodec])) missing = [] for x in fail_info: missing.append(gst.pbutils.missing_encoder_installer_detail_new(x)) context = gst.pbutils.InstallPluginsContext () gst.pbutils.install_plugins_async (missing, context, self.donemessage, "") else: self._start_transcoding()
def __init__(self, STREAMDATA, AUDIODATA, VIDEODATA): GObject.GObject.__init__(self) # Choose plugin based on Container name self.audiodata = AUDIODATA self.videodata = VIDEODATA self.streamdata = STREAMDATA # set preset directory Gst.preset_set_app_dir("/usr/share/transmageddon/presets/") # Choose plugin based on Codec Name # or switch to remuxing mode if any of the values are set to 'pastr' self.stoptoggle = False self.doaudio = False self.preset = self.streamdata['devicename'] self.blackborderflag = False self.missingplugin = False self.probestreamid = False self.sinkpad = None self.usedstreamids = [] # switching width and height around for rotationchoices where it makes sense if int(self.videodata[0]['rotationvalue']) == 1 or int( self.videodata[0]['rotationvalue']) == 3: nwidth = self.videodata[0]['videoheight'] nheight = self.videodata[0]['videowidth'] self.videodata[0]['videoheight'] = nheight self.videodata[0]['videowidth'] = nwidth # if needed create a variable to store the filename of the multipass \ # statistics file if self.streamdata['multipass'] != 0: videoencoderplugin = codecfinder.get_video_encoder_element( self.videodata[0]['outputvideocaps']) videoencoder = Gst.ElementFactory.make(videoencoderplugin, "videoencoder") properties = videoencoder.get_property_names() if "multipass-cache-file" in properties: self.cachefile = (str (GLib.get_user_cache_dir()) + "/transmageddon/" + \ "multipass-cache-file" + ".log") else: self.streamdata['multipass'] = 0 # gather preset data if relevant if self.preset != "nopreset": self.provide_presets() # Create transcoding pipeline self.pipeline = Gst.Pipeline() self.pipeline.set_state(Gst.State.PAUSED) # first check if we have a container format, if not set up output # for possible outputs should not be hardcoded if self.streamdata['container'] == False: x = 0 while x < len(self.audiodata): if self.audiodata[x]['outputaudiocaps'] != False: if not (self.audiodata[x]['outputaudiocaps'].intersect( Gst.caps_from_string( "audio/mpeg, mpegversion=1, layer=3")) ).is_empty(): self.streamdata['container'] = Gst.caps_from_string( "application/x-id3") x = x + 1 else: self.encodebinprofile = GstPbutils.EncodingContainerProfile.new( "containerformat", None, self.streamdata['container'], None) # What to do if we are not doing video passthrough (we only support video inside a # container format if self.videodata[0]['outputvideocaps'] != False: if (self.videodata[0]['dopassthrough'] == False) and (self.streamdata['passcounter'] == int(0)): self.videoflipper = Gst.ElementFactory.make( 'videoflip', None) self.videoflipper.set_property( "method", int(self.videodata[0]['rotationvalue'])) self.pipeline.add(self.videoflipper) self.colorspaceconverter = Gst.ElementFactory.make( "videoconvert", None) self.pipeline.add(self.colorspaceconverter) self.deinterlacer = Gst.ElementFactory.make( 'avdeinterlace', None) self.pipeline.add(self.deinterlacer) self.deinterlacer.link(self.colorspaceconverter) self.colorspaceconverter.link(self.videoflipper) self.deinterlacer.set_state(Gst.State.PAUSED) self.colorspaceconverter.set_state(Gst.State.PAUSED) self.videoflipper.set_state(Gst.State.PAUSED) # this part of the pipeline is used for both passthrough and re-encoding if (self.videodata[0]['outputvideocaps'] != False): videopreset = None self.videoprofile = GstPbutils.EncodingVideoProfile.new( self.videodata[0]['outputvideocaps'], videopreset, Gst.Caps.new_any(), 0) self.encodebinprofile.add_profile(self.videoprofile) # We do not need to do anything special for passthrough for audio, since we are not # including any extra elements between uridecodebin and encodebin x = 0 while x < len(self.audiodata): # print(self.audiodata[x]['outputaudiocaps']) if self.audiodata[x]['outputaudiocaps'] != False: audiopreset = None if self.streamdata['container'] == False: self.encodebinprofile = GstPbutils.EncodingAudioProfile.new( self.audiodata[x]['outputaudiocaps'], audiopreset, Gst.Caps.new_any(), 0) else: audioprofile = GstPbutils.EncodingAudioProfile.new( self.audiodata[x]['outputaudiocaps'], audiopreset, Gst.Caps.new_any(), 0) audioprofile.set_name("audioprofilename" + str(x)) self.encodebinprofile.add_profile(audioprofile) x = x + 1 # Dealing with Video multipass encoding if (self.streamdata['passcounter'] != int(0) and self.streamdata['multipass'] != int(0)): videoencoderplugin = codecfinder.get_video_encoder_element( self.videodata[0]['outputvideocaps']) self.videoencoder = Gst.ElementFactory.make( videoencoderplugin, "videoencoder") self.pipeline.add(self.videoencoder) GstPresetType = GObject.type_from_name("GstPreset") if GstPresetType in GObject.type_interfaces(self.videoencoder): self.videoencoder.load_preset( "Pass " + str(self.streamdata['passcounter'])) properties = self.videoencoder.get_property_names() if "multipass-cache-file" in properties: self.videoencoder.set_property("multipass-cache-file", self.cachefile) else: self.streamdata['multipass'] = 0 self.multipassfakesink = Gst.ElementFactory.make( "fakesink", "multipassfakesink") self.pipeline.add(self.multipassfakesink) self.videoencoder.set_state(Gst.State.PAUSED) self.multipassfakesink.set_state(Gst.State.PAUSED) else: self.encodebin = Gst.ElementFactory.make("encodebin", None) self.encodebin.connect("element-added", self.OnEncodebinElementAdd) self.encodebin.set_property("profile", self.encodebinprofile) self.encodebin.set_property("avoid-reencoding", True) self.pipeline.add(self.encodebin) self.encodebin.set_state(Gst.State.PAUSED) self.audiopads = {} x = 0 while x < len(self.audiodata): if self.audiodata[x]['outputaudiocaps'] != False: if self.streamdata['container'] != False: self.audiopads[x] = self.encodebin.emit( "request-profile-pad", "audioprofilename" + str(x)) x = x + 1 self.uridecoder = Gst.ElementFactory.make("uridecodebin", "uridecoder") self.uridecoder.set_property("uri", self.streamdata['filechoice']) self.uridecoder.connect('autoplug-continue', self.on_autoplug_continue) self.uridecoder.connect("pad-added", self.OnDynamicPad) self.uridecoder.connect('source-setup', self.dvdreadproperties) self.uridecoder.set_state(Gst.State.PAUSED) self.pipeline.add(self.uridecoder) if self.streamdata['passcounter'] != int(0): self.videoencoder.link(self.multipassfakesink) else: self.transcodefileoutput = Gst.ElementFactory.make("filesink", \ "transcodefileoutput") self.transcodefileoutput.set_property("location", \ (self.streamdata['outputdirectory']+"/"+self.streamdata['outputfilename'])) self.pipeline.add(self.transcodefileoutput) self.encodebin.link(self.transcodefileoutput) self.transcodefileoutput.set_state(Gst.State.PAUSED) self.uridecoder.set_state(Gst.State.PAUSED) self.BusMessages = self.BusWatcher() Gst.debug_bin_to_dot_file(self.pipeline, Gst.DebugGraphDetails.ALL, 'transmageddon-debug-graph') # we need to wait on this one before going further self.uridecoder.connect("no-more-pads", self.noMorePads)
def __init__(self, STREAMDATA, AUDIODATA, VIDEODATA): GObject.GObject.__init__(self) # Choose plugin based on Container name self.audiodata = AUDIODATA self.videodata = VIDEODATA self.streamdata = STREAMDATA # set preset directory Gst.preset_set_app_dir("/usr/share/transmageddon/presets/") # Choose plugin based on Codec Name # or switch to remuxing mode if any of the values are set to 'pastr' self.stoptoggle = False self.doaudio = False self.preset = self.streamdata["devicename"] self.blackborderflag = False self.missingplugin = False self.probestreamid = False self.sinkpad = None self.usedstreamids = [] # switching width and height around for rotationchoices where it makes sense if int(self.videodata[0]["rotationvalue"]) == 1 or int(self.videodata[0]["rotationvalue"]) == 3: nwidth = self.videodata[0]["videoheight"] nheight = self.videodata[0]["videowidth"] self.videodata[0]["videoheight"] = nheight self.videodata[0]["videowidth"] = nwidth # if needed create a variable to store the filename of the multipass \ # statistics file if self.streamdata["multipass"] != 0: videoencoderplugin = codecfinder.get_video_encoder_element(self.videodata[0]["outputvideocaps"]) videoencoder = Gst.ElementFactory.make(videoencoderplugin, "videoencoder") properties = videoencoder.get_property_names() if "multipass-cache-file" in properties: self.cachefile = str(GLib.get_user_cache_dir()) + "/transmageddon/" + "multipass-cache-file" + ".log" else: self.streamdata["multipass"] = 0 # gather preset data if relevant if self.preset != "nopreset": self.provide_presets() # Create transcoding pipeline self.pipeline = Gst.Pipeline() self.pipeline.set_state(Gst.State.PAUSED) # first check if we have a container format, if not set up output # for possible outputs should not be hardcoded if self.streamdata["container"] == False: x = 0 while x < len(self.audiodata): if self.audiodata[x]["outputaudiocaps"] != False: if not ( self.audiodata[x]["outputaudiocaps"].intersect( Gst.caps_from_string("audio/mpeg, mpegversion=1, layer=3") ) ).is_empty(): self.streamdata["container"] = Gst.caps_from_string("application/x-id3") x = x + 1 else: self.encodebinprofile = GstPbutils.EncodingContainerProfile.new( "containerformat", None, self.streamdata["container"], None ) # What to do if we are not doing video passthrough (we only support video inside a # container format if self.videodata[0]["outputvideocaps"] != False: if (self.videodata[0]["dopassthrough"] == False) and (self.streamdata["passcounter"] == int(0)): self.videoflipper = Gst.ElementFactory.make("videoflip", None) self.videoflipper.set_property("method", int(self.videodata[0]["rotationvalue"])) self.pipeline.add(self.videoflipper) self.colorspaceconverter = Gst.ElementFactory.make("videoconvert", None) self.pipeline.add(self.colorspaceconverter) self.deinterlacer = Gst.ElementFactory.make("avdeinterlace", None) self.pipeline.add(self.deinterlacer) self.deinterlacer.link(self.colorspaceconverter) self.colorspaceconverter.link(self.videoflipper) self.deinterlacer.set_state(Gst.State.PAUSED) self.colorspaceconverter.set_state(Gst.State.PAUSED) self.videoflipper.set_state(Gst.State.PAUSED) # this part of the pipeline is used for both passthrough and re-encoding if self.videodata[0]["outputvideocaps"] != False: videopreset = None self.videoprofile = GstPbutils.EncodingVideoProfile.new( self.videodata[0]["outputvideocaps"], videopreset, Gst.Caps.new_any(), 0 ) self.encodebinprofile.add_profile(self.videoprofile) # We do not need to do anything special for passthrough for audio, since we are not # including any extra elements between uridecodebin and encodebin x = 0 while x < len(self.audiodata): # print(self.audiodata[x]['outputaudiocaps']) if self.audiodata[x]["outputaudiocaps"] != False: audiopreset = None if self.streamdata["container"] == False: self.encodebinprofile = GstPbutils.EncodingAudioProfile.new( self.audiodata[x]["outputaudiocaps"], audiopreset, Gst.Caps.new_any(), 0 ) else: audioprofile = GstPbutils.EncodingAudioProfile.new( self.audiodata[x]["outputaudiocaps"], audiopreset, Gst.Caps.new_any(), 0 ) audioprofile.set_name("audioprofilename" + str(x)) self.encodebinprofile.add_profile(audioprofile) x = x + 1 # Dealing with Video multipass encoding if self.streamdata["passcounter"] != int(0) and self.streamdata["multipass"] != int(0): videoencoderplugin = codecfinder.get_video_encoder_element(self.videodata[0]["outputvideocaps"]) self.videoencoder = Gst.ElementFactory.make(videoencoderplugin, "videoencoder") self.pipeline.add(self.videoencoder) GstPresetType = GObject.type_from_name("GstPreset") if GstPresetType in GObject.type_interfaces(self.videoencoder): self.videoencoder.load_preset("Pass " + str(self.streamdata["passcounter"])) properties = self.videoencoder.get_property_names() if "multipass-cache-file" in properties: self.videoencoder.set_property("multipass-cache-file", self.cachefile) else: self.streamdata["multipass"] = 0 self.multipassfakesink = Gst.ElementFactory.make("fakesink", "multipassfakesink") self.pipeline.add(self.multipassfakesink) self.videoencoder.set_state(Gst.State.PAUSED) self.multipassfakesink.set_state(Gst.State.PAUSED) else: self.encodebin = Gst.ElementFactory.make("encodebin", None) self.encodebin.connect("element-added", self.OnEncodebinElementAdd) self.encodebin.set_property("profile", self.encodebinprofile) self.encodebin.set_property("avoid-reencoding", True) self.pipeline.add(self.encodebin) self.encodebin.set_state(Gst.State.PAUSED) self.audiopads = {} x = 0 while x < len(self.audiodata): if self.audiodata[x]["outputaudiocaps"] != False: if self.streamdata["container"] != False: self.audiopads[x] = self.encodebin.emit("request-profile-pad", "audioprofilename" + str(x)) x = x + 1 self.uridecoder = Gst.ElementFactory.make("uridecodebin", "uridecoder") self.uridecoder.set_property("uri", self.streamdata["filechoice"]) self.uridecoder.connect("autoplug-continue", self.on_autoplug_continue) self.uridecoder.connect("pad-added", self.OnDynamicPad) self.uridecoder.connect("source-setup", self.dvdreadproperties) self.uridecoder.set_state(Gst.State.PAUSED) self.pipeline.add(self.uridecoder) if self.streamdata["passcounter"] != int(0): self.videoencoder.link(self.multipassfakesink) else: self.transcodefileoutput = Gst.ElementFactory.make("filesink", "transcodefileoutput") self.transcodefileoutput.set_property( "location", (self.streamdata["outputdirectory"] + "/" + self.streamdata["outputfilename"]) ) self.pipeline.add(self.transcodefileoutput) self.encodebin.link(self.transcodefileoutput) self.transcodefileoutput.set_state(Gst.State.PAUSED) self.uridecoder.set_state(Gst.State.PAUSED) self.BusMessages = self.BusWatcher() Gst.debug_bin_to_dot_file(self.pipeline, Gst.DebugGraphDetails.ALL, "transmageddon-debug-graph") # we need to wait on this one before going further self.uridecoder.connect("no-more-pads", self.noMorePads)