Search code examples
nginxffmpegrtmp

FFmpeg -> JSMpeg Websocket Closes Repeatedly


I'm trying to create a fairly simple streaming server/site. Here's the current flow:

  • OBS streams to an RTMP URL
  • Nginx accepts the RTMP stream and uses exec-push to have FFmpeg pick up the stream and transcode it
  • FFmpeg transcodes the stream and outputs it to a JSMpeg application, which displays the stream on a webpage.

When I have my exec_push statement as follows, everything seems to work perfectly, except the browser says Possible garbage data. Skipping. on every frame it receives:

exec_push /usr/bin/ffmpeg -re -i rtmp://127.0.0.1:1935/$app/$name -f mpeg1video  http://localhost:8080/supersecret;

This behavior is understandable, because JSMpeg must receive MPEG-TS data, not MPEG1 data. It sees the MPEG1 frames and thinks they're garbage.

So through some online research, I found this:

exec_push /usr/bin/ffmpeg -re -i rtmp://127.0.0.1:1935/$app/$name -c:v copy -c:a copy -f mpegts http://localhost:8080/supersecret;

Supposedly, this is supposed to transcode my RTMP stream into an MPEG-TS format, which should be compatible with JSMpeg.

However, with the second version of the command, my FFmpeg -> JSMpeg stream keeps connecting and disconnecting, connecting and disconnecting, and so on. This behavior is observed in terminal:

Stream Connected: ::1:40208
close
Stream Connected: ::1:40212
close
Stream Connected: ::1:40216
close
Stream Connected: ::1:40220
close
Stream Connected: ::1:40224
close
...

What would cause this? I am pretty certain the issue is in my exec_push command. OBS is perfectly content, which tells me that the stream is making it to the server, and if I do a push, I can do a test push to Ustream just fine, which tells me that Nginx is at least processing the stream with some reasonable degree of success.


Disclaimer: I have no idea what I'm talking about. Everything I know about FFmpeg and JSMpeg/Node is from snippets of code that I found online.


Solution

  • Answer credit goes to @Mulvya.

    In the second exec_push command, the -c:v copy -c:a copy should not be there. By using that, there isn't any transcoding going on-- it's just a stream passthrough.

    Removing the -c:v copy -c:a copy from the command and restarting Nginx yields a successful stream.