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 128 forks source link

Opus stream breaks up when playing a playlist #180

Closed noer closed 5 years ago

noer commented 10 years ago
set("log.file.path","/tmp/basic-radio.log")

playlist = mksafe(playlist("playlist.m3u"))

output.icecast(%opus(bitrate=48),
  host = "localhost", port = 8000,
  password = "hackme", mount = "stream.opus",
  playlist)

When listening to the stream in Chromium or VLC, the streaming stops when switching to a new track in the playlist.

Icecast error.log contains lines like this for every new track

[2014-06-13  11:01:15] INFO format-opus/initial_opus_page seen initial opus header

This makes for a very bad listener experience.

noer commented 10 years ago

This doesn't seem to be an issue with Liquidsoap anyway.

Whenever metadata on the stream is updated Chromium and VLC stops playing the stream. Icecast will notice this in the error.log as see before.

Firefox and Liquidsoap on the other hand, does NOT have this problem.

noer commented 10 years ago

Ok, a little too fast there. Firefox plays fine but Liquidsoap does have problems when the metadata in the stream is updated.

If normal metadata like title="new title" is updated, I get a little artifact in the sound. If I set metadata like key1="val1" the stream is dropped and reconnected a couple of times... not good

2014/06/17 13:26:08 [web_stream:2] Feeding stopped: Invalid_argument("Wrong number of channels.")
toots commented 10 years ago

Hi,

Your first problem is an issue with ogg decoding on the client side. As for the second it could indeed be a problem on our side.. I have tried to reproduce the issue but wasn't able to.. Do you have reproduction steps for this issue?

noer commented 10 years ago

Create an Opus stream in one Liquidsoap instance:

set("log.file.path","/tmp/basic1.log")
set("server.telnet", true)
set("server.telnet.port", 1234)

playlist = mksafe(playlist("playlist.m3u"))
playlist = server.insert_metadata(id="ID", playlist)

output.icecast(%opus(bitrate=48),
  host = "localhost", port = 8000,
  password = "hackme", mount = "stream.opus",
  playlist)

Play the stream in another Liquidsoap instance:

set("log.file.path","/tmp/basic2.log")

stream = input.http("http://localhost:8000/stream.opus")
output.dummy(fallible=true, stream)

stream = mksafe(stream)

output.alsa(device="hw:0,0", stream)

Now connect with telnet localhost 1234 and send ID.insert title="test" twice. The second time I send the command, it drops and reconnects 4 times with the message Feeding stopped: Invalid_argument("Wrong number of channels.").

You might have to send the command more than twice.

xogium commented 5 years ago

Hi, I can confirm this is still the case with the latest liquidsoap built with opus support (I used the opam way). Vlc, firefox, audacious, mpv, chromium, they all get disconnected at practically every song change. I think it has to do with ogg chaining that the opus also uses but I can be wrong. It happens also if you read a directory, not just with a playlist. If I capture a sample of the stream with wget and examine the result with opusinfo, then pastebin the result, would that help ?

toots commented 5 years ago

Thanks for the report, I'll look at it asap.

xogium commented 5 years ago

Hi, thanks ! In case you need it, here's the opusinfo output from a sample:


New logical stream (#1, serial: 348a22bc): type opus
Encoded with ocaml-opus by the Savonet Team.
WARNING: sequence number gap in stream 1. Got page 202 when expecting page 2. Indicates missing data. (normal for live streams)
WARNING: discontinuity in stream (1)
WARNING: Invalid zero byte packet in stream 1
Opus stream 1:
    Pre-skip: 3840
    Playback gain: 0 dB
    Channels: 2
    Original sample rate: 48000 Hz
    Packet duration:   20.0ms (max),   20.0ms (avg),   20.0ms (min)
    Page duration:    680.0ms (max),  654.1ms (avg),  140.0ms (min)
    Total data length: 384750 bytes (overhead: 1.46%)
    Playback length: 1m:00.100s
    Average bitrate: 51.21 kbit/s, w/o overhead: 50.47 kbit/s
Logical stream 1 ended
New logical stream (#2, serial: 2ab01604): type opus
Encoded with ocaml-opus by the Savonet Team.
User comments section follows...
    album=On The Epic Edge
    artist=Mark Denis / Ryan Andrews
    title=Ardent Justice
    genre=orchestral
    tracknumber=03
WARNING: EOS not set on stream 2 (normal for live streams)
Opus stream 2:
    Pre-skip: 3840
    Playback gain: 0 dB
    Channels: 2
    Original sample rate: 48000 Hz
    Packet duration:   20.0ms (max),   20.0ms (avg),   20.0ms (min)
    Page duration:    760.0ms (max),  662.9ms (avg),  640.0ms (min)
    Total data length: 177650 bytes (overhead: 1.56%)
    Playback length: 0m:27.760s
    Average bitrate: 51.2 kbit/s, w/o overhead: 50.4 kbit/s

That 'WARNING: Invalid zero byte packet in stream 1' looks suspicious to me...

toots commented 5 years ago

@noer Thanks for those scripts. Sorry this slipped through the cracks. I'm on it now.

MinePro120 commented 1 year ago

Are we sure this is fixed @toots? MPV reports [lavf] Linearizing discontinuity when playing the stream, and there is a small stutter on every track change in VLC. This is the command I use:

liquidsoap 'output.icecast(%opus(bitrate = 128, samplerate = 48000, stereo, signal="music", application="audio"), port = 42868, password = "hackme", mount = "stream.opus", mksafe(replaygain(playlist(mode = "randomize", reload = 900, reload_mode = "rounds", prefix = "replaygain:", "/musicDir"))))'

Liquidsoap version: 2.2.1