savonet / liquidsoap

Liquidsoap is a statically typed scripting general-purpose language with dedicated operators and backend for all thing media, streaming, file generation, automation, HTTP backend and more.
http://liquidsoap.info
GNU General Public License v2.0
1.4k stars 130 forks source link

Liquidsoap for Icecast AutoDJ doesn't work #1679

Closed Jonikster closed 3 years ago

Jonikster commented 3 years ago

Hello. There is an IceCast server. It works correct. I want to configure AutoDJ on the Linux server to play tracks from the / Home / Music folder. So, I tried Liquidsoap. But it doesn't work. So what did I do? I have Debian 10.9.0.

apt install icecast2

In the .xml file I created MountPoints:

<mount>
 <mount-name>/autodj</mount-name> 
 <password>test123</password> 
 <max-listeners>500</max-listeners> 
 <max-listener-duration>3600</max-listener-duration> 
 <dump-file>/tmp/dump-live.mp3</dump-file> 
 <intro></intro> 
 <charset>ISO8859-1</charset> 
 <public>1</public> 
 <stream-name>TestRadio</stream-name> 
 <stream-description>It's TestRadio!</stream-description> 
 <stream-url>http://ip:8000/autodj.mp3.m3u</stream-url> 
 <genre>Other</genre> 
 <bitrate>128</bitrate> 
 <type>application/mp3</type> 
 <subtype>mp3</subtype> 
 <burst-size>65536</burst-size> 
 <mp3-metadata-interval>4096</mp3-metadata-interval> 
</mount> 
<mount> 
 <mount-name>/live</mount-name> 
 <password>test123</password> 
 <max-listeners>500</max-listeners> 
 <max-listener-duration>3600</max-listener-duration> 
 <dump-file>/tmp/dump-live.mp3</dump-file> 
 <intro></intro> 
 <fallback-mount>/autodj</fallback-mount> 
 <fallback-override>1</fallback-override> 
 <fallback-when-full>1</fallback-when-full> 
 <charset>ISO8859-1</charset> 
 <public>1</public> 
 <stream-name>TestRadio</stream-name> 
 <stream-description>It's TestRadio!</stream-description> 
 <stream-url>http://ip:8000/live.mp3.m3u</stream-url> 
 <genre>Other</genre> 
 <bitrate>128</bitrate> 
 <type>application/mp3</type> 
 <subtype>mp3</subtype> 
 <burst-size>65536</burst-size> 
 <mp3-metadata-interval>4096</mp3-metadata-interval> 
</mount>

I used different ways to install Liquidsoap. With apt install Liquidsoap, opam and deb package. It didn't run, so I used the template: https://github.com/Renaud11232/icecast-autodj

git clone https://github.com/Renaud11232/icecast-autodj.git
cd icecast-autodj
mkdir -p /etc/liquidsoap
cp configs/dj.liq /etc/liquidsoap
chown -R icecast2:icecast /etc/liquidsoap
chmod 660 /etc/liquidsoap/dj.liq
cp systemd/liquidsoap.service /etc/systemd/system/
systemctl daemon-reload
systemctl enable icecast2
systemctl enable liquidsoap
systemctl start icecast2
systemctl start liquidsoap

dj.liq:

#!/usr/bin/liquidsoap -d
#set("init.daemon",true)
#set("init.daemon.pidfile",false)
set("log.file",false)
#set("log.file.path","/var/log/liquidsoap/basic.log")
#set("log.stdout",true)
#set("log.level",4)
set("decoder.file_decoders",["META","MAD","OGG"])
set("decoder.file_extensions.mad",["mp3","mp2","mp1"])
set("decoder.file_extensions.ogg",["ogv","oga","ogx","ogg","opus"])
set("decoder.mime_types.ogg",["application/ogg","application/x-ogg","audio/x-ogg","audio/ogg","video/ogg"])
set("decoder.mime_types.mp3",["audio/mpeg","audio/MPA"])
def update_title(m) =
 title = m["title"]
 if title == "" or title == "Unknown" then
  content = m["filename"]
  content = basename(content)
  content = get_process_output("STR=\""^content^"\"; echo ${STR%.*}")
  content = string.recode(out_enc="UTF-8", content)
  [("title", content)]
 else
  sArtist = string.recode(out_enc="UTF-8", m["artist"])
  sTitle = string.recode(out_enc="UTF-8", m["title"])
  [("title", sTitle),
  ("artist", sArtist)]
 end
