Discussion:
[Savonet-users] How to inject StreamTitle= in the real time stream immediately prior to track change?
Jeff Garvas
2017-03-20 19:23:39 UTC
Permalink
I'm using liquidsoap for an unconventional use case where I predominantly
stream silence, and inject very short audio files sourced from a police
scanner. The way I've come up with doing this (thanks to some help from
others here) is as follows below. This is working very very well.


# This creates a 1 second silence period
silence = blank(duration=1.)

#
myqueue = request.queue()
myqueue = server.insert_metadata(id="S4",myqueue)

# If there is anything in the queue, play it. If not, play the silence
defined above repeatedly:
stream = fallback(track_sensitive=false, [myqueue, silence])


Here is the challenge I have -- I want to be able to include a StreamTitle=
in the streaming payload immediately prior to adding a new track to the
queue. I ran a packet capture on windows based application that supports
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio source
(when transitioning from silence)

This creates two questions in my mind. First, what format of metadata is
this approach? I do not want to have to send http requests to the icecast
server for each change because they're happening too frequently. (the
tracks are sometimes very brief). How can I rewrite a field out of a
.mp3 file into SongTitle= to do this cleanly? Or do I have to manually do
it via the socket I'm using to add tracks to the queue?

My second question is, if you've set the StreamTitle to something and your
queue runs out and you go back to the silence loop above will the previous
track title remain? If it remains is there a clean way to change that
title once, not every second you're waiting for an item to get queued?

Thanks,

Jeff
Romain Beauxis
2017-03-21 04:54:08 UTC
Permalink
Hi,
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I predominantly
stream silence, and inject very short audio files sourced from a police
scanner.
Well, that certainly is an interesting usage!
Post by Jeff Garvas
The way I've come up with doing this (thanks to some help from
others here) is as follows below. This is working very very well.
# This creates a 1 second silence period
silence = blank(duration=1.)
#
myqueue = request.queue()
myqueue = server.insert_metadata(id="S4",myqueue)
# If there is anything in the queue, play it. If not, play the silence
stream = fallback(track_sensitive=false, [myqueue, silence])
Here is the challenge I have -- I want to be able to include a
StreamTitle=
Post by Jeff Garvas
in the streaming payload immediately prior to adding a new track to the
queue. I ran a packet capture on windows based application that supports
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio source
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's metadata, like
artist or title as they are later sent via output.icecast etc.

Have you tried the annotate: protocol? You can wrap your request into a
annotate: uri, allowing you to pass extra metadata.

For instance, instead of:
<source>.push http://.. (or /path/to/file etc.)
You can do:
<source>.push annotate:title="My Custom Title",artist="My custom
artist":http://..

And the annotated metadata will be added, possibly overriding any metadata
with the same field name in your original request.
Post by Jeff Garvas
This creates two questions in my mind. First, what format of metadata is
this approach? I do not want to have to send http requests to the icecast
server for each change because they're happening too frequently. (the
tracks are sometimes very brief). How can I rewrite a field out of a
.mp3
Post by Jeff Garvas
file into SongTitle= to do this cleanly? Or do I have to manually do it
via the socket I'm using to add tracks to the queue?
My second question is, if you've set the StreamTitle to something and your
queue runs out and you go back to the silence loop above will the previous
track title remain? If it remains is there a clean way to change that
title
Post by Jeff Garvas
once, not every second you're waiting for an item to get queued?
By default, fallback() and switch() replay the last metadata from a child
source when switching back to it.

By the way, do you need a finite silence in your script? It feel like, with
track_sensitive=false, your fallback would switch to the request source
immediately when it becomes available..

Hope this helps,
Romain
Jeff Garvas
2017-03-21 21:44:19 UTC
Permalink
Post by Romain Beauxis
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I predominantly
stream silence, and inject very short audio files sourced from a police
scanner.
Well, that certainly is an interesting usage!
It's working quite well. When the application that generates a .mp3 file
writes the file it runs a script I wrote that connects to the socket and
queues the mp3 file. Liquidsoap is pointed to a mount point at
http://broadcastify.com.
Post by Romain Beauxis
Here is the challenge I have -- I want to be able to include a
StreamTitle=
Post by Jeff Garvas
in the streaming payload immediately prior to adding a new track to the
queue. I ran a packet capture on windows based application that
supports
Post by Jeff Garvas
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio source
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's metadata, like
artist or title as they are later sent via output.icecast etc.
Yes - but I literally mean StreamTitle. I did a packet capture of another
application that does this called RadioFeed, where you use an audio cable
to feed a sound card and a serial cable to get the "alpha tag" of the
channel from the scanner itself. If you look at the packet capture the
alpha tag of the channel (say, "PD Dispatch") is in the payload like this:
StreamTitle=PD%20Dispatch (i think the %20 was in there, not 100% sure).

