Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 42 additions & 23 deletions liquidsoap/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
FROM archlinux
# FROM archlinux
#
# RUN pacman -Sy --noconfirm archlinux-keyring
#
# RUN pacman-key --init
# RUN pacman-key --populate archlinux
# RUN yes | pacman -Syu --noconfirm opam make m4 gcc patch diffutils gavl ffmpeg git automake autoconf pkg-config which taglib sudo glibc jq libffi pcre libmad
#

RUN pacman -Sy --noconfirm archlinux-keyring
FROM savonet/liquidsoap:v2.4.x-latest
#RUN useradd liquidsoap && mkdir /home/liquidsoap && chown -R liquidsoap /home/liquidsoap
#RUN usermod -aG wheel liquidsoap
# RUN echo "Defaults !requiretty" >> /etc/sudoers
# RUN echo "%wheel ALL=NOPASSWD: ALL" >> /etc/sudoers

RUN pacman-key --init
RUN pacman-key --populate archlinux
RUN yes | pacman -Syu --noconfirm opam make m4 gcc patch diffutils ffmpeg git automake autoconf pkg-config which taglib sudo glibc jq libffi pcre libmad
ENV HOME=/home/liquidsoap

RUN useradd liquidsoap && mkdir /home/liquidsoap && chown -R liquidsoap /home/liquidsoap
RUN usermod -aG wheel liquidsoap
RUN echo "Defaults !requiretty" >> /etc/sudoers
RUN echo "%wheel ALL=NOPASSWD: ALL" >> /etc/sudoers
USER root

ENV HOME=/home/liquidsoap
RUN apt-get update
RUN apt-get install -y --no-install-recommends curl jq

USER liquidsoap

RUN opam init --disable-sandboxing --yes
# RUN opam init --disable-sandboxing --yes

WORKDIR /home/liquidsoap

Expand All @@ -26,17 +32,17 @@ WORKDIR /home/liquidsoap
# RUN echo "%sudo ALL=NOPASSWD: ALL" >> /etc/sudoers
#RUN echo 'eval "$(opam config env)"' >> /home/liquidsoap/.bashrc

RUN sudo touch /var/log/liquidsoap.log
RUN sudo chown liquidsoap:users /var/log/liquidsoap.log

RUN opam switch create 4.14.2
RUN opam update
RUN touch /var/log/liquidsoap.log
RUN chown liquidsoap:users /var/log/liquidsoap.log

# RUN opam switch create 4.14.2
# RUN opam update
#
# depext no longer required to install, integrated with opam
# RUN opam install depext -y
# RUN opam depext taglib mad lame ogg vorbis cry samplerate liquidsoap -y
# RUN opam install taglib mad lame ogg vorbis cry samplerate ocurl liquidsoap -y
RUN opam install ctypes-foreign metadata mad lame ogg vorbis cry samplerate ocurl liquidsoap -y
#RUN opam install ctypes-foreign metadata mad lame ogg vorbis cry samplerate ocurl gavl ffmpeg liquidsoap -y

# RUN for i in ocaml-gavl ocaml-ffmpeg ocaml-dtools ocaml-duppy ocaml-mm ocaml-cry ocaml-taglib ocaml-lame ocaml-mad ocaml-ogg ocaml-vorbis ocaml-samplerate; do \
# cd /home/liquidsoap && git clone https://github.com/savonet/$i && cd $i && opam pin add --yes --no-action .; \
Expand All @@ -45,23 +51,36 @@ RUN opam install ctypes-foreign metadata mad lame ogg vorbis cry samplerate ocur
#RUN cd /home/liquidsoap && git clone https://github.com/savonet/liquidsoap && cd liquidsoap && opam pin add --yes --no-action .
# RUN opam install --yes liquidsoap ffmpeg cry taglib lame mad ogg vorbis samplerate
#
RUN eval $(opam env) && liquidsoap --version

# RUN eval $(opam env) && liquidsoap --version
#
RUN mkdir /home/liquidsoap/radio
ADD ./ /home/liquidsoap/radio/

RUN sudo chown -R liquidsoap:liquidsoap /home/liquidsoap/radio/
#RUN chown -R liquidsoap:liquidsoap /home/liquidsoap/radio/
RUN chmod +x /home/liquidsoap/radio/libStereoTool_64.so

RUN mkdir /home/liquidsoap/tracks
RUN chown liquidsoap:liquidsoap /home/liquidsoap/tracks
RUN mkdir /home/liquidsoap/recordings
RUN chown liquidsoap:liquidsoap /home/liquidsoap/recordings

RUN mkdir /home/liquidsoap/hls
RUN chown liquidsoap:liquidsoap /home/liquidsoap/hls

RUN chown -R liquidsoap:liquidsoap /home/liquidsoap/

WORKDIR /home/liquidsoap/radio
RUN eval $(opam env) && liquidsoap --check radio.liq
# RUN eval $(opam env) && liquidsoap --check radio.liq
RUN liquidsoap --check radio.liq
# RUN chown 1000:1000 /home/liquidsoap/tracks
# RUN chown 1000:1000 /home/liquidsoap/recordings
#RUN chown liquidsoap:liquidsoap /home/liquidsoap/tracks
#RUN chown liquidsoap:liquidsoap /home/liquidsoap/recordings

USER liquidsoap

EXPOSE 9000
CMD ["/bin/bash", "-c", "eval `opam config env`; liquidsoap radio.liq"]
EXPOSE 9001
EXPOSE 1936
# CMD ["/bin/bash", "-c", "eval `opam config env`; liquidsoap radio.liq"]
CMD ["liquidsoap", "radio.liq"]
4 changes: 2 additions & 2 deletions liquidsoap/PACKAGES
Original file line number Diff line number Diff line change
Expand Up @@ -117,11 +117,11 @@ ocaml-flac
# is very efficient and has a quality setting for
# tweaking load vs. quality of the conversion.
# It is the recommended module to use with video
# ocaml-gavl
ocaml-gavl

# FFMPEG is currently only used to convert from
# and to many formats.
# ocaml-ffmpeg
ocaml-ffmpeg

# Frei0r is a minimalistic plugin API for video sources and filters.
# ocaml-frei0r
Expand Down
60 changes: 54 additions & 6 deletions liquidsoap/radio.liq
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set("request.deprecated_on_air_metadata", true)

#set("server.telnet",true)
set("server.socket",true)
# set("server.socket.path","/tmp/datafruits/liquidsoap.sock")
set("server.socket.path","/home/liquidsoap/tracks/liquidsoap.sock")

set("harbor.bind_addrs",["0.0.0.0"])
Expand Down Expand Up @@ -43,6 +44,7 @@ stop_dump_f = ref (fun () -> ())

# live_dj = ref empty()
live_dj = ref(source.fail())
# rtmp_relay = ref(source.fail())
# fallback_ref = ref(fallback([source.fail()]))

def icy_update(v) =
Expand Down Expand Up @@ -85,7 +87,7 @@ def dj_dummy_stopped() =
f()
end

def get_user(user,password) =
def get_user(user, password) =
if user == "source" then
x = string.split(separator=';',password)
list.nth(x,0,default="")
Expand All @@ -94,7 +96,7 @@ def get_user(user,password) =
end
end

def get_password(user,password) =
def get_password(user, password) =
if user == "source" then
x = string.split(separator=';',password)
list.nth(x,1,default="")
Expand All @@ -104,10 +106,10 @@ def get_password(user,password) =
end

#auth function
def dj_auth(params) =
def dj_auth(req) =
log("dj auth")
u = get_user(params.user,params.password)
p = get_password(params.user,params.password)
u = get_user(req.user, req.password)
p = get_password(req.user, req.password)
ret = process.read.lines("./dj_auth.sh '#{u}' '#{p}' '#{radio_name}'")
#ret has now the value of the live client (dj1,dj2, or djx), or "ERROR"/"unknown"
ret = list.hd(default="",ret)
Expand Down Expand Up @@ -226,6 +228,18 @@ end
# buffer breaks fallback?
live_dj := stereo(input.harbor("#{radio_name}",id="live_dj",port=9000,auth=dj_auth,on_connect=on_connect,on_disconnect=on_disconnect,logfile="/tmp/liquidsoap_harbor.log",buffer=15.0,max=40.0))

# this source doesn't need on_connect handler, all recording/metadata is handled elsewhere
# disconnect handler to clear metadata is necessary though
# rtmp_relay := stereo(input.harbor("#{radio_name}_rtmp",id="rtmp_relay",port=9001,logfile="/tmp/liquidsoap_rtmp_relay_harbor.log",user="rtmp_source",password="pricemaster9876",on_disconnect=on_disconnect,buffer=15.0,max=40.0))

# ingest rtmp from viz server

# how do we get the key?!
# live = input.rtmp(listen=false, "rtmp://localhost:1935/live/key")
# live = input.rtmp(listen=false, "rtmp://vjstream.streampusher.com:1935/live/key")

# rtmp = input.rtmp("rtmp://0.0.0.0:1935/live", listen=true)

# live_dj := input.harbor(
# "liq_live_dj",
# port=9000,
Expand Down Expand Up @@ -293,8 +307,13 @@ end

output.file(%mp3, current_dump_filename_getter, live_dj(), fallible=true, reopen_when=reopen_when, reopen_delay=0.0, append=true)

# nginx-rtmp pushes the live RTMP stream here when a DJ is streaming with obs
rtmp_relay = input.rtmp(listen=true, "rtmp://datafruits_viz:1936")
# TODO uncommenting this causes type error
rtmp_audio = stereo(source.tracks(rtmp_relay).audio)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is incorrect and not needed: the decoder should be able to convert to audio implicitly when needed.


source = fallback(id="fallback",track_sensitive=false,
[live_dj(),scheduled_shows,mksafe(id="backup_playlist_mksafe", backup_playlist)])
[rtmp_audio, live_dj(),scheduled_shows,mksafe(id="backup_playlist_mksafe", backup_playlist)])

source.on_metadata(synchronous=false, pub_metadata)

Expand Down Expand Up @@ -336,3 +355,32 @@ output.icecast(%mp3,id="icecast",
send_icy_metadata=true,description="",
url="", encoding="UTF-8",
mksafe(buffer(source)))

# HLS video output

hls_audio_fallback = fallback(id="fallback",track_sensitive=false,
[live_dj(),scheduled_shows,mksafe(id="backup_playlist_mksafe", backup_playlist)])

single_video = noise()

logo_fallback = mux_audio(single_video, audio=hls_audio_fallback)

# RTMP video takes priority; fall back to static logo + audio
hls_source = fallback(id="hls_fallback", track_sensitive=false, [rtmp_relay, logo_fallback])
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#23 0.944 At radio.liq, line 368, char 77-90:   
#23 0.944 hls_source = fallback(id="hls_fallback", track_sensitive=false, [rtmp_relay, logo_fallback])                                                                                            
#23 0.944                                       
#23 0.944 Error 5: this value has type          
#23 0.944   source(audio=source(_), _)          
#23 0.944   .{

#23 0.944 but it should be a subtype of the type of the value at radio.liq, line 368, char 64-91 
#23 0.944   source(audio=pcm(stereo), _)                                                         
#23 0.944   .{

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an issue where the typechecker thinks the whole audio track is of type source(...). This most likely comes from the stereo call above which passes the audio track to the operator instead of the whole source.


hls_enc = %ffmpeg(
format="mpegts",
%video(codec="libx264", x264opts="keyint=100:min-keyint=100"),
%audio(codec="aac", channels=2, ar=44100)
)

output.file.hls(
id="hls_output",
playlist="live.m3u8",
segment_duration=4.0,
segments=5,
segments_overhead=5,
"/home/liquidsoap/hls/",
[("live", hls_enc)],
hls_source
)