# Gstreamer ruby handling TAG messages

**URL:** <https://www.ruby-forum.com/t/gstreamer-ruby-handling-tag-messages/226283>\
**Category:** Ruby-Gnome 2\
**Created:** [May 18, 2012, 3:19pm UTC](https://www.ruby-forum.com/t/gstreamer-ruby-handling-tag-messages/226283 "2012-05-18T15:19:29Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [May 18, 2012, 3:19pm UTC](https://www.ruby-forum.com/t/gstreamer-ruby-handling-tag-messages/226283/1 "2012-05-18T15:19:29Z")

</div>

All,

I am not getting any audio tags from my gstreamer playbin2 ruby setup.  
Not sure why. I am trying to grab the ICV (title, artist, etc) from the  
stream. My message bus is handling messages as I am getting  
STATE\_CHANGED messages, but I never see a TAG message which, by all  
documentation I can find  
([Plugins](http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-playbin2.html))  
says should happen by default with playbin2. UPDATE: I do get the tag  
messages, but I have to query get\_state to get them.

##########################  
require ‘thread’  
require ‘gst’  
Gst.init

#create a thread for a glib main loop  
thread = Thread.new() do  
@mainloop = GLib::MainLoop.new  
@mainloop.run  
end  
#make a few queries  
@query\_position = Gst::QueryPosition.new(Gst::Format::TIME)  
@query\_duration = Gst::QueryDuration.new(Gst::Format::TIME)

#make the playbin  
@playbin = Gst::ElementFactory.make(“playbin2”)

bin = Gst::Bin.new()  
@eq = Gst::ElementFactory.make(“equalizer-10bands”)  
autosink = Gst::ElementFactory.make(“autoaudiosink”)

bin.add(@eq)  
bin.add(autosink)  
@eq \>\> autosink

eqpad = @eq.get\_pad(“sink”)  
gpad = Gst::GhostPad.new(“gpad”, eqpad) # playbin2 requires a ghost  
pad, not sure why  
bin.add\_pad(gpad)

@playbin.audio\_sink = bin

#get the playbins bus  
bus = @playbin.bus  
#watch the bus for messages  
bus.add\_watch do |bus, message|  
p message  
case message.type

```
when Gst::Message::Type::TAG
  puts ("Got a TAG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
  tag_list = message.parse()
  #we need to get the key and value from the tag
  tag_list.each do |key,val|
    p "key: " + key
    p "val: " + val
    #handle this
  end

```

end  
true

end

@playbin.set\_property(“uri”,“[http://streampoint.radioio.com/streams/56/47bf578c13be7/](http://streampoint.radioio.com/streams/56/47bf578c13be7/)”)  
@playbin.play

##########################

So… not TAGs yet… but, if you call

@playbin.get\_state

We get the messages dumped to the screen. What am I missing???

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [May 21, 2012, 12:47am UTC](https://www.ruby-forum.com/t/gstreamer-ruby-handling-tag-messages/226283/2 "2012-05-21T00:47:19Z")

</div>

hi Michael,

sorry it took me a while to see this post… i had a similarly hard  
time working with tags in gstreamer.

i don’t have time to test the code right now, but you might try  
changing this:

case message.type  
when Gst::Message::Type::TAG  
…

to this:

case message.type  
when Gst::Message::TAG  
…

i also seem to remember having a problem with the #parse method on the  
message, so i used:

message.structure.entries

…to grab the tag information.

i’ll give your code a try when i get some more time.

you can check out the tag handling in my player here:  
[gsWax/brains/Wax.rb at master · lljk/gsWax · GitHub](https://github.com/lljk/gsWax/blob/master/brains/Wax.rb) (lines 95 - 109)

it’s basically the first thing i ever wrote in ruby, so the code’s  
kinda “funny” (got to get in there and clean it up,) but you can see how  
i handle the tags anyway…

good luck, keep rockin…

- j

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [May 21, 2012, 4:13pm UTC](https://www.ruby-forum.com/t/gstreamer-ruby-handling-tag-messages/226283/3 "2012-05-21T16:13:10Z")

</div>

Michael K. wrote in post #1061447:

> Jake,
> 
> …I say MOSTLY because this all works EXCEPT for  
> when the the signal handler for the ICYdemux src pad added event is  
> fired. When that happens, all audio stops playing and I still don’t get  
> any TAG messages from the ICYdemux.

hi Michael,

well, i’ve been playing around with your snippet a bit and with a  
couple of changes i get the tags to show up, but the playback still  
stops. bummer. i’ve got to head off to work (real bummer,) but i’ll  
keep fiddling with the thing when i can.

the changes i made are these:

bus.add\_watch do |bus, message|  
case message.type  
when Gst::Message::TAG  
puts (“Got a TAG!!!”)  
tag\_list = message.parse()  
#we need to get the key and value from the tag  
tag\_list.each do |key,val|  
#p "key: " + key  
#p "val: " + val

```
    p "key: #{key}" #changed this
    p "val: #{val}" #and this, as sometimes these values are

```

integers

```
    #handle this
  end

```

end  
true  
end

…i also had to add

thread.join

…to the end. running this i get some tag output, although as i  
mentioned the sound still cuts out… odd. hopefully we’ll get it  
working…

here’s the output i get:

Got a TAG!!!  
“key: organization”  
“val: io80’s Pop. An ioWorldMedia Production.”  
“key: genre”  
“val: 80’s Pop”  
“key: location”  
“val: [http://www.radioio.com](http://www.radioio.com)”  
a new pad src was created for  
ICY!!!  
a new pad src0 was created!  
Got a TAG!!!  
“key: audio-codec”  
“val: MPEG 2 Audio, Layer 3 (MP3)”  
Got a TAG!!!  
“key: bitrate”  
“val: 64000”  
“key: has-crc”  
“val: false”  
“key: channel-mode”  
“val: joint-stereo”  
Got a TAG!!!  
“key: audio-codec”  
“val: MPEG 2 Audio, Layer 3 (MP3)”  
Got a TAG!!!  
“key: bitrate”  
“val: 64000”

- j

---

<div class="post-metadata">

**Author:** ![mrkohrea](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/4491bb/32.png) [@mrkohrea](https://www.ruby-forum.com/u/mrkohrea)\
**Post date:** [May 21, 2012, 1:31am UTC](https://www.ruby-forum.com/t/gstreamer-ruby-handling-tag-messages/226283/4 "2012-05-21T01:31:25Z")

</div>

Jake,

Thanks for the response. I have made some headway on this. I have  
mostly working code now. I say MOSTLY because this all works EXCEPT for  
when the the signal handler for the ICYdemux src pad added event is  
fired. When that happens, all audio stops playing and I still don’t get  
any TAG messages from the ICYdemux. Take a peek, I appreciate any and  
all help! BTW: Changing Gst::Message::Type::TAG to Gst::Message::TAG  
had no effect. They are identical anyway, just run  
Gst::Message::Type::TAG == Gst::Message::TAG in ruby 😉

Here is my current code:

require ‘thread’  
require ‘gst’  
Gst.init

#create a thread for a glib main loop  
thread = Thread.new() do  
@mainloop = GLib::MainLoop.new  
@mainloop.run  
end

# Here is the gst-launch we are going for:

# gst-launch souphttpsrc

location=[http://streampoint.radioio.com/streams/56/47bf578c13be7/](http://streampoint.radioio.com/streams/56/47bf578c13be7/)  
iradio-mode=true ! tee name=t ! queue2 ! decodebin2 ! audioconvert !  
autoaudiosink t. ! queue2 ! icydemux ! fakesink -t

# 

# To do this we’ll do 4 things:

# 1. Create a SRC element that feeds a TEE

# 2. Create an AUDIO OUT element array

# 3. Create a DECODER for the audio

# 4. Create an ICYDEMUX element to decode ICY messages

# 5. Link the TEE src pads to the DECODER and the ICYDEMUX

respectively

apipeline = Gst::Pipeline.new(“ArydioPipeline”)

########## Step 1, create the SRC Bin

httpsrc = Gst::ElementFactory.make(“souphttpsrc”)  
httpsrc.location =  
“[http://streampoint.radioio.com/streams/56/47bf578c13be7/](http://streampoint.radioio.com/streams/56/47bf578c13be7/)”  
httpsrc.live = true  
httpsrc.do\_timestamp = false  
httpsrc.iradio\_mode = true

audiotee = Gst::ElementFactory.make(“tee”)  
audiotee.name = “audiotee”

apipeline.add(httpsrc)  
apipeline.add(audiotee)

########### Step 2, create the audio out pipeline. We’ll link to the  
decoder with the src is ready  
audioconv = Gst::ElementFactory.make(“audioconvert”)  
@eq = Gst::ElementFactory.make(“equalizer-10bands”)  
autosink = Gst::ElementFactory.make(“autoaudiosink”)

apipeline.add(audioconv)  
apipeline.add(@eq)  
apipeline.add(autosink)

audioconv \>\> @eq \>\> autosink

########### Step 3, create the DECODER bin  
queue1 = Gst::ElementFactory.make(“queue2”)  
decoder = Gst::ElementFactory.make(“decodebin2”)

## decodebin2 does not expose a SRC pad by default, we need to look for

the signal and then construct the pipeline  
decoder.signal\_connect(“pad-added”) do |element, pad, data|  
puts “a new pad #{pad.name} was created!”  
if pad.caps.to\_s.match(‘audio’)  
element \>\> audioconv  
else  
fakesink = Gst::ElementFactory.make(‘fakesink’)  
apipeline.add(fakesink)  
element \>\> fakesink  
end  
true  
end

apipeline.add(queue1)  
apipeline.add(decoder)

httpsrc \>\> audiotee  
queue1 \>\> decoder

########### Step 4, create the ICYDEMUX element

queue2 = Gst::ElementFactory.make(“queue2”)  
icydemx = Gst::ElementFactory.make(“icydemux”)

icydemx.signal\_connect(“pad-added”) do |element, pad, data|  
puts “a new pad #{pad.name} was created for  
ICY!!!”  
fakesink = Gst::ElementFactory.make(‘fakesink’)  
fakesink.set\_property(“dump”, true)  
apipeline.add(fakesink)  
element \>\> fakesink  
true  
end

apipeline.add(queue2)  
apipeline.add(icydemx)

queue2 \>\> icydemx

############ Step 5, Link the TEE to the two paths  
teesrc0 = audiotee.get\_request\_pad(“src%d”)  
queue1sink = queue1.get\_pad(“sink”)  
teesrc0.link(queue1sink)

teesrc1 = audiotee.get\_request\_pad(“src%d”)  
queue2sink = queue2.get\_pad(“sink”)  
teesrc1.link(queue2sink)

#get the apipeline bus  
bus = apipeline.bus  
#watch the bus for messages  
bus.add\_watch do |bus, message|  
case message.type

```
when Gst::Message::TAG
  puts ("Got a TAG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
  tag_list = message.parse()
  #we need to get the key and value from the tag
  tag_list.each do |key,val|
    p "key: " + key
    p "val: " + val
    #handle this
  end

```

end  
true

end

apipeline.play

loop = true  
sleep 1  
while loop  
puts “type ‘quit’ to quit”  
s = $stdin.gets.chomp  
if s.eql? “quit”  
loop = false  
end  
if s.eql? “rock”  
@eq.band0 = 10  
@eq.band1 = 10  
@eq.band2 = 10  
@eq.band3 = 10  
@eq.band4 = 5  
@eq.band5 = 0  
@eq.band6 = -3  
@eq.band7 = -3  
@eq.band8 = -3  
@eq.band9 = -3  
end  
if s.eql? “jazz”  
@eq.band0 = 10  
@eq.band1 = 10  
@eq.band2 = 5  
@eq.band3 = 0  
@eq.band4 = -5  
@eq.band5 = -5  
@eq.band6 = -5  
@eq.band7 = 5  
@eq.band8 = 10  
@eq.band9 = 10  
end  
if s.eql? “normal”  
@eq.band0 = 0  
@eq.band1 = 0  
@eq.band2 = 0  
@eq.band3 = 0  
@eq.band4 = 0  
@eq.band5 = 0  
@eq.band6 = 0  
@eq.band7 = 0  
@eq.band8 = 0  
@eq.band9 = 0  
end

end