So its a format that uses the phrase StreamTitle. I don't know if this is
a old meta tag methodology, shoutcast specific, or icecast? It is not
sending http updates to the server, its in the stream itself.
Post by Romain Beauxis
Have you tried the annotate: protocol? You can wrap your request into a
annotate: uri, allowing you to pass extra metadata.
<source>.push http://.. (or /path/to/file etc.)
<source>.push annotate:title="My Custom Title",artist="My custom
artist":http://..
I've messed with a number of approaches where maybe I'd inject the title
via the socket immediately prior to queuing and while I got that working it
was making a separate http:// call to my icecast test server, and the
problem is these titles can change very frequently.

My preference would be to inject the title into the .mp3 and have some sort
of rewrite logic take the content of that metatag and somehow put it into
SongTitle= or an equivalent but I can't find any comprehensive
documentation on how to do that :/

And the annotated metadata will be added, possibly overriding any metadata
Post by Romain Beauxis
with the same field name in your original request.
By default, fallback() and switch() replay the last metadata from a child
source when switching back to it.
Is there a way to override it with something or blank it out?

By the way, do you need a finite silence in your script? It feel like, with
Post by Romain Beauxis
track_sensitive=false, your fallback would switch to the request source
immediately when it becomes available..
I basically need it to not stream any audio at all when there isn't
something in the queue. If you want to hear it yourself you can go here,
click on the play icon, and play the audio. It may be silent for a minute
or two until someone speaks :)

http://www.broadcastify.com/listen/feed/24877
d***@gmail.com
2017-03-21 22:48:38 UTC
Permalink
Hi, I am not sure what you are doing exactly there, but if the filename
of the generated mp3 gave the title, I would use that by scripting just
a little. If that was not the case then I would probably try to create
the mp3 with metadata so that everything is ready from start and not
need to complicate things later. But again, I made such thoughts while
not really understanding the situation very very well.