end
set("tag.encodings",["UTF-8"])
music = nrj(playlist(mode='randomize', reload_mode='rounds=1', '/home/music'))
mount = "autodj",
encoding = "ISO-8859-1",
default,
host = "ip", port = 8000, password = "test123",
genre="other",
name="TestRadio",
fallible = true,
icy_metadata="true",
public=true,
url="http://ip",
description="It's TestRadio!")

But, after executing systemctl start, I open http://ip:8000/autodj, and it doesn't work. What's wrong? Please help me! Thank you in advance!

jonathanstowe commented 3 years ago

Is there any chance you could format the code and xml parts of your post by editing them, selecting the appropriate parts and using the <> (code) formatter in the editor toolbar, it's almost impossible to read as it is at the moment.

jonathanstowe commented 3 years ago

Also, while testing a new script it might be better to add

set("log.file", false)
set("log.stdout", true)

To the top of the script and then run liquidsoap in the foreground like:

liquidsoap script.liq

rather than as a daemon so you can see if there are any problems with your script.

jonathanstowe commented 3 years ago

Hi, there were a couple of problems with the script: firstly the basename at line 17 should be path.basename and secondly it appears to omit part of the output.icecast call at around line 30. If adjusted as:

#!/usr/bin/liquidsoap -d
#set("init.daemon",true)
#set("init.daemon.pidfile",false)
set("log.file",false)
#set("log.file.path","/var/log/liquidsoap/basic.log")
set("log.stdout",true)
set("log.level",4)
set("decoder.file_decoders",["META","MAD","OGG"])
set("decoder.file_extensions.mad",["mp3","mp2","mp1"])
set("decoder.file_extensions.ogg",["ogv","oga","ogx","ogg","opus"])
set("decoder.mime_types.ogg",["application/ogg","application/x-ogg","audio/x-ogg","audio/ogg","video/ogg"])
set("decoder.mime_types.mp3",["audio/mpeg","audio/MPA"])
def update_title(m) =
 title = m["title"]
 if title == "" or title == "Unknown" then
  content = m["filename"]
  content = path.basename(content)
  content = get_process_output("STR=\""^content^"\"; echo ${STR%.*}")
  content = string.recode(out_enc="UTF-8", content)
  [("title", content)]
 else
  sArtist = string.recode(out_enc="UTF-8", m["artist"])
  sTitle = string.recode(out_enc="UTF-8", m["title"])
  [("title", sTitle),
  ("artist", sArtist)]
 end
end
set("tag.encodings",["UTF-8"])
music = nrj(playlist(mode='randomize', reload_mode='rounds=1', '/home/jonathan/Music'))
output.icecast(
  %mp3(
    bitrate=160
  ),
mount = "autodj",
encoding = "ISO-8859-1",
music,
host = "127.0.0.1", port = 8000, password = "hackme",
genre="other",
name="TestRadio",
fallible = true,
icy_metadata="true",
public=true,
url="http://localhost",
description="It's TestRadio!")

(host, password and playlist path being adjusted as per my local setup.)

And that all works fine:

[jonathan@menenius Audio-Liquidsoap]$ liquidsoap jj.liq
2021/06/09 07:50:19 >>> LOG START
2021/06/09 07:50:19 [main:3] Liquidsoap 1.4.4
2021/06/09 07:50:19 [main:3] Using: bytes=[distributed with OCaml 4.02 or above] pcre=7.4.6 sedlex=2.2 menhirLib=20210419 dtools=0.4.2 duppy=0.9.0 cry=0.6.5 mm=0.5.1 ogg=0.5.2 vorbis=0.7.1 opus=0.1.3 mad=0.4.5 flac=0.1.7 flac.ogg=0.1.7 dynlink=[distributed with Ocaml] lame=0.3.4 fdkaac=0.3.2 gavl=0.1.6 bjack=0.1.6 samplerate=0.1.5 taglib=0.3.6 camomile=1.0.2
2021/06/09 07:50:19 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz master.
2021/06/09 07:50:19 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples.
2021/06/09 07:50:19 [frame:3] Targetting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks.
2021/06/09 07:50:19 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks.
2021/06/09 07:50:19 [sandbox:3] Sandboxing disabled
2021/06/09 07:50:19 [video.converter:3] Using preferred video converter: gavl.
2021/06/09 07:50:19 [audio.converter:3] Using samplerate converter: libsamplerate.
2021/06/09 07:50:19 [threads:4] Created thread "generic queue #1" (1 total).
2021/06/09 07:50:19 [threads:4] Created thread "generic queue #2" (2 total).
2021/06/09 07:50:19 [threads:4] Created thread "non-blocking queue #1" (3 total).
2021/06/09 07:50:19 [threads:4] Created thread "non-blocking queue #2" (4 total).
2021/06/09 07:50:19 [clock:4] Currently 1 clocks allocated.
2021/06/09 07:50:19 [clock.wallclock_main:4] Starting 1 sources...
2021/06/09 07:50:19 [source:4] Source output.icecast_7393 gets up.
2021/06/09 07:50:19 [source:4] Source compress_7390 gets up.
2021/06/09 07:50:19 [compress_7390:4] Content kind is {audio=2;video=0;midi=0}.
2021/06/09 07:50:19 [source:4] Source normalize_7389 gets up.
2021/06/09 07:50:19 [normalize_7389:4] Content kind is {audio=2;video=0;midi=0}.
2021/06/09 07:50:19 [source:4] Source playlist_7388 gets up.
2021/06/09 07:50:19 [Music:3] Loading playlist...
2021/06/09 07:50:19 [Music:3] Playlist is a directory.
2021/06/09 07:50:19 [Music:3] Successfully loaded a playlist of 4031 tracks.
2021/06/09 07:50:19 [Music:4] Content kind is {audio=2;video=0;midi=0}.
2021/06/09 07:50:19 [Music:4] Activations changed: static=[normalize_7389:compress_7390:TestRadio:TestRadio], dynamic=[].
2021/06/09 07:50:19 [normalize_7389:4] Activations changed: static=[compress_7390:TestRadio:TestRadio], dynamic=[].
2021/06/09 07:50:19 [compress_7390:4] Activations changed: static=[TestRadio:TestRadio], dynamic=[].
2021/06/09 07:50:19 [TestRadio:4] Activations changed: static=[TestRadio], dynamic=[].
2021/06/09 07:50:19 [TestRadio:4] Enabling caching mode: active source.
2021/06/09 07:50:19 [threads:4] Created thread "wallclock_main" (1 total).
2021/06/09 07:50:19 [clock:4] Main phase starts.
2021/06/09 07:50:19 [clock.wallclock_main:3] Streaming loop starts, synchronized with wallclock.
2021/06/09 07:50:19 [decoder:4] Trying method "META" for "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3"...
2021/06/09 07:50:19 [decoder:4] Trying method "MAD" for "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3"...
2021/06/09 07:50:19 [decoder.mad:4] Libmad recognizes "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3" as mpeg audio (layer III, 320kbps, 44100Hz, 2 channels).
2021/06/09 07:50:19 [decoder:3] Method "MAD" accepted "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3".
2021/06/09 07:50:19 [metadata.flac:4] Invalid file extension for "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3"!
2021/06/09 07:50:19 [decoder.ogg:4] Invalid file extension for "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3"!
2021/06/09 07:50:19 [Music:4] Remaining: 0.0s, queued: 0.0s, adding: 30.0s (RID 1)
2021/06/09 07:50:19 [decoder:4] Trying method "META" for "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3"...
2021/06/09 07:50:19 [decoder:4] Trying method "MAD" for "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3"...
2021/06/09 07:50:19 [decoder.mad:4] Libmad recognizes "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3" as mpeg audio (layer III, 320kbps, 44100Hz, 2 channels).
2021/06/09 07:50:19 [decoder:3] Method "MAD" accepted "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3".
2021/06/09 07:50:19 [metadata.flac:4] Invalid file extension for "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3"!
2021/06/09 07:50:19 [decoder.ogg:4] Invalid file extension for "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3"!
2021/06/09 07:50:19 [Music:4] Remaining: 0.0s, queued: 30.0s, adding: 30.0s (RID 2)
2021/06/09 07:50:19 [Music:4] Remaining: 0.0s, queued: 60.0s, taking: 30.0s
2021/06/09 07:50:19 [Music:3] Prepared "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3" (RID 1).
2021/06/09 07:50:19 [TestRadio:3] Connecting mount autodj for source@127.0.0.1...
2021/06/09 07:50:19 [TestRadio:3] Connection setup was successful.
2021/06/09 07:55:47 [decoder:4] Trying method "META" for "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3"...
2021/06/09 07:55:47 [decoder:4] Trying method "MAD" for "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3"...
2021/06/09 07:55:47 [decoder.mad:4] Libmad recognizes "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3" as mpeg audio (layer III, 320kbps, 44100Hz, 2 channels).
2021/06/09 07:55:47 [decoder:3] Method "MAD" accepted "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3".
2021/06/09 07:55:47 [metadata.flac:4] Invalid file extension for "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3"!
2021/06/09 07:55:47 [decoder.ogg:4] Invalid file extension for "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3"!
2021/06/09 07:55:47 [Music:4] Remaining: 9.8s, queued: 30.0s, adding: 30.0s (RID 3)
2021/06/09 07:55:57 [decoder:4] Decoding "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3" ended: Mad.End_of_stream.
2021/06/09 07:55:57 [Music:4] Finished with "/home/jonathan/Music/Rikardo/Dark Pressure/02 - Dark Pressure (Farrel 8 Remix).mp3".
2021/06/09 07:55:57 [Music:4] Remaining: 0.0s, queued: 60.0s, taking: 30.0s
2021/06/09 07:55:57 [Music:3] Prepared "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3" (RID 2).
2021/06/09 08:02:23 [decoder:4] Trying method "META" for "/home/jonathan/Music/Jagat Skad/Everybody Knows We're Thieves/03 - Oh, Weekends.b-mtp-687"...
2021/06/09 08:02:23 [decoder:4] Trying method "MAD" for "/home/jonathan/Music/Jagat Skad/Everybody Knows We're Thieves/03 - Oh, Weekends.b-mtp-687"...
2021/06/09 08:02:23 [decoder.mad:4] Invalid file extension for "/home/jonathan/Music/Jagat Skad/Everybody Knows We're Thieves/03 - Oh, Weekends.b-mtp-687"!
2021/06/09 08:02:23 [decoder:4] Trying method "OGG" for "/home/jonathan/Music/Jagat Skad/Everybody Knows We're Thieves/03 - Oh, Weekends.b-mtp-687"...
2021/06/09 08:02:23 [decoder.ogg:4] Invalid file extension for "/home/jonathan/Music/Jagat Skad/Everybody Knows We're Thieves/03 - Oh, Weekends.b-mtp-687"!
2021/06/09 08:02:23 [decoder:3] Unable to decode "/home/jonathan/Music/Jagat Skad/Everybody Knows We're Thieves/03 - Oh, Weekends.b-mtp-687" as {audio=2;video=0;midi=0}!
2021/06/09 08:02:23 [decoder:4] Trying method "META" for "/home/jonathan/Music/Inigo Kennedy/Chords Depend (ASYMP3006)/03 - Insomnia Spins"...
2021/06/09 08:02:23 [decoder:4] Trying method "MAD" for "/home/jonathan/Music/Inigo Kennedy/Chords Depend (ASYMP3006)/03 - Insomnia Spins"...
2021/06/09 08:02:23 [decoder.mad:4] Invalid file extension for "/home/jonathan/Music/Inigo Kennedy/Chords Depend (ASYMP3006)/03 - Insomnia Spins"!
2021/06/09 08:02:23 [decoder:4] Trying method "OGG" for "/home/jonathan/Music/Inigo Kennedy/Chords Depend (ASYMP3006)/03 - Insomnia Spins"...
2021/06/09 08:02:23 [decoder.ogg:4] Invalid file extension for "/home/jonathan/Music/Inigo Kennedy/Chords Depend (ASYMP3006)/03 - Insomnia Spins"!
2021/06/09 08:02:23 [decoder:3] Unable to decode "/home/jonathan/Music/Inigo Kennedy/Chords Depend (ASYMP3006)/03 - Insomnia Spins" as {audio=2;video=0;midi=0}!
2021/06/09 08:02:23 [decoder:4] Trying method "META" for "/home/jonathan/Music/mp3/various_artists/trunk_records__now_we_are_ten/tiffany_glass__orriel_smith.mp3"...
2021/06/09 08:02:23 [decoder:4] Trying method "MAD" for "/home/jonathan/Music/mp3/various_artists/trunk_records__now_we_are_ten/tiffany_glass__orriel_smith.mp3"...
2021/06/09 08:02:23 [decoder.mad:4] Libmad recognizes "/home/jonathan/Music/mp3/various_artists/trunk_records__now_we_are_ten/tiffany_glass__orriel_smith.mp3" as mpeg audio (layer III, 128kbps, 44100Hz, 2 channels).
2021/06/09 08:02:23 [decoder:3] Method "MAD" accepted "/home/jonathan/Music/mp3/various_artists/trunk_records__now_we_are_ten/tiffany_glass__orriel_smith.mp3".
2021/06/09 08:02:23 [metadata.flac:4] Invalid file extension for "/home/jonathan/Music/mp3/various_artists/trunk_records__now_we_are_ten/tiffany_glass__orriel_smith.mp3"!
2021/06/09 08:02:23 [decoder.ogg:4] Invalid file extension for "/home/jonathan/Music/mp3/various_artists/trunk_records__now_we_are_ten/tiffany_glass__orriel_smith.mp3"!
2021/06/09 08:02:23 [Music:4] Remaining: 9.9s, queued: 30.0s, adding: 30.0s (RID 5)
2021/06/09 08:02:33 [decoder:4] Decoding "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3" ended: Mad.End_of_stream.
2021/06/09 08:02:33 [Music:4] Finished with "/home/jonathan/Music/Inigo Kennedy/Spectre - Wonderhorse/02 - Wonderhorse (Original Mix).mp3".
2021/06/09 08:02:33 [Music:4] Remaining: 0.0s, queued: 60.0s, taking: 30.0s
2021/06/09 08:02:33 [Music:3] Prepared "/home/jonathan/Music/Trolley Route/Form Factor EP/02 - Neutron (Original Mix).mp3" (RID 3).

And plays fine:

[jonathan@menenius xt]$ mplayer http://127.0.0.1:8000/autodj
MPlayer 1.4-10 (C) 2000-2019 MPlayer Team
do_connect: could not connect to socket
connect: No such file or directory
Failed to open LIRC support. You will not be able to use your remote control.

Playing http://127.0.0.1:8000/autodj.
Resolving 127.0.0.1 for AF_INET6...

Couldn't resolve name for AF_INET6: 127.0.0.1
Connecting to server 127.0.0.1[127.0.0.1]: 8000...

Name   : TestRadio
Genre  : other
Website: http://localhost
Public : yes
Bitrate: 160kbit/s
Cache size set to 320 KBytes
Cache fill:  0.00% (0 bytes)   
ICY Info: StreamTitle='Trolley Route - Neutron (Original Mix)';

...

I can't recommend running the script in the foreground with logging to stdout turned on before attempting to run as a daemon with no logging enough, it would show exactly where the problems are.