Hi everybody,
Good news for the end of year: liquidsoap is getting quite stable, we'll
make a release at the beginning of next year ! The criterion was at
least 7 days of uptime for a full-featured radio which is running at the
ENS Lyon. It's been running for 9 days and 20 hours. More details below.
First, a short status report for the many sub-projects.
1) Liquidsoap: bugs corrected, features added, quite stable.
2) LibSavonet should be working, but has not been tested widely, and is
not supported by the components of the project. One day we may work at
this integration.
3) Strider, in charge of indexing a large & distributed amount of audio
files, was mostly rewritten by a new team of developers. It's not yet
stable, and doesn't communicate with liquidsoap using libsavonet. If
fills the database and the IRC bot or the website reads it, then sends
an URI to the radio.
4) Soapdish (the website) and Botanick (the IRC/... bot), are
unmaintained. We do have a website and a wonderful bot, but they are
written in Perl, using the telnet interface of liquidsoap. The telnet
source is supposed to be replaced by a libsavonet interface. So Perl
modules & scripts won't be published officially. Anyway they're dirty.
5) Libs: ocaml-ftp, ocaml-fetch and ocaml-dtools are wonderful. At
least, they behave well in liquidsoap.
6) OCaml bindings: the team has made many libs available for ocaml:
ocaml-ssl, vorbis, mad, mp3id3, smbclient. Fatal bugs in vorbis were
corrected recently, thanks to mfurr. Binding is really a critical task.
Unfortunately, ocaml-ssl is not being tested in liquidsoap. Vorbis and
Mp3id3 got some corrections about file descriptors left open, which made
liquidsoap consume so much of them. Mp3Id3 and fetch were rewritten
using a nice plugin system.
Now, a short story of geek radio and its bugs. Geek radio is the
webradio running at the ENS Lyon. It's script is the most complicated we
thought about, featuring mostly eveyrything. I attached it. Since the
0.1.1 demonstration at school, liquidsoap progessed a lot. The first
important step was a correction in ocaml-mad, which made the sound
crappy. After that, I was able to really work on liquidsoap problems,
and there were a lot of them. Apart from cleaning and adding more (nicer
timestamps) or less (vorbis metadata) minor features, the development
consisted in two phases. First phase: the radio died 'cleanly', for a
scheduler death for example, or an exception. This was not so hard to
correct, except for the telnet source, which caused signals to be sent,
that we didn't suspected for a long time. Then, we had a cleanly running
radio, which however crashed every two days... We made the radio nicer
and nicer, worked a bit, but could not find out the bug. Recently, mfurr
told us about an odd function in vorbis bindings, which was indeed
guilty of segmentation faults. A second bug was a race condition in the
output loop, which I corrected without noticing at first. It's been a
long way!
There probably remain one bug. Sometimes, it seems that a thread is not
scheduled for more than 30s, which is fatal for the radio. We saw it a
few times, crashing the radio after 4 or 5 days. We don't understand it.
Anyway, it seems that liquidsoap is quite stable. Moreover, even if
this bug remains, it is possibly linked with the fact that the radio is
running on a bi-proc machine.
What's the point of this long mail ? Not much ;)
First, I want to thank the whole team for having worked on savonet.
Also, even if it's a bit early, I expect some people to read liquidsoap
doc and maybe try to run the anonymous CVS version. Less than four guys
in the world understand .liq files! I wrote a short tutorial, I hope
it's enough for most of the geeks to understand. If you've got little
time left, please try. You can do a very good radio with liquidsoap!
Happy new year, long life to techno music and our bot bimbo !
--
David, for Savonet
#!/usr/local/bin/liquidsoap
set outputs = [ "geek.ogg" ; "geek.modem.ogg" ]
set log.level.geek.ogg = 5
set log.level.root = 5
set daemon = true
set geek.ogg.type = "icecast2"
set geek.ogg.host = "sparc8"
set geek.ogg.bitrate = 128
set geek.ogg.multicast_ip = "239.255.0.1"
set geek.modem.ogg.type = "icecast2_fork"
set geek.modem.ogg.host = "sparc8"
set geek.modem.ogg.bitrate = 64
set geek.modem.ogg.multicast_ip = "239.255.0.2"
let req = say_metadatas (telnet) in
let on_fail =
one_file
"/home/dbaelde/ogg/default.ogg"
in
let def = playlist
~reload_mode:"seconds" ~reload:3600
"/home/dbaelde/playlist.local" in
let ftp = playlist
~reload_mode:"seconds" ~reload:3600
"/home/dbaelde/playlist" in
let techno = playlist
~reload_mode:"seconds" ~reload:3600
"/home/dbaelde/playlist.techno" in
let smb = playlist
~reload_mode:"seconds" ~reload:3600
"smb://footwar/mp3/playlist" in
let bla = playlist
~reload_mode:"seconds" ~reload:3600
"/home/dbaelde/playlist.say" in
let bla = change_volume 1.2 bla in
let beep = sine 880 in
add_w [
# A "beep beep" around 0 minutes
((date_switch [("59m & 58s", beep);("0m & 0s", beep)]),3) ;
# Playlists.
((random_w [
# About 1 jingle for 8 songs
(bla,1) ;
((fallback [
# User requests first,
# with pronunciation of the title/artist at the end
req ;
# techno makes developers work faster!
(date_switch [("0-1h", techno)]) ;
# 50% of crap music (ftp)
(date_switch [("22h", (random [smb;ftp]))]) ;
# Default (remote) playlist
smb ;
# Un-checked local files, in case download fails
def ;
# Checked local file, in case there is a ill-encoded local file
on_fail
]),8)
]),1)
]