George
Post by Jeff Garvas
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I
predominantly
Post by Jeff Garvas
stream silence, and inject very short audio files sourced from a
police
Post by Jeff Garvas
scanner.
Well, that certainly is an interesting usage!
It's working quite well. When the application that generates a .mp3
file writes the file it runs a script I wrote that connects to the
socket and queues the mp3 file. Liquidsoap is pointed to a mount
point at http://broadcastify.com.
Post by Jeff Garvas
Here is the challenge I have -- I want to be able to include a StreamTitle=
in the streaming payload immediately prior to adding a new track
to the
Post by Jeff Garvas
queue. I ran a packet capture on windows based application
that supports
Post by Jeff Garvas
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3
audio source
Post by Jeff Garvas
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's
metadata, like artist or title as they are later sent via
output.icecast etc.
Yes - but I literally mean StreamTitle. I did a packet capture of
another application that does this called RadioFeed, where you use an
audio cable to feed a sound card and a serial cable to get the "alpha
tag" of the channel from the scanner itself. If you look at the
packet capture the alpha tag of the channel (say, "PD Dispatch") is in
the payload like this: StreamTitle=PD%20Dispatch (i think the %20 was
in there, not 100% sure).
So its a format that uses the phrase StreamTitle. I don't know if
this is a old meta tag methodology, shoutcast specific, or icecast?
It is not sending http updates to the server, its in the stream itself.
Have you tried the annotate: protocol? You can wrap your request
into a annotate: uri, allowing you to pass extra metadata.
<source>.push http://.. (or /path/to/file etc.)
<source>.push annotate:title="My Custom Title",artist="My custom
artist":http://..
I've messed with a number of approaches where maybe I'd inject the
title via the socket immediately prior to queuing and while I got that
working it was making a separate http:// call to my icecast test
server, and the problem is these titles can change very frequently.
My preference would be to inject the title into the .mp3 and have some
sort of rewrite logic take the content of that metatag and somehow put
it into SongTitle= or an equivalent but I can't find any comprehensive
documentation on how to do that :/
And the annotated metadata will be added, possibly overriding any
metadata with the same field name in your original request.
By default, fallback() and switch() replay the last metadata from
a child source when switching back to it.
Is there a way to override it with something or blank it out?
By the way, do you need a finite silence in your script? It feel
like, with track_sensitive=false, your fallback would switch to
the request source immediately when it becomes available..
I basically need it to not stream any audio at all when there isn't
something in the queue. If you want to hear it yourself you can go
here, click on the play icon, and play the audio. It may be silent
for a minute or two until someone speaks :)
http://www.broadcastify.com/listen/feed/24877
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
Jeff Garvas
2017-03-21 22:51:12 UTC
Permalink
I appreciate your help! My challenge is the recipie in liquid soap, but I
agree I can do it in the. iD tags or the file name and then extract that in
the script, but I can't figure out how to tell liquid soap to put it in the
right spot :)
Hi, I am not sure what you are doing exactly there, but if the filename of
the generated mp3 gave the title, I would use that by scripting just a
little. If that was not the case then I would probably try to create the
mp3 with metadata so that everything is ready from start and not need to
complicate things later. But again, I made such thoughts while not really
understanding the situation very very well.
George
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I predominantly
stream silence, and inject very short audio files sourced from a police
scanner.
Well, that certainly is an interesting usage!
It's working quite well. When the application that generates a .mp3 file
writes the file it runs a script I wrote that connects to the socket and
queues the mp3 file. Liquidsoap is pointed to a mount point at
http://broadcastify.com.
Post by Jeff Garvas
Here is the challenge I have -- I want to be able to include a
StreamTitle=
Post by Jeff Garvas
in the streaming payload immediately prior to adding a new track to the
queue. I ran a packet capture on windows based application that
supports
Post by Jeff Garvas
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio source
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's metadata, like
artist or title as they are later sent via output.icecast etc.
Yes - but I literally mean StreamTitle. I did a packet capture of another
application that does this called RadioFeed, where you use an audio cable
to feed a sound card and a serial cable to get the "alpha tag" of the
channel from the scanner itself. If you look at the packet capture the
StreamTitle=PD%20Dispatch (i think the %20 was in there, not 100% sure).
So its a format that uses the phrase StreamTitle. I don't know if this is
a old meta tag methodology, shoutcast specific, or icecast? It is not
sending http updates to the server, its in the stream itself.
Have you tried the annotate: protocol? You can wrap your request into a
annotate: uri, allowing you to pass extra metadata.
<source>.push http://.. (or /path/to/file etc.)
http://..
I've messed with a number of approaches where maybe I'd inject the title
via the socket immediately prior to queuing and while I got that working it
was making a separate http:// call to my icecast test server, and the
problem is these titles can change very frequently.
My preference would be to inject the title into the .mp3 and have some
sort of rewrite logic take the content of that metatag and somehow put it
into SongTitle= or an equivalent but I can't find any comprehensive
documentation on how to do that :/
And the annotated metadata will be added, possibly overriding any metadata
with the same field name in your original request.
By default, fallback() and switch() replay the last metadata from a child
source when switching back to it.
Is there a way to override it with something or blank it out?
By the way, do you need a finite silence in your script? It feel like,
with track_sensitive=false, your fallback would switch to the request
source immediately when it becomes available..
I basically need it to not stream any audio at all when there isn't
something in the queue. If you want to hear it yourself you can go here,
click on the play icon, and play the audio. It may be silent for a minute
or two until someone speaks :)
http://www.broadcastify.com/listen/feed/24877
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
Bill Burton
2017-03-21 23:27:56 UTC
Permalink
Hello Jeff,

I was able to locate the Broadcastify documentation for Alternative
Broadcasting Software and Clients at
https://broadcastify.zendesk.com/hc/en-us/articles/204740015-Alternative-Broadcasting-Software-and-Clients
and
the liquidsoap integration instructions at
http://wiki.radioreference.com/index.php/Liquidsoap.
From the above, it looks like broadcastify.com supports an Icecast server.
The example on the Liquidsoap page is this:

#!/usr/bin/liquidsoap -v
radio = input.alsa(device="<device>")
output.icecast(%mp3(stereo=false, bitrate=16, samplerate=22050),
host="audio3.radioreference.com",
port=80, password="xxxxxxxxx", genre="Scanner",
description="Scanner audio", mount="/xxxxxxxx",
name="Baltimore Maryland Police/Fire/EMS", user="source",
url="http://www.scanbaltimore.com", radio)

