m1k1o / neko

A self hosted virtual browser that runs in docker and uses WebRTC.
https://neko.m1k1o.net/
Apache License 2.0
5.96k stars 449 forks source link

RTMP streaming to rtsp-simple-server not working #205

Closed Sharrnah closed 1 year ago

Sharrnah commented 1 year ago

I wanted to use the rtmp streaming feature but with the rtsp-simple-server (https://github.com/aler9/rtsp-simple-server). I already streamed a lot and used both nginx and the rtsp-simple-server and never had any issue with both.

But with neko, streaming only works to NGINX. on rtsp-simple-server i see the following error in the log:

2022/10/05 00:06:29 INF [RTMP] [conn 10.42.3.1:32451] opened
2022/10/05 00:06:29 INF [RTMP] [conn 10.42.3.1:32451] closed (parse "'rtmp://<ip>:21935/neko?user=publish&pass=abcdef": first path segment in URL cannot contain colon)

So to me it looks as if the part here: https://github.com/m1k1o/neko/blob/d06740aa967490fa0c6ed722bd73d0e6f4cc9a9c/server/internal/capture/pipelines.go#L49

actually includes the colon and sends it to the rtmp server. NGINX doesn't seem to have an issue with it (even though i had to start and stop streaming to it 2 or 3 times until it actually worked. But that could be an unrelated issue so ignore that for now)

mbattista commented 1 year ago

Hi, I think this should be a bug in the rtsp simple server, but I am not sure yet.

The error message means that the URL cannot be parsed correctly. https://stackoverflow.com/questions/54392948/first-path-segment-in-url-cannot-contain-colon

And in your error message you can see the lonely "'" before the URL string. Also in every example of the "rtsp simple server" you can see, that they only use the location URL without the extra parameters, which are allowed and needed in some cases. The URL/location can contain extra connection or session parameters for librtmp, such as 'flashver=version'. See the librtmp documentation for more detail (https://gstreamer.freedesktop.org/documentation/rtmp/rtmpsink.html?gi-language=c) and (https://stackoverflow.com/questions/26497747/does-the-live-1-on-ffmpeg-rtmp-urls-mean-that-the-stream-is-live-and-you-canno)

I think that removing the "live=1" parameter and the enclosing "'" from the location in the line you have posted should work for rtsp:

pipelineStr = fmt.Sprintf("flvmux name=mux ! rtmpsink location=%s %s audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. %s x264enc bframes=0 key-int-max=60 byte-stream=true tune=zerolatency speed-preset=veryfast ! mux.", url, audio, video)

I will try this change and look into it.

Sharrnah commented 1 year ago

thank you. If it is a bug in rtsp-simple-server, it is one that i never encountered so far. i streamed to it using OBS, vMix, XSplit and probably others before and it never had any issue with URLs.

that doesn't mean its out of the question that it revealed an issue with rtsp-simple-server of course.

m1k1o commented 1 year ago

I also tried streaming from neko to Youtube an it worked with current setup. When removing live=1 it did not work with nginx-rtmp on the other hand.

mbattista commented 1 year ago

Hi, I tested it yesterday and today a bit.

If I remove the ' at this line with a trim https://github.com/aler9/rtsp-simple-server/blob/v0.20.0/internal/rtmp/conn.go#L359 everything works as expected.

But I think the position is wrong, since probably there is also an ' at the end of the parameters and the rtsp-simple-server correctly splits the Location URL and the parameters before reading in the URL.

I tried to remove the ' from the Location URL in neko, but then the pipeline was no longer valid.

m1k1o commented 1 year ago

Even official docs from gstreamer use it like we do:

 gst-launch-1.0 -v videotestsrc ! ffenc_flv ! flvmux ! rtmpsink location='rtmp://localhost/path/to/stream live=1'

https://gstreamer.freedesktop.org/documentation/rtmp/rtmpsink.html

Sharrnah commented 1 year ago

that doesn't mean that it might not even be an issue with gstreamer / rtmpsink.

In my opinion it should not even send the ' character to the server at all.

I guess as a (hopefully temporary) workaround i could set the NEKO_BROADCAST_PIPELINE variable to

flvmux name=mux ! rtmpsink location={url} {device} audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. {display} x264enc bframes=0 key-int-max=60 byte-stream=true tune=zerolatency speed-preset=veryfast ! mux.

Edit: That doesn't work either. i get (neko:13): GStreamer-CRITICAL **: 17:49:36.994: gst_element_make_from_uri: assertion 'gst_uri_is_valid (uri)' failed as error, and everything except the URL is logged in the pipeline:

5:49PM INF starting pipeline module=capture src="flvmux name=mux ! rtmpsink location= auto_null.monitor audio/x-raw,channels=2 ! audioconvert ! voaacenc ! mux. :99.0 x264enc bframes=0 key-int-max=60 byte-stream=true tune=zerolatency speed-preset=veryfast ! mux." submodule=broadcast url=
mbattista commented 1 year ago

As I said before, when I removed the ' in the pipeline the pipeline was no longer valid.

If you need a (bad) hotfix for rtsp-simple-server you can use this version: https://github.com/mbattista/rtsp-simple-server or this docker images https://hub.docker.com/r/mbattista/rtsp-simple-server/tags

They will work with neko, but I will not keep them updated.

m1k1o commented 1 year ago

Fixed in v0.21.2: https://github.com/aler9/mediamtx/issues/1177