ossrs / srs

SRS is a simple, high-efficiency, real-time video server supporting RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH, and GB28181.
https://ossrs.io
MIT License
24.79k stars 5.28k forks source link

Support FFmpeg timecode, fix AMF0 parsing failed. v5.0.179 v6.0.77 #3804

Closed winlinvip closed 9 months ago

winlinvip commented 9 months ago

Please see https://github.com/ossrs/srs/issues/3803 for detail:

  1. When using FFmpeg with the -map 0 option, there may be a 4-byte timecode in the AMF0 Data.
  2. SRS should be able to handle this packet without causing a parsing error, as it's generally expected to be an AMF0 string, not a 4-byte timecode.
  3. Disregard the timecode since SRS doesn't utilize it.

See Error submitting a packet to the muxer: Broken pipe, Error muxing a packet


Co-authored-by: john hondaxiao@tencent.com

streamingsystems commented 7 months ago

https://github.com/ossrs/srs/assets/59889605/e72004cc-7df1-403e-8f83-654d3ee4a269

Hi,

It seems like maybe this problem is not fixed or there is a related bug. I am running FFMPEG 6 and the latest version of SRS (I just built it from the source).

When I run this:

ffmpeg -stream_loop -1 -re -i 2.mp4 -stream_loop -1 -re -i 2.mp4 -stream_loop -1 -re -i 2.mp4 -map 0 -c copy -f flv rtmp://127.0.0.1:1935/live/ss/1 -map 1 -c copy -f flv rtmp://127.0.0.1:1935/live/ss/2 -map 2 -c copy -f flv rtmp://127.0.0.1:1935/live/ss/3

(In my real application I have different video as inputs but they were too big to all upload to GitHub but the above command will use the same input video and reproduce the problem)

When the video is done and starts over at the beginning ffmpeg crashes with this:

av_interleaved_write_frame(): Broken pipesize= 4881kB time=00:00:49.98 bitrate= 800.0kbits/s speed= 1x [out#1/flv @ 0x7fd52e90cec0] Error muxing a packet av_interleaved_write_frame(): Broken pipe [out#2/flv @ 0x7fd52ea112c0] Error muxing a packet

"Broken Pipe" usually means the server hit some type of an error.

Do you have any developers that also work on FFMPEG we would pay the money to fix this problem in ffmpeg as it seems ffmpeg is not sending the correct bytes in this situation.

Thanks!

winlinvip commented 7 months ago

@streamingsystems In fact, you don't need to modify FFmpeg. I noticed that there is a timeout during the Stream loop. So, you just need to extend the timeout period below to solve the problem:

vhost __defaultVhost__ {
    publish { 
        firstpkt_timeout 30000; 
        normal_timeout 30000; 
    }
}

TRANS_BY_GPT4

streamingsystems commented 7 months ago

Good evening,

It seems that ffmpeg is not sending some data properly that is causing a longer timeout needed?

If you just use "1" map like this:

ffmpeg -stream_loop -1 -re -i 2.mp4 -map 0 -c copy -f flv rtmp://127.0.0.1:1935/live/ss/1 -map 1

ffmpeg does not exit with a "broken pipe" and runs correctly with no change to the timeout.

But if I do 2 (or more( maps:

ffmpeg -stream_loop -1 -re -i 2.mp4 -stream_loop -1 -re -i 2.mp4 -map 0 -c copy -f flv rtmp://127.0.0.1:1935/live/ss/1 -map 1 -c copy -f flv rtmp://127.0.0.1:1935/live/ss/2

av_interleaved_write_frame(): Broken pipe 4855kB time=00:00:49.55 bitrate= 802.6kbits/s speed= 1x

To me, this seems to be a bug in the "map" or "rtmp" code in ffmpeg that it's behaving differently by maybe not sending the data related to timecode that is causing the server to hit a timeout and fail?

I use the timouts low for other reasons so I am trying to not have to increase the timeout for what seems to be a bug in ffmpeg.

As always thanks for your help.

winlinvip commented 7 months ago

@streamingsystems In fact, we cannot completely rule out the possibility of a bug in FFmpeg. You could report this to the FFmpeg community. By increasing the timeout configuration in SRS, you should be able to get around this issue without affecting your business. Additionally, if 'map 0' is problematic, is it possible to not use 'map 0' and only use 'map 1', 'map 2', 'map N', etc.?

streamingsystems commented 7 months ago

Hi,

I don't believe that map 0 specifically is the problem, it seems when you use more than 1 map (map 0 being the first) it causes the problem.

What is puzzling and problematic to me is that it seems like ffmpeg with more than 1 map in the command is not sending the proper timing information to the server which is causing the timeout to be hit.

In other words, with just a single map the server does not need a 30s timeout and ffmpeg works fine. When more than 1 map is used, the server times out which would imply to me that ffmpeg is not sending the proper data to the server which is causing it to timeout.

I am trying to find a ffmpeg developer that can look at the "map" function.

If you see this bug report I opened a while ago:

https://trac.ffmpeg.org/ticket/10565

Steven Luis replies with this comment:

Looks the problem is happened when it publish timecode stream:

Stream #0:20x3: Data: none (tmcd / 0x64636D74) Metadata: handler_name : VideoHandler timecode : 01:00:00:00

I am emailing with Steven now to see if I can pay him to look at the code and see if maybe ffmpeg is not sending up the proper timecode information when more than 1 map is used.

winlinvip commented 7 months ago

Steven Liu is my good friend and also the maintainer of the FFmpeg RTMP/FLV module. If he is willing to spend time on it, there is hope that he can solve this problem.

TRANS_BY_GPT4