which is simply relaying from a sound card directly to the web stream.

What I have used to rewrite a stream title to broadcast to Airtime is this:

source = rewrite_metadata([("title", "#{artist} - #{title}")], source)

Where title and artist are defined however you require and they are
separated by <space><hyphen><space>. Broadcastify may or may not use the
same convention so YMMV.

Hope this helps,
-Bill
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I predominantly
stream silence, and inject very short audio files sourced from a police
scanner.
Well, that certainly is an interesting usage!
It's working quite well. When the application that generates a .mp3 file
writes the file it runs a script I wrote that connects to the socket and
queues the mp3 file. Liquidsoap is pointed to a mount point at
http://broadcastify.com.
Post by Jeff Garvas
Here is the challenge I have -- I want to be able to include a
StreamTitle=
Post by Jeff Garvas
in the streaming payload immediately prior to adding a new track to the
queue. I ran a packet capture on windows based application that
supports
Post by Jeff Garvas
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio source
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's metadata, like
artist or title as they are later sent via output.icecast etc.
Yes - but I literally mean StreamTitle. I did a packet capture of another
application that does this called RadioFeed, where you use an audio cable
to feed a sound card and a serial cable to get the "alpha tag" of the
channel from the scanner itself. If you look at the packet capture the
StreamTitle=PD%20Dispatch (i think the %20 was in there, not 100% sure).
So its a format that uses the phrase StreamTitle. I don't know if this is
a old meta tag methodology, shoutcast specific, or icecast? It is not
sending http updates to the server, its in the stream itself.
Have you tried the annotate: protocol? You can wrap your request into a
annotate: uri, allowing you to pass extra metadata.
<source>.push http://.. (or /path/to/file etc.)
<source>.push annotate:title="My Custom Title",artist="My custom
artist":http://..
I've messed with a number of approaches where maybe I'd inject the title
via the socket immediately prior to queuing and while I got that working it
was making a separate http:// call to my icecast test server, and the
problem is these titles can change very frequently.
My preference would be to inject the title into the .mp3 and have some
sort of rewrite logic take the content of that metatag and somehow put it
into SongTitle= or an equivalent but I can't find any comprehensive
documentation on how to do that :/
And the annotated metadata will be added, possibly overriding any metadata
with the same field name in your original request.
By default, fallback() and switch() replay the last metadata from a child
source when switching back to it.
Is there a way to override it with something or blank it out?
By the way, do you need a finite silence in your script? It feel like,
with track_sensitive=false, your fallback would switch to the request
source immediately when it becomes available..
I basically need it to not stream any audio at all when there isn't
something in the queue. If you want to hear it yourself you can go here,
click on the play icon, and play the audio. It may be silent for a minute
or two until someone speaks :)
http://www.broadcastify.com/listen/feed/24877
John Chewter
2017-03-22 00:05:00 UTC
Permalink
I just found this. It looks like you could do it all in icecast?

http://rockdio.org/ayudatech/how-to-insert-live-interventions-in-a-icecast2-stream-without-creating-a-silence/
Jeff Garvas
2017-03-22 00:15:08 UTC
Permalink
I may need to re-read this with a clear head. I don't own the icecast
server I'm feeding which is why I started with liquidsoap. I think you're
implying I could do everything within icecast, presuming I was the icecast
streaming source?

I probably could, but this is a remote source feeding a centralized icecast
system. In its current form it works perfectly, its just missing titles :)
Post by John Chewter
I just found this. It looks like you could do it all in icecast?
http://rockdio.org/ayudatech/how-to-insert-live-
interventions-in-a-icecast2-stream-without-creating-a-silence/
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
d***@gmail.com
2017-03-22 00:26:59 UTC
Permalink
Yes you can use the fallback of icecast to move the listener to the
fallback mount in case the main mount is not connected to any source,
and then automatically move the listener back to the main mount once
connected. So you keep listening to a dead mount point which becomes
alive at times and them goes back dead again etc. This does not cover
metadata updates though, at least not in the way I "understood" he wants
it to happen I may be wrong.

George
Post by John Chewter
I just found this. It looks like you could do it all in icecast?
http://rockdio.org/ayudatech/how-to-insert-live-interventions-in-a-icecast2-stream-without-creating-a-silence/
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
Jeff Garvas
2017-03-22 00:11:26 UTC
Permalink
Bill,

