LiquidSoap

Anyone have experience with LiquidSoap for broadcasting video?

I’m poking around trying to figure out how to establish an always-on MTV like FediTV for music videos.

I tried ffmpeg and that worked up to a limit – it has a documented but unimplemented feature (say what?) for pulling metadata out of video files and getting them onscreen (artist, track, album). It also doesn’t handle failures all that well for 24x7 broadcasting. Maybe it could with some magic but…

That is what LiquidSoap was designed for.

With LiquidSoap you could setup a constant stream that pulls from a randomized playlist of videos and

  • inject periodic station identification
  • supersede regular broadcast to allow for live events
  • fallback to known good video when something breaks (no dead air)
  • transcode on-the-fly

But still struggling to pull metadata out of the videos and get it onscreen - which is deal breaker - this is about artist promotion as far as I am concerned. I worry this is down to the same missing feature in ffmpeg (since it uses ffmpeg internally).

(p.s. one interesting side effect could be… syndication… or something like it. I’ve noticed that there are many owncasts that go unused most of the time… i believe you could set this up to syndicate the stream to all of them and then allow any of them to pick up a live stream on demand - talking about gravitons, tibr, labr, basspistol, being able to opt-in to syndication but that is for another day)

Anyway, does anyone have experience setting up LiquidSoap and getting metadata onscreen?

Complete examples are hard to find… and I declare, functional programming is not my strong suit. See what I did there?

2 Likes

BTW, here is a LiquidSoap script that will stream a folder of videos to an owncast server inserting a random station break every 4th video:

settings.frame.video.width := 1280
settings.frame.video.height := 720

m = medialib(persistency=“videos.json”, “/media/videos/”)
l = m.find(artist_contains=“”)
l = list.shuffle(l)

m2 = medialib(persistency=“jingles.json”, “/media/jingles/”)
l2 = m.find(artist_contains=“”)
l2 = list.shuffle(l2)

s = random( weights=[1,4], [ playlist.list(l2), playlist.list(l) ] )

encoder = %ffmpeg(
format=“flv”,
%video.raw(codec=“libx264”, “x264-params”=“keyint=60:min-keyint=60:scenecut=0:tune=zerolatency”, hwaccel=“auto”, pixel_format=“yuv420p”, b=“2500k”, preset=“veryfast”, r=25, g=50),
%audio( codec=“aac”, b=“128k”, samplerate=48000 ),
)

output.url(fallible=true,url=“rtmp://THE_OWNCAST_URL/live/THE_STREAMING_KEY”,encoder,s)

LiquidSoap also supports, formally, time predicates. So you could establish programming slots for different types of music. Headbangers ball 1800-2000, 120 minutes ahem weird music 2000-2200, ambient 2200-0600, etc. Does it all work? I dunno…

2 Likes

That’s brilliant! Fedi MTV has to happen! I was thinking also of some of us organising hosted programs for music videos, like livestream shows.

Haven’t used LiquidSoap before, sorry I’m no use here really :see_no_evil_monkey: Interested in having a poke around it though…

1 Like

helpful videos (sort of, discussing capabilities) here: Liquidsoap 3rd one in particular FOSDEM 2020 presentation gives a nice overview of what it can do and why it was made

2 Likes

I got the text overlay sorted, mostly.

still need to figure out how to pull album art from .mp4 as well as artist support URL to feed into the qr code onscreen… but it is closer now

3 Likes

FWIW – here’s the .liq script I came up with. roku/indiebeattv at main · limebar/roku · GitHub in case anyone is interested. LiquidSoap seems very robust even on my testing in Windows.

1 Like

I’m building the same thing right now with Subjam TV! Just this morning I got the “Draw Text” filter in ffmpeg working (see Jordan: "Learning how to use the "Draw Text" filter on ffm…" - DEF CON Social heh). Very crazy I run into this post now.

I use liquidsoap for the beta 24x7 Subjam radio. I’ve used it for various projects for many years, but basically set it up once and it just runs. Doing it with video and streaming to Owncast is exactly what I’m looking for.

I’ll be looking more deeply into this in the upcoming weeks, thanks for posting your findings and the scripts. I’ll keep this post updated with what I come up with too! Also, eventually I’d love to federate Subjam (however that may look) so maybe some syndication is in order for that :slight_smile:

6 Likes

very cool!
a couple of odds and ends on LiquidSoap

here’s a link with info on running as a daemon (so you get autostart and restart if ever needed) but also mentions running using nohup on the easier side (because honestly it seems very robust)… search “daemon” in this link: Creating a 24/7 “Lofi Like” stream part 2: Adding Features | Liquidsoap – Mikulski

The script I made allows you to seemlessly interrupt regular bcast for live events… which is so awesome I can’t believe it … but I was a little surprised to learn that rtmp is sort of very insecure out of the box. most owncast and peertube examples I’ve seen have the stream key in clear text… see this for some ideas on how to “fix” although… i dunno, seems heavy to me: The rtmp server and security, any way to specify a streaming key? · savonet/liquidsoap · Discussion #4607 · GitHub

anyway I left it in because… apparently everyone is doing this with an unsecure impl all the time anyway, but there must be a solution that works easily with like OBS

also, you’ll see my script is using the built-in text overlay which uses a crude 8bit-like font which i quite like but might be too crude for some scenarios (I noticed your screenshot has tiny text so a better font is needed) – anyway there are ways to get LiquidSoap to use proper fonts but I think it requires builds with proper SDL or FFMPEG integration for text – Liquidsoap see add_text.ffmpeg and add_text.sdl

the script I made is just randomly picking up files from folders (and watching for changes so you can dump in new stuff and it’ll see it). but you can use static playlists in various formats as well if you want a specific play order: Liquidsoap

finally I found this “bug?” on windows that might not be an issue on Linux… related to watch and recursion … easy to work around just drop a file in the root and then remove it after the playlists reload… Playlist recursion and reload_mode="watch" issue? · savonet/liquidsoap · Discussion #4606 · GitHub

1 Like

updated the liquidsoap script to output nowplaying.json whenever the track changes
ignore(file.write(data=“{"song":{"link":"#{current_www()}","artist":"#{current_artist()}","title":"#{current_title()}","album":"#{current_album()}"}}”, append=false, “nowplaying.json”))

will update git soon after testing a bit longer

looks like:
{“song”:{“link”:“https://limebar.bandcamp.com”,“artist”:“Lime Bar”,“title”:“Lime Bar Vs Fugue State Audio #1”,“album”:“Lime Bar Vs Fugue State Audio”}}

1 Like

hey, just a reminder that you can put your code into a special “code box” that’s much easier to read through and copy, by putting it inbetween two series of three accents like these ```.

It will appear like so. I think it even colours th syntax if it recognizes it.

Or just select your text and click on this icon in the text editor:
image