def set_metadata(self, track): """ Set track metadata for currently playing song. Only needs to be called by sources such as `appsrc` which do not already inject tags in playbin, e.g. when using :meth:`emit_data` to deliver raw audio data to GStreamer. :param track: the current track :type track: :class:`mopidy.models.Track` """ taglist = gst.TagList() artists = [a for a in (track.artists or []) if a.name] # Default to blank data to trick shoutcast into clearing any previous # values it might have. taglist[gst.TAG_ARTIST] = ' ' taglist[gst.TAG_TITLE] = ' ' taglist[gst.TAG_ALBUM] = ' ' if artists: taglist[gst.TAG_ARTIST] = ', '.join([a.name for a in artists]) if track.name: taglist[gst.TAG_TITLE] = track.name if track.album and track.album.name: taglist[gst.TAG_ALBUM] = track.album.name event = gst.event_new_tag(taglist) self._playbin.send_event(event)
def main(argv): parser = optparse.OptionParser() default = 'cli' parser.add_option('-r', '--runner', action="store", dest="runner", help="runner ('cli' or 'gtk', defaults to %s)" % default, default=default) options, args = parser.parse_args(argv[1:]) taglist = gst.TagList() taglist[gst.TAG_ARTIST] = 'Thomas' taglist[gst.TAG_TITLE] = 'Yes' taskk = encode.EncodeTask(args[0], args[1], taglist=taglist) if options.runner == 'cli': runner = task.SyncRunner() function = climain elif options.runner == 'gtk': runner = taskgtk.GtkProgressRunner() function = gtkmain function(runner, taskk)
def testWrite(self): fd, inpath = tempfile.mkstemp(suffix=u'.morituri.tagwrite.flac') # wave is pink-noise because a pure sine is encoded too efficiently # by flacenc and triggers not enough frames in parsing # FIXME: file a bug for this in GStreamer os.system('gst-launch ' 'audiotestsrc ' 'wave=pink-noise num-buffers=10 samplesperbuffer=588 ! ' 'audioconvert ! ' 'audio/x-raw-int,channels=2,width=16,height=16,rate=44100 ! ' 'flacenc ! filesink location=%s > /dev/null 2>&1' % inpath) os.close(fd) fd, outpath = tempfile.mkstemp(suffix=u'.morituri.tagwrite.flac') self.runner = task.SyncRunner(verbose=False) taglist = gst.TagList() taglist[gst.TAG_ARTIST] = 'Artist' taglist[gst.TAG_TITLE] = 'Title' t = encode.TagWriteTask(inpath, outpath, taglist) self.runner.run(t) t = encode.TagReadTask(outpath) self.runner.run(t) self.failUnless(t.taglist) self.assertEquals(t.taglist['audio-codec'], 'FLAC') self.assertEquals(t.taglist['description'], 'audiotest wave') self.assertEquals(t.taglist[gst.TAG_ARTIST], 'Artist') self.assertEquals(t.taglist[gst.TAG_TITLE], 'Title') os.unlink(inpath) os.unlink(outpath)
def testNoChange(self): taglist = gst.TagList() taglist[gst.TAG_DESCRIPTION] = 'audiotest wave' taglist[gst.TAG_AUDIO_CODEC] = 'FLAC' t = encode.SafeRetagTask(self._path, taglist) self.runner.run(t)
def main(args): "Tagsetter test, test result with:" "gst-launch -t playbin uri=file://$PWD/test.avi" # create a new bin to hold the elements bin = gst.parse_launch('audiotestsrc num-buffers=100 ! ' + 'lame ! ' + 'avimux name=mux ! ' + 'filesink location=test.avi') mux = bin.get_by_name('mux') bus = bin.get_bus() bus.add_signal_watch() bus.connect('message::eos', on_eos) # prepare bin.set_state(gst.STATE_READY) # send tags l = gst.TagList() l[gst.TAG_ARTIST] = "Unknown Genius" l[gst.TAG_TITLE] = "Unnamed Artwork" mux.merge_tags(l, gst.TAG_MERGE_APPEND) # start playing bin.set_state(gst.STATE_PLAYING) try: mainloop.run() except KeyboardInterrupt: pass # stop the bin bin.set_state(gst.STATE_NULL)
def testChange(self): taglist = gst.TagList() taglist[gst.TAG_DESCRIPTION] = 'audiotest retagged' taglist[gst.TAG_AUDIO_CODEC] = 'FLAC' taglist[gst.TAG_ARTIST] = 'Artist' t = encode.SafeRetagTask(self._path, taglist) self.runner.run(t)
def OnDynamicPad(self, uridecodebin, src_pad): origin = src_pad.get_caps() if (self.container == False): a = origin.to_string() if a.startswith("audio/"): sinkpad = self.encodebin.get_static_pad("audio_0") src_pad.link(sinkpad) else: if self.videocaps == "novid": c = origin.to_string() if c.startswith("audio/"): sinkpad = self.encodebin.emit("request-pad", origin) d = sinkpad.get_caps().to_string() if d.startswith("audio/"): src_pad.link(sinkpad) else: # Checking if its a subtitle pad which we can't deal with # currently.0 # Making sure that when we remove video from a file we don't # bother with the video pad. c = origin.to_string() if not c.startswith("text/"): if not (c.startswith("video/") and (self.videocaps == False)): # print "creating sinkpad" sinkpad = self.encodebin.emit("request-pad", origin) if c.startswith("audio/"): src_pad.link(sinkpad) elif ((c.startswith("video/") or c.startswith("image/")) and (self.videocaps != False)): if self.videopasstoggle == False: src_pad.link(self.deinterlacer.get_static_pad("sink")) self.videoflipper.get_static_pad("src").link(sinkpad) else: srccaps = src_pad.get_caps() srcstring = srccaps.to_string() #print "source pad is " + str(srcstring) sinkcaps = sinkpad.get_caps() sinkstring = sinkcaps.to_string() #print "sinkpad is " + str(sinkstring) src_pad.link(sinkpad) # Grab element from encodebin which supports tagsetter interface and set app name # to Transmageddon GstTagSetterType = gobject.type_from_name("GstTagSetter") tag_setting_element = self.encodebin.get_by_interface(GstTagSetterType) if tag_setting_element != None: taglist = gst.TagList() taglist[ gst. TAG_ENCODER] = "Transmageddon encoder" # this should probably be set to # string combining audio+video encoder # implementations taglist[gst.TAG_APPLICATION_NAME] = "Transmageddon transcoder" tag_setting_element.merge_tags(taglist, gst.TAG_MERGE_APPEND)
def populate_metadata(self, data): ''' Populate global tag list variable with file metadata for vorbistag audio element ''' self.tags = gst.TagList() for tag in data.keys(): if(gst.tag_exists(tag)): self.tags[tag] = data[tag] else: self.core.logger.log.debug("WARNING: Tag \"" + str(tag) + "\" is not registered with gstreamer.")
def _get_tags(self, type): tl = gst.TagList() tl[gst.TAG_ARTIST] = self.model.get_nickname() tl[gst.TAG_COMMENT] = "olpc" #this is unfortunately, unreliable #record.Record.log.debug("self.ca.metadata['title']->" + str(self.ca.metadata['title']) ) tl[gst.TAG_ALBUM] = "olpc" #self.ca.metadata['title'] tl[gst.TAG_DATE] = utils.getDateString(int(time.time())) stringType = constants.MEDIA_INFO[type]['istr'] # Translators: photo by photographer, e.g. "Photo by Mary" tl[gst.TAG_TITLE] = _('%(type)s by %(name)s') % {'type': stringType, 'name': self.model.get_nickname()} return tl
def _preplay(self, sltv): taglist = gst.TagList() taglist[gst.TAG_TITLE] = self.title_entry.get_text() taglist[gst.TAG_ARTIST] = self.artist_entry.get_text() taglist[gst.TAG_GENRE] = self.genre_entry.get_text() (year, month, day) = self.calendar.get_date() month += 1 date = "%d-%d-%d" % (year, month, day) taglist[gst.TAG_DATE] = date taglist[gst.TAG_LOCATION] = self.location_entry.get_text() taglist[gst.TAG_ORGANIZATION] = self.organization_entry.get_text() taglist[gst.TAG_COPYRIGHT] = self.copyright_entry.get_text() taglist[gst.TAG_CONTACT] = self.contact_entry.get_text() buffer = self.textview.get_buffer() text = buffer.get_text(buffer.get_start_iter(), buffer.get_end_iter(), True) taglist[gst.TAG_DESCRIPTION] = text self.sltv.set_metadata(taglist)
def __init__(self, tags, f, t, quality): Thread.__init__(self) self.tags = tags gnlcomposition = gst.element_factory_make("gnlcomposition") self.gnlcomposition = gnlcomposition audioconverter = gst.element_factory_make("audioconvert") gnlcomposition.connect("pad-added", partial(self.__on_pad, audioconverter = audioconverter)) # gnlcomposition.connect("new-decoded-pad", partial(self.__on_dynamic_pad, audioconverter = audioconverter)) filesrc = gst.element_factory_make("gnlfilesource", None) dur = tags["cut-end-at"]-tags["cut-start-at"] if dur > 0 and tags["cut-start-at"] != 0 and tags["cut-end-at"] != 0: filesrc.set_property("location", f) filesrc.set_property("start", tags["cut-start-at"]) filesrc.set_property("duration", dur) self.tags["duration"] = dur else: # print "Discarding start/end silence removing "+unicode(tags["cut-start-at"])+"-"+unicode(tags["cut-end-at"]) filesrc.set_property("location", f) filesrc.set_property("start", 0) # max 1 hour filesrc.set_property("duration", self.tags["duration"]) gnlcomposition.add(filesrc) self.filesrc = filesrc audioresample = gst.element_factory_make("audioresample") audiofilter = gst.element_factory_make("capsfilter") audiofilter.set_property("caps", self.caps) self.pipe = gst.Pipeline("pipeline") audioconverter2 = gst.element_factory_make("audioconvert") rgvolume = gst.element_factory_make("rgvolume") self.rgvolume = rgvolume rgvolume.set_property("album-mode", 0) rgvolume.set_property("pre-amp", tags["replaygain-track-gain"]) rgvolume.set_property("headroom", 60.0) rglimiter = gst.element_factory_make("rglimiter") tl = gst.TagList() # tl[gst.TAG_ALBUM_GAIN] = tags["replaygain-track-gain"] # tl[gst.TAG_ALBUM_PEAK] = tags["replaygain-track-peak"] # This do not work tl[gst.TAG_TRACK_GAIN] = tags["replaygain-track-gain"] tl["replaygain-track-gain"] = tags["replaygain-track-gain"] tl[gst.TAG_TRACK_PEAK] = tags["replaygain-track-peak"] tl["replaygain-track-peak"] = tags["replaygain-track-peak"] tl[gst.TAG_REFERENCE_LEVEL] = tags["replaygain-reference-level"] tl["replaygain-reference-level"] = tags["replaygain-reference-level"] event = gst.event_new_tag(tl) rgvolume_sink = rgvolume.get_pad("sink") rgvolume_sink.send_event(event) rgvolume.send_event(event) audioconverter3 = gst.element_factory_make("audioconvert") vorbisenc = gst.element_factory_make("vorbisenc") # [-0.1,1] # 64 = 0.1 # 128 = 0.4 # -q0 64 kb/s # -q1 80 kb/s # -q2 96 kb/s # -q3 112 kb/s # -q4 128 kb/s # -q5 160 kb/s # -q6 192 kb/s # -q7 224 kb/s # -q8 256 kb/s # -q9 320 kb/s # -q10 500 kb/s # If we change quality we need to change it also in Pipeline vorbisenc.set_property("quality", quality) oggmux = gst.element_factory_make('oggmux') filesink = gst.element_factory_make("filesink") filesink.set_property("location", t) self.pipe.add(gnlcomposition, audioconverter, audioresample, audiofilter, audioconverter2, rgvolume, audioconverter3, rglimiter, vorbisenc, oggmux, filesink) gst.element_link_many(audioconverter, audioresample, audiofilter, audioconverter2, rgvolume, audioconverter3, rglimiter, vorbisenc, oggmux, filesink) bus = self.pipe.get_bus() bus.add_signal_watch() bus.connect("message::eos", self.bus_message_eos) # bus.connect("message", self.bus_message) self.pipe.set_state(gst.STATE_PLAYING)
track = self.metadata.tracks[number - 1] trackArtist = track.artist title = track.title mbidTrack = track.mbid mbidTrackArtist = track.mbidArtist except IndexError, e: print 'ERROR: no track %d found, %r' % (number, e) raise else: # htoa defaults to disc's artist title = 'Hidden Track One Audio' # here to avoid import gst eating our options import gst ret = gst.TagList() # gst-python 0.10.15.1 does not handle unicode -> utf8 string # conversion # see http://bugzilla.gnome.org/show_bug.cgi?id=584445 if self.metadata and not self.metadata.various: ret["album-artist"] = albumArtist.encode('utf-8') ret[gst.TAG_ARTIST] = trackArtist.encode('utf-8') ret[gst.TAG_TITLE] = title.encode('utf-8') ret[gst.TAG_ALBUM] = disc.encode('utf-8') # gst-python 0.10.15.1 does not handle tags that are UINT # see gst-python commit 26fa6dd184a8d6d103eaddf5f12bd7e5144413fb # FIXME: no way to compare against 'master' version after 0.10.15 if gst.pygst_version >= (0, 10, 15): ret[gst.TAG_TRACK_NUMBER] = number