rtsp-ffmpeg icon indicating copy to clipboard operation
rtsp-ffmpeg copied to clipboard

Stream not terminated properly by FFMpeg.stop (on Windows)

Open Venryx opened this issue 4 years ago • 4 comments

In my program, I have buttons to start and stop a "preview" of the selected camera. The first time previewing is run, the stream loads fine -- ffmpeg starts up, receives the data, and retransmits it to my NodeJS program in a format it can understand.

However, if I then stop the stream:

ffmpegInstance.removeListener("data", listener); // calls stop()

...and then start a new stream within about 30 seconds, that second stream fails to load.

Camera model: Reolink C2 (https://www.amazon.com/gp/product/B01LS71KNO)

I did a variety of additional tests to try to narrow down what the problem was.

Some observations:

  1. After FFMpeg.stop() was called, all ffmpeg streams from my network camera would fail for the next ~30 seconds -- including external ffmpeg launches from cmd, which just write to a file.
  2. It's not just an issue of the camera needing time between streams or something, because I can start and stop overlapping and "right after each other" streams, as many as I want, so long as they're all done from those external cmd-launched ffmpeg instances. (rather than being preceded by a stream for which FFMpeg.stop() is called)
  3. The situation remains the same, even if I exactly match the command-line options between the FFMpeg spawned-process and the from-cmd spawned-process. In other words, it's definitely not an issue with what flags are passed.
  4. The issue also occurs if I force-stop the ffmpeg process. (either by killing the process in task manager, or pressing ctrl+c in the console from which my parent program is run)

So what are the errors that occur in the ffmpeg process, specifically? Well, lots of lines like this:

[mp4 @ 000001ec843da040] Non-monotonous DTS in output stream 0:1; previous: 1022089453, current: 101517; changing to 1022089454. This may result in incorrect timestamps in the output file.
[rtsp @ 000001ec83b4d840] RTP: PT=61: bad cseq 414e expected=ca0a
[mp4 @ 000001ec843da040] Non-monotonous DTS in output stream 0:0; previous: 2774137739, current: 567874; changing to 2774137740. This may result in incorrect timestamps in the output file.
[mp4 @ 000001ec843da040] Non-monotonous DTS in output stream 0:0; previous: 2774137740, current: 1521704688; changing to 2774137741. This may result in incorrect timestamps in the output file.
[rtsp @ 000001ec83b4d840] RTP: PT=60: bad cseq a5b6 expected=4e9b
[rtsp @ 000001ec83b4d840] RTP: PT=60: bad cseq 4e9c expected=a5b8
[mp4 @ 000001ec843da040] Non-monotonous DTS in output stream 0:0; previous: 2774137741, current: 573904; changing to 2774137742. This may result in incorrect timestamps in the output file.
[rtsp @ 000001ec83b4d840] RTP: PT=60: bad cseq a5b9 expected=4e9e
[rtsp @ 000001ec83b4d840] RTP: PT=60: bad cseq 4e9f expected=a5bb
[rtsp @ 000001ec83b4d840] RTP: PT=60: bad cseq a5bc expected=4ea1
[rtsp @ 000001ec83b4d840] RTP: PT=60: bad cseq 4ea2 expected=a5be

Anyway, observations 3 and 4 were interesting, as they seemed to indicate that the problem was a failure of rtsp-ffmpeg to properly close down the stream or something.

And indeed, that is what I found. After hours of debugging, I finally figured out how to fix the issue:

FFMpeg.prototype.stop = function() {

	// replace this...
	//this.child.kill();
	
	// with this...
	this.child.stdin.write("q\r\n");

	delete this.child;
	this.emit('stop');
};

With the change above, the function still causes the process to close, but apparently it does it more "gracefully" -- allowing the ffmpeg process to do some cleanup which is apparently required for an RTSP stream (over TCP), in order for the subsequent stream to not have issues.

I've confirmed that the fix above is what solves the issue for me. Though keep in mind that I'm on Windows, so perhaps this issue doesn't show up on other platforms. But in any case, it was a super annoying bug, which I'm hoping can get fixed in this repo so others won't have to hit it.

Some posts by another user (and others) who seem to have hit the same issue:

  • https://superuser.com/questions/1289019/reolink-rtsp-ffmpeg-rtp-pt-xx-bad-cseq-if-stopped-restarted-quickly
  • https://arstechnica.com/civis/viewtopic.php?f=6&t=1419143
  • https://reolink.com/topic/reolink-rtsp-ffmpeg-rtp-ptxx-bad-cseq-if-stoppedrestarted-quickly/

Old bug ticket for ffmpeg, which seems somewhat similar but for the UDP protocol, and fixed years ago: (not that relevant solution-wise, but similar symptoms)

  • Old https://trac.ffmpeg.org/ticket/916

EDIT: I forgot that you also have to comment out the part below, otherwise the library spawns a new ffmpeg process after the first one gracefully exits (and then when the parent program exits, the second ffmpeg instance abruptly exits, causing the same problem -- just at a later point):

// comment out the below part
/*this.child.on('close', function(code) {
	if (code === 0) {
		setTimeout(FFMpeg.prototype.start.bind(this), 1000);
	}
}.bind(this));*/

Venryx avatar Jun 22 '20 02:06 Venryx

Having the same issue. What file did you modify? I can't find the syntax you have above in any of the ffmpeg files.

jgoo9410 avatar Nov 29 '22 20:11 jgoo9410

Which file did you modify? Can you post a quick tutorial?

mcpeixoto avatar Jul 01 '24 11:07 mcpeixoto

Oh! Totally forgot about this issue, I don't know why I missed it out, my bad... @Venryx thank you very much for a very detailed explanation! @mcpeixoto @jgoo9410 fixed this in a version 0.0.18 here: https://github.com/agsh/rtsp-ffmpeg/blob/master/lib/rtsp-ffmpeg.js#L130 and here: https://github.com/agsh/rtsp-ffmpeg/blob/master/lib/rtsp-ffmpeg.js#L111 Please let me know if something goes wrong

agsh avatar Jul 01 '24 20:07 agsh

Also added a new urls for the examples :smile_cat: image

agsh avatar Jul 01 '24 21:07 agsh