Yep - I knew about that and its how I'm connecting to them but thanks for
reminding me about this because i was starting to wonder if the
StreamTitle= i saw in a packet capture was Shoutcast and I forgot this
example was out there confirming they're icecast. The thing that example
never solved for was putting titles into the stream.

The difference is also I'm not sourcing audio from a physical scanner. I'm
using USB dongles (RTL-SDR) to capture digital radio off an antenna via
USB, track the data channel to determine where each digital talk-group will
appear on any number of voice radio frequencies, capture that specific
transmission, and write it to a .wav file (it's pretty darn impressive
how well it works).

Since the output is .wav I'm converting them to .mp3 with lame, where I can
easily inject the alpha tag of the transmission into the ID. The problem
with the example you found is his solution isn't doing alpha tagging. His
stream doesn't include names.

Alpha tagging (in broadcastify terms) is when you take the name of a given
scanner channel and display it during the stream just like a song title,
but instead of a song title its the channel name to give the listener
context to what they're hearing. So say one moment it may be "Police Disp
1" but maybe 10 seconds later its the "Fire Disp 1" - the more elaborate
solutions sneak the word "Scanning" in when there is nothing playing.

Jeff
Post by Bill Burton
Hello Jeff,
I was able to locate the Broadcastify documentation for Alternative
Broadcasting Software and Clients at https://broadcastify.
zendesk.com/hc/en-us/articles/204740015-Alternative-
Broadcasting-Software-and-Clients and the liquidsoap integration
instructions at http://wiki.radioreference.com/index.php/Liquidsoap.
Bill Burton
2017-03-22 17:37:45 UTC
Permalink
Hello Jeff,
Post by Jeff Garvas
Bill,
Yep - I knew about that and its how I'm connecting to them but thanks for
reminding me about this because i was starting to wonder if the
StreamTitle= i saw in a packet capture was Shoutcast and I forgot this
example was out there confirming they're icecast. The thing that example
never solved for was putting titles into the stream.
The difference is also I'm not sourcing audio from a physical scanner.
I'm using USB dongles (RTL-SDR) to capture digital radio off an antenna via
USB, track the data channel to determine where each digital talk-group will
appear on any number of voice radio frequencies, capture that specific
transmission, and write it to a .wav file (it's pretty darn impressive
how well it works).
Right. I posted the example code to give others an idea of how you were
streaming even though the way you're feeding the stream differs.
Post by Jeff Garvas
Since the output is .wav I'm converting them to .mp3 with lame, where I
can easily inject the alpha tag of the transmission into the ID. The
problem with the example you found is his solution isn't doing alpha
tagging. His stream doesn't include names.
Right.
Post by Jeff Garvas
Alpha tagging (in broadcastify terms) is when you take the name of a given
scanner channel and display it during the stream just like a song title,
but instead of a song title its the channel name to give the listener
context to what they're hearing. So say one moment it may be "Police Disp
1" but maybe 10 seconds later its the "Fire Disp 1" - the more elaborate
solutions sneak the word "Scanning" in when there is nothing playing.
That should be doable. Have you seen the page
http://liquidsoap.fm/doc-1.2.1/metadata.html? The rewrite_metadata()
function supports conditional logic so you could insert "Scanning" when the
title is blank. Also note at the end of that page, there are a couple of
ways metadata is being sent externally to liquidsoap.

However, given that you are setting the ID3 title tag for each mp3 with the
Alpha tag, the following might work:

artist = 'Twinsburg, Hudson and Reminderville Police, Fire / EMS'
title = '$(if $(title),"$(artist) - $(title)","$(artist) - Scanning")'
radio = rewrite_metadata([("title", title)], radio)
output.icecast(%mp3(...), ..., radio)

There may be a better way to do the above but hopefully, this will help.

-Bill
Post by Jeff Garvas
Jeff
Hello Jeff,
I was able to locate the Broadcastify documentation for Alternative
Broadcasting Software and Clients at
https://broadcastify.zendesk.com/hc/en-us/articles/204740015-Alternative-Broadcasting-Software-and-Clients and
the liquidsoap integration instructions at
http://wiki.radioreference.com/index.php/Liquidsoap.
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
Romain Beauxis
2017-03-22 18:50:12 UTC
Permalink
Post by Jeff Garvas
Post by Romain Beauxis
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I
predominantly
stream silence, and inject very short audio files sourced from a police
scanner.
Well, that certainly is an interesting usage!
It's working quite well. When the application that generates a .mp3 file
writes the file it runs a script I wrote that connects to the socket and
queues the mp3 file. Liquidsoap is pointed to a mount point at
http://broadcastify.com.
Post by Romain Beauxis
Post by Jeff Garvas
Here is the challenge I have -- I want to be able to include a StreamTitle=
in the streaming payload immediately prior to adding a new track to the
queue. I ran a packet capture on windows based application that supports
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio source
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's metadata, like
artist or title as they are later sent via output.icecast etc.
Yes - but I literally mean StreamTitle. I did a packet capture of another
application that does this called RadioFeed, where you use an audio cable
to
Post by Jeff Garvas
feed a sound card and a serial cable to get the "alpha tag" of the channel
from the scanner itself. If you look at the packet capture the alpha tag
of
Post by Jeff Garvas
StreamTitle=PD%20Dispatch (i think the %20 was in there, not 100% sure).
So its a format that uses the phrase StreamTitle. I don't know if this
is a
Post by Jeff Garvas
old meta tag methodology, shoutcast specific, or icecast? It is not
sending
Post by Jeff Garvas
http updates to the server, its in the stream itself.
Let me backtrack here for a second.

Liquidsoap streams have metadata attached to them, potentially at any
position. When a metadata packet is received by output.icecast or
output.shoutcast, it computes the new value for StreamTitle and sends that
to icecast/shoutcast. See here:
https://github.com/savonet/liquidsoap/blob/master/src/outputs/icecast2.ml#L402

In turn, when icecast/shoutcast receives the metadata update call, it
inserts the new metadata into the listeners stream, which is what you refer
to as StreamTitle I think.

So, in the most simple terms, as soon as a metadata of the form:
[("title","Some text here")] is passed, with nothing else, them your
listeners will see StreamTitle updated to "Some text here".

Thus, your problem becomes simply: how to insert a metadata packet with
only title like above.

If, as you said in another message, your original files are .wav files then
all you need to do is, instead of pushing a request of the form:
/path/to/file.wav, push a request of the form:
annotate:title="StreamTitle content":/path/to/file.wav

And this will trickle down the stream path to update StreamTitle in your
listeners stream.

Romain
Jeff Garvas
2017-03-22 19:51:11 UTC
Permalink
Romain,

Thank you. This is invaluable information and I didn't think to look at
the source but I would have gotten lost in it, if not more confused. Is
there any reason this exact approach would not work if I've converted these
to .mp3? Some of the audio has a hum on it so I am using the conversion
to mp3 to run a highpass filter.

I'm using the file socket to do a queue.push /path/to/file - I will try this
Post by Jeff Garvas
Post by Jeff Garvas
Post by Romain Beauxis
Post by Jeff Garvas
I'm using liquidsoap for an unconventional use case where I predominantly
stream silence, and inject very short audio files sourced from a
police
Post by Jeff Garvas
Post by Romain Beauxis
Post by Jeff Garvas
scanner.
Well, that certainly is an interesting usage!
It's working quite well. When the application that generates a .mp3
file
Post by Jeff Garvas
writes the file it runs a script I wrote that connects to the socket and
queues the mp3 file. Liquidsoap is pointed to a mount point at
http://broadcastify.com.
Post by Romain Beauxis
Post by Jeff Garvas
Here is the challenge I have -- I want to be able to include a StreamTitle=
in the streaming payload immediately prior to adding a new track to
the
Post by Jeff Garvas
Post by Romain Beauxis
Post by Jeff Garvas
queue. I ran a packet capture on windows based application that supports
alpha tagging and in the payload itself of the mp3 stream there is a
StreamTitle= immediately prior to the begining of a new mp3 audio
source
Post by Jeff Garvas
Post by Romain Beauxis
Post by Jeff Garvas
(when transitioning from silence)
By StreamTitle, I assume that you mean to set the track's metadata, like
artist or title as they are later sent via output.icecast etc.
Yes - but I literally mean StreamTitle. I did a packet capture of
another
Post by Jeff Garvas
application that does this called RadioFeed, where you use an audio
cable to
Post by Jeff Garvas
feed a sound card and a serial cable to get the "alpha tag" of the
channel
Post by Jeff Garvas
from the scanner itself. If you look at the packet capture the alpha
tag of
Post by Jeff Garvas
StreamTitle=PD%20Dispatch (i think the %20 was in there, not 100% sure).
So its a format that uses the phrase StreamTitle. I don't know if this
is a
Post by Jeff Garvas
old meta tag methodology, shoutcast specific, or icecast? It is not
sending
Post by Jeff Garvas
http updates to the server, its in the stream itself.
Let me backtrack here for a second.
Liquidsoap streams have metadata attached to them, potentially at any
position. When a metadata packet is received by output.icecast or
output.shoutcast, it computes the new value for StreamTitle and sends that
to icecast/shoutcast. See here: https://github.com/
savonet/liquidsoap/blob/master/src/outputs/icecast2.ml#L402
In turn, when icecast/shoutcast receives the metadata update call, it
inserts the new metadata into the listeners stream, which is what you refer
to as StreamTitle I think.
[("title","Some text here")] is passed, with nothing else, them your
listeners will see StreamTitle updated to "Some text here".
Thus, your problem becomes simply: how to insert a metadata packet with
only title like above.
If, as you said in another message, your original files are .wav files
annotate:title="StreamTitle content":/path/to/file.wav
And this will trickle down the stream path to update StreamTitle in your
listeners stream.
Romain
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
Romain Beauxis
2017-03-22 20:38:50 UTC
Permalink
Post by Jeff Garvas
Romain,
Thank you. This is invaluable information and I didn't think to look at the
source but I would have gotten lost in it, if not more confused. Is there
any reason this exact approach would not work if I've converted these to
.mp3? Some of the audio has a hum on it so I am using the conversion to
mp3 to run a highpass filter.
No, it would work as well. Make sure you don't have a artist metadata,
though, otherwise StreamTitle will be #{title} - #{artist}

Romain
Jeff Garvas
2017-03-22 20:58:30 UTC
Permalink
Success!

I think I've been over complicating this all along thinking the basic
'title' field wouldn't suffice. I have it streaming to a local test
icecast and the production icecast stream and it is working perfectly with
this syntax:

queue.push annotate:title="Hudson PD1":<path to audio file> (Where
"Hudson PD1" is variably defined)

I am going to see if I can support this strictly out of the ID field alone
later and just convert everything to mp3, but for now this is functional
and I'm blown away.


Now, using Bill's idea above I put this in there in an attempt to display
the word "Scanning" while nothing is going on but with removing the
reference to artist obvious (and it works beautifully):

title = '$(if $(title),"$(title)","...Scanning...")'
stream = rewrite_metadata([("title", title)], stream)

...but because of the way I am generating a silence loop when the queue is
empty it is "updating" the metadata every second and occasionally getting
behind (which was not an issue before I started doing the rewite):

2017/03/22 16:12:50 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:50 [clock.wallclock_main:2] We must catchup 1.10 seconds!
2017/03/22 16:12:50 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:51 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:52 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:53 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:54 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:55 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:56 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:57 [clock.wallclock_main:2] We must catchup 1.37 seconds!
2017/03/22 16:12:57 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:58 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:12:59 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:13:00 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:13:01 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:13:02 [map_metadata_4978:3] Inserting missing metadata.
2017/03/22 16:13:03 [clock.wallclock_main:2] We must catchup 1.24 seconds!

Is there a more proper / efficient way to go about that part? From the
app perspective, it looks great:

Here we are in dead silence with nothing present to play:

[image: Inline image 1]

and when there is audio:

[image: Inline image 2]

Once I get this cleaned up I'm going to add a wiki entry on broadcastify.com
/ radio reference on how to use this.

Jeff
Post by Romain Beauxis
Post by Jeff Garvas
Romain,
Thank you. This is invaluable information and I didn't think to look at
the
Post by Jeff Garvas
source but I would have gotten lost in it, if not more confused. Is
there
Post by Jeff Garvas
any reason this exact approach would not work if I've converted these to
.mp3? Some of the audio has a hum on it so I am using the conversion to
mp3 to run a highpass filter.
No, it would work as well. Make sure you don't have a artist metadata,
though, otherwise StreamTitle will be #{title} - #{artist}
Romain
------------------------------------------------------------
------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, Slashdot.org! http://sdm.link/slashdot
_______________________________________________
Savonet-users mailing list
https://lists.sourceforge.net/lists/listinfo/savonet-users
Loading...