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.41k stars 130 forks source link

Not able to listen to the stream coming from webcaster client #744

Closed vatsalkgor closed 5 years ago

vatsalkgor commented 5 years ago

Hi, Please forgive me if i post something that was previously answered as I am a noob in liquidsoap. I have researched extensively but was not able to find the solution that's why I am opening the new Issue.

First of all I would like to tell what I want to do. I want to make a radio station in my college that can broadcast live streams coming from different users. So I googled it and found that WebSocket is a protocol that provides full duplex client and server side communication. I found the implementation in Webcaster.js by @toots.

So I am using this link Webcaster to generate the stream. (I have not cloned the repo just using github.io link to generate the stream.)

My liquidsoap code is

set('log.file.path','/tmp/harbor.log')
set("harbor.bind_addr","0.0.0.0")
set("harbor.verbose",true)

radio = mksafe(input.harbor("mount",port=8080))
output.icecast(%mp3,host='localhost',port=8000,password='hackme',mount='harbor',radio)

If I run the script without mksafe then I get source fallible error. The logs in the logs file says

2019/03/29 23:16:35 >>> LOG START
2019/03/29 23:16:35 [protocols.external:3] Found "/usr/bin/wget".
2019/03/29 23:16:35 [main:3] Liquidsoap 1.1.1
2019/03/29 23:16:35 [main:3] Using: graphics=[distributed with Ocaml] pcre=7.2.3 dtools=0.3.1 duppy=0.5.1 duppy.syntax=0.5.1 cry=0.2.2 mm=0.2.1 xmlplaylist=0.1.3 lastfm=0.3.0 ogg=0.4.5 vorbis=0.6.1 opus=0.1.0 speex=0.2.0 mad=0.4.4 flac=0.1.1 flac.ogg=0.1.1 dynlink=[distributed with Ocaml] lame=0.3.2 shine=0.2.0 gstreamer=0.2.0 frei0r=0.1.0 voaacenc=0.1.0 theora=0.3.0 gavl=0.1.5 bjack=0.1.4 alsa=0.2.3 ao=0.2.0 samplerate=0.1.2 taglib=0.3.1 magic=0.7.3 camomile=0.8.4 inotify=1.0 faad=0.3.2 soundtouch=0.1.7 portaudio=0.2.0 pulseaudio=0.1.2 ladspa=0.1.4 dssi=0.1.1 sdl=0.9.1 camlimages=4.2.0 lo=0.1.0 yojson=1.3.2 gd=1.0a5
2019/03/29 23:16:35 [dynamic.loader:3] Could not find dynamic module for fdkaac encoder.
2019/03/29 23:16:35 [dynamic.loader:3] Could not find dynamic module for aacplus encoder.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/mad.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/cry.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/lame.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/ogg.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/faad.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/taglib.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/vorbis.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/flac_ogg.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/alsa.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/voaacenc.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/flac.cmxs.
2019/03/29 23:16:35 [dynamic.loader:2] Loaded plugin file /usr/lib/liquidsoap/1.1.1/plugins/pulseaudio.cmxs.
2019/03/29 23:16:35 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz master.
2019/03/29 23:16:35 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples.
2019/03/29 23:16:35 [frame:3] Targetting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks.
2019/03/29 23:16:35 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks.
2019/03/29 23:16:35 [threads:3] Created thread "generic queue #1".
2019/03/29 23:16:35 [threads:3] Created thread "generic queue #2".
2019/03/29 23:16:35 [harbor:3] Adding mountpoint '/mount' on port 8080
2019/03/29 23:16:35 [harbor:3] Connecting mount harbor for source@localhost...
2019/03/29 23:16:35 [harbor:3] Connection setup was successful.
2019/03/29 23:16:35 [threads:3] Created thread "wallclock_main" (1 total).
2019/03/29 23:16:35 [clock.wallclock_main:3] Streaming loop starts, synchronized with wallclock.
2019/03/29 23:16:35 [mksafe:3] Switch to safe_blank.

One point to be noted here is that I am using an old liquidsoap v1.1.1

Can anyone tell me what is the issue here??

vatsalkgor commented 5 years ago

saw issue #276 and updated to latest liquidsoap using opam. However the porblem is still not solved. in the log file I can see that the connection is successful but suddenly after i get error like 'source failed(no more tracks) stopping out...' Here is my .liq file for reference.

set('log.file.path','/tmp/harbor.log')
set("harbor.bind_addr","0.0.0.0")
set("harbor.verbose",true)
set("log.level",5)

radio = input.harbor("/mount",port=8080)
live = fallback(track_sensitive=false,[radio])
output.icecast(%mp3,fallible=true,host="localhost",port=8000,password="hackme",mount="harbor",live)
pl1 = mksafe(playlist("playlist1.txt"))
output.icecast(%mp3,host="localhost",port=8000,password="hackme",mount="pl1",pl1)

the playlist1 is successfully played on icecast2 but i can't see mount point "harbor" in the icecast.

Log File reads:

