Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
7 changes: 5 additions & 2 deletions liquidsoap/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ FROM archlinux
RUN yes | pacman -Sy archlinux-keyring
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
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 useradd liquidsoap && mkdir /home/liquidsoap && chown -R liquidsoap /home/liquidsoap
RUN usermod -aG wheel liquidsoap
Expand Down Expand Up @@ -34,7 +34,7 @@ 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 gavl ffmpeg taglib mad lame ogg vorbis cry samplerate ocurl 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 @@ -51,11 +51,14 @@ 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

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

EXPOSE 9000
CMD ["/bin/bash", "-c", "eval `opam config env`; 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
74 changes: 73 additions & 1 deletion liquidsoap/radio.liq
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ stop_dump_f = ref (fun () -> ())

# live_dj = ref empty()
live_dj = ref(source.fail())
live_video_audio = ref(source.fail())
live_video = ref(source.fail())
vj_video = ref(source.fail())

# def dj_dummy_started() =
# log("dj dummy on_start")
Expand Down Expand Up @@ -237,13 +240,24 @@ end

live_dj := map_metadata(new_meta, !live_dj,update=false)

live_video := input.ffmpeg(id="main_video", max_buffer=60.0, "https://viz.streampusher.com:16666/hls/datafruits.m3u8")
vj_video := input.ffmpeg(id="vj_video", max_buffer=60.0, "https://viz.streampusher.com:16666/vj/datafruits.m3u8")

live_video_audio := audio_to_stereo(drop_video(!live_video))
# live_dj := pipe(process="./stereo_tool_cmd_64 - - -s ./stereotool.sts -k '#{stereo_tool_key}'", buffer=10.0, replay_delay=10.0, !live_dj)

# output.dummy(fallible=true, on_start=dj_dummy_started, on_stop=dj_dummy_stopped, !live_dj)
output.file(%mp3, "/home/liquidsoap/recordings/#{radio_name}-#{current_dump_filename}.mp3", !live_dj, fallible=true, append=true)

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

single_video = noise()

video_source = fallback(id="video_fallback",track_sensitive=false,
[!live_video,
mux_audio(drop_audio(!vj_video), audio=source),
mksafe(mux_audio(single_video, audio=source))])
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.

Error 10: A source cannot belong to two clocks (mux_audio_1.child[],
mux_audio_0.child[]).
The command '/bin/sh -c eval $(opam env) && liquidsoap --check radio.liq' returned a non-zero code: 1

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The problem here is that the muxing operator wants control over the sources being muxed so make sure that it can pull data from both sources at the rate that's needed to synchronize audio and video content.

The buffer operator should be available to decorelate this so you can pass the same source into two different muxers. Something like this:

video_source = fallback(id="video_fallback",track_sensitive=false,
                        [!live_video,
                         mux_audio(drop_audio(!vj_video), audio=buffer(source)),
                         mksafe(mux_audio(single_video, audio=buffer(source)))])

This operator is in need of some love so let us know if you have any issue with it.

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.

Thank you so much @toots ! This seems to compile.
So buffer will create a new clock for each muxer I assume?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Yeah


# source = if tunein_metadata_updates_enabled == "true" then on_track(tunein.submit(partnerid=tunein_partner_id,partnerkey=tunein_partner_key,stationid=tunein_station_id), source) else source end

Expand All @@ -263,3 +277,61 @@ output.icecast(%mp3,id="icecast",
icy_metadata="true",description="",
url="", encoding="UTF-8",
mksafe(buffer(source)))

aac_lofi = %ffmpeg(format="mpegts",
%audio(
codec="aac",
channels=2,
ar=44100
),
%video(
codec="libx264",
b="5M"
)
)

aac_midfi = %ffmpeg(format="mpegts",
%audio(
codec="aac",
channels=2,
ar=44100,
b="96k"
),
%video(
codec="libx264",
b="5M"
)
)

aac_hifi = %ffmpeg(format="mpegts",
%audio(
codec="aac",
channels=2,
ar=44100,
b="192k"
),
%video(
codec="libx264",
b="5M"
)
)

streams = [("aac_lofi",aac_lofi),
("aac_midfi", aac_midfi),
("aac_hifi", aac_hifi)]

def segment_name(~position,~extname,stream_name) =
timestamp = int_of_float(time())
duration = 2
"#{stream_name}_#{duration}_#{timestamp}_#{position}.#{extname}"
end

output.file.hls(playlist="#{radio_name}.m3u8",
segment_duration=2.0,
segments=5,
segments_overhead=5,
segment_name=segment_name,
persist_at="/home/liquidsoap/state.config",
"/home/liquidsoap/hls",
streams,
video_source)