2019/03/31 16:41:18 >>> LOG START
2019/03/31 16:41:18 [main:3] Liquidsoap 1.3.6
2019/03/31 16:41:18 [main:3] Using: bytes=[distributed with OCaml 4.02 or above] pcre=7.4.1 dtools=0.4.1 duppy=0.8.0 cry=0.6.2 mm=0.4.0 ogg=0.5.2 vorbis=0.7.1 mad=0.4.5 dynlink=[distributed with Ocaml] lame=0.3.3 alsa=0.2.3 ao=0.2.1 samplerate=0.1.4 taglib=0.3.3 camomile=1.0.1
2019/03/31 16:41:18 [dynamic.loader:3] Could not find dynamic module for fdkaac encoder.
2019/03/31 16:41:18 [lang.deprecated:2] WARNING: "harbor.bind_addr" is deprecated! Please use "harbor.bind_addrs"
2019/03/31 16:41:18 [frame:3] Using 44100Hz audio, 25Hz video, 44100Hz master.
2019/03/31 16:41:18 [frame:3] Frame size must be a multiple of 1764 ticks = 1764 audio samples = 1 video samples.
2019/03/31 16:41:18 [frame:3] Targetting 'frame.duration': 0.04s = 1764 audio samples = 1764 ticks.
2019/03/31 16:41:18 [frame:3] Frames last 0.04s = 1764 audio samples = 1 video samples = 1764 ticks.
2019/03/31 16:41:18 [video.converter:4] Couldn't find preferred video converter: gavl.
2019/03/31 16:41:18 [audio.converter:4] Using preferred samplerate converter: libsamplerate.
2019/03/31 16:41:18 [threads:3] Created thread "generic queue #1".
2019/03/31 16:41:18 [threads:3] Created thread "generic queue #2".
2019/03/31 16:41:18 [threads:3] Created thread "non-blocking queue #1".
2019/03/31 16:41:18 [threads:3] Created thread "non-blocking queue #2".
2019/03/31 16:41:18 [clock:4] Currently 1 clocks allocated.
2019/03/31 16:41:18 [clock.wallclock_main:4] Starting 2 sources...
2019/03/31 16:41:18 [source:4] Source output.icecast_6217 gets up.
2019/03/31 16:41:18 [source:4] Source mksafe gets up.
2019/03/31 16:41:18 [source:4] Source playlist_6213 gets up.
2019/03/31 16:41:18 [playlist1(dot)txt:3] Loading playlist...
2019/03/31 16:41:18 [playlist1(dot)txt:3] No mime type specified, trying autodetection.
2019/03/31 16:41:18 [playlist parser:4] Trying application/x-cue parser
2019/03/31 16:41:18 [playlist parser:4] Trying audio/x-scpls parser
2019/03/31 16:41:18 [playlist parser:4] Trying application/x-mpegURL parser
2019/03/31 16:41:18 [playlist1(dot)txt:3] Playlist treated as format application/x-mpegURL
2019/03/31 16:41:18 [playlist1(dot)txt:3] Successfully loaded a playlist of 19 tracks.
2019/03/31 16:41:18 [playlist1(dot)txt:4] Content kind is {audio=2;video=0;midi=0}.
2019/03/31 16:41:18 [playlist1(dot)txt:4] Activations changed: static=[], dynamic=[mksafe:pl1:pl1].
2019/03/31 16:41:18 [source:4] Source safe_blank gets up.
2019/03/31 16:41:18 [safe_blank:4] Content kind is {audio=2;video=0;midi=0}.
2019/03/31 16:41:18 [safe_blank:4] Activations changed: static=[], dynamic=[mksafe:pl1:pl1].
2019/03/31 16:41:18 [mksafe:4] Activations changed: static=[pl1:pl1], dynamic=[].
2019/03/31 16:41:18 [playlist1(dot)txt:5] Queue is empty!
2019/03/31 16:41:18 [playlist1(dot)txt:5] Failed to prepare track: no file.
2019/03/31 16:41:18 [pl1:4] Activations changed: static=[pl1], dynamic=[].
2019/03/31 16:41:18 [pl1:4] Enabling caching mode: active source.
2019/03/31 16:41:18 [source:4] Source output.icecast_6212 gets up.
2019/03/31 16:41:18 [source:4] Source fallback_6210 gets up.
2019/03/31 16:41:18 [source:4] Source input.harbor_6208 gets up.
2019/03/31 16:41:18 [input.harbor_6208:4] Content kind is {audio=2;video=0;midi=0}.
2019/03/31 16:41:18 [harbor:4] Opening port 8080 with icy = false
2019/03/31 16:41:18 [harbor:3] Adding mountpoint '/mount' on port 8080
2019/03/31 16:41:18 [input(dot)harbor_6208:4] Activations changed: static=[], dynamic=[fallback_6210:harbor:harbor].
2019/03/31 16:41:18 [fallback_6210:4] Activations changed: static=[harbor:harbor], dynamic=[].
2019/03/31 16:41:18 [harbor:4] Activations changed: static=[harbor], dynamic=[].
2019/03/31 16:41:18 [harbor:4] Enabling caching mode: active source.
2019/03/31 16:41:18 [pl1:3] Connecting mount pl1 for source@localhost...
2019/03/31 16:41:18 [decoder:4] Trying method "META" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder:4] Trying method "WAV" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder.wav/aiff:4] Invalid file extension for "./songs/Suit Suit_320(MyMp3Song).mp3"!
2019/03/31 16:41:18 [decoder:4] Trying method "AIFF" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder.wav/aiff:4] Invalid file extension for "./songs/Suit Suit_320(MyMp3Song).mp3"!
2019/03/31 16:41:18 [decoder:4] Trying method "MIDI" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder:4] Trying method "IMAGE" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder:4] Trying method "OGG" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder.ogg:4] Invalid file extension for "./songs/Suit Suit_320(MyMp3Song).mp3"!
2019/03/31 16:41:18 [decoder:4] Trying method "MAD" for "./songs/Suit Suit_320(MyMp3Song).mp3"...
2019/03/31 16:41:18 [decoder.mad:4] Libmad recognizes "./songs/Suit Suit_320(MyMp3Song).mp3" as mpeg audio (layer III, 320kbps, 44100Hz, 2 channels).
2019/03/31 16:41:18 [decoder:3] Method "MAD" accepted "./songs/Suit Suit_320(MyMp3Song).mp3".
2019/03/31 16:41:18 [decoder.ogg:4] Invalid file extension for "./songs/Suit Suit_320(MyMp3Song).mp3"!
2019/03/31 16:41:18 [pl1:3] Connection setup was successful.
2019/03/31 16:41:18 [harbor:3] Connecting mount harbor for source@localhost...
2019/03/31 16:41:18 [playlist1(dot)txt:4] Remaining: 0.0s, queued: 0.0s, adding: 30.0s (RID 1)
2019/03/31 16:41:18 [harbor:3] Connection setup was successful.
2019/03/31 16:41:18 [threads:3] Created thread "wallclock_main" (1 total).
2019/03/31 16:41:18 [clock.wallclock_main:3] Streaming loop starts, synchronized with wallclock.
2019/03/31 16:41:18 [clock:4] Main phase starts.
2019/03/31 16:41:19 [mksafe:3] Switch to safe_blank.
2019/03/31 16:41:19 [safe_blank:4] Activations changed: static=[mksafe:pl1:pl1], dynamic=[mksafe:pl1:pl1].
2019/03/31 16:41:19 [playlist1(dot)txt:4] Remaining: 0.0s, queued: 30.0s, taking: 30.0s
2019/03/31 16:41:19 [playlist1(dot)txt:3] Prepared "./songs/Suit Suit_320(MyMp3Song).mp3" (RID 1).
2019/03/31 16:41:19 [mksafe:3] Switch to playlist1(dot)txt with transition.
2019/03/31 16:41:19 [safe_blank:4] Activations changed: static=[], dynamic=[mksafe:pl1:pl1].
2019/03/31 16:41:19 [playlist1(dot)txt:4] Activations changed: static=[mksafe:pl1:pl1], dynamic=[mksafe:pl1:pl1].
2019/03/31 16:41:19 [harbor:3] Source failed (no more tracks) stopping output...
2019/03/31 16:41:19 [harbor:3] Closing connection...

Eagerly waiting for response.

toots commented 5 years ago

Hi,

It looks like the webcaster client is not sending any data. Have you looked at the logs on the browser's side?

vatsalkgor commented 5 years ago

First of all thanks for reply.

Yes, you are right. At first the browser was saying: SecurityError: The operation is insecure.

Then I followed the SO answer which fixed the above issue. It is now working in Firefox.

Then I tried to do the same with Chromium. But found that the song is not even playing in the browser. It says that the "AudioContext must be resumed or created after a user gesture on the page" followed by a more information link

So I guess that the way webcaster is written, does not support this change in google chrome / chromium.

P.S. This change in chrome/chromium is done after version 66 in May 2018. However, I have not tested this issue in versions before 66.

toots commented 5 years ago

Hi,

Le ven. 12 avr. 2019 à 09:19, vatsalkgor notifications@github.com a écrit :

First of all thanks for reply.

Yes, you are right. At first the browser was saying: SecurityError: The operation is insecure.

Then I followed the SO answer which fixed the above issue. It is now working in Firefox.

Then I tried to do the same with Chromium. But found that the song is not even playing in the browser. It says that the "AudioContext must be resumed or created after a user gesture on the page" with a link for more information trailing. link

So I guess that the way webcaster is written, does not support this change in google chrome / chromium.

P.S. This change in chrome/chromium is done after version 66 in May 2018. However, I have not tested this issue in versions before 66.

Thanks for reporting this. I'll have to test the code. The web audio support is constantly improving and it's possible that the code is now outdated.

Romain

vatsalkgor commented 5 years ago

Great. As of now I am closing the issue. Please let me know if there is any update on webcaster client.

toots commented 5 years ago

@vatsalkgor Should be fixed now! Try it at: https://webcast.github.io/webcaster/