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.77k stars 5.28k forks source link

WebRTC: FLV 404 when transmux WebRTC to FLV. #2682

Open thegobot opened 2 years ago

thegobot commented 2 years ago

Note: Issues that do not provide the following information will be deleted directly (Please follow the issue template, or we will delete it)'

Make sure to maintain the markdown structure.

Note: For inquiries and discussions, please submit them to the SRS forum (Please ask questions at) http://bbs.ossrs.net

Make sure to maintain the markdown structure.

Description

Make sure to maintain the markdown structure.

Please describe your issue here.

Make sure to maintain the markdown structure.

  1. SRS version: 4.0.178
  2. The log of SRS is as follows:

Make sure to maintain the markdown structure.

xxxxxxxxxxxx
  1. The configuration of SRS is as follows:

Make sure to maintain the markdown structure.

listen              1940;
max_connections     1000;
daemon              off;
srs_log_tank        console;
srs_log_level verbose;

http_server {
    enabled         on;
    crossdomain     off;
    listen          8040;
    dir             ./objs/nginx/html;
}

http_api {
    crossdomain     off;
    enabled         on;
    listen          1945;
}
stats {
    network         0;
}
rtc_server {
    enabled on;
    listen 9999;
    # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
    candidate 178.76.25.21;
}

vhost webrtc {

    rtc {
        enabled     on;
        rtc_to_rtmp on;
    }

    http_remux {
        enabled     on;
        mount       /[app]/[stream].flv;

    }
}

Replay

Make sure to maintain the markdown structure.

How to replay bug?

Make sure to maintain the markdown structure.

  1. Push WebRTC to server
  2. Start playing FLV in Chrome with Flv.JS

Expect

Please describe your expectation. Continuous playback, no pause

Some bugs

  1. First, when downloading (stream.flv from SRS server), the server gives a 404 error, if you repeat it, the download will start. If you stop downloading and start snoring, then the server again gives a 404 error, after 5 times the server sends the file successfully
  2. The video is interrupted approximately every 5 seconds. At the same time, errors like ` net::ERR_INCOMPLETE_CHUNKED_ENCODING [IOController] > Loader error, code = undefined, msg = Fetch stream meet Early-EOF [TransmuxingController] > IOException: type = UnrecoverableEarlyEof, code = undefined, msg = Fetch stream meet Early-EOF ... reload flv .... net::ERR_FAILED 404 ... reload flv again ... net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 [IOController] > Loader error, code = undefined, msg = Fetch stream meet Early-EOF [TransmuxingController] > IOException: type = UnrecoverableEarlyEof, code = undefined, msg = Fetch stream meet Early-EOF ... reload ... [MSEController] > MediaSource onSourceOpen [FLVDemuxer] > Parsed AudioSpecificConfig [FLVDemuxer] > Parsed AVCDecoderConfigurationRecord [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! [FLVDemuxer] > Found another AVCDecoderConfigurationRecord! ... infinite

`

TRANS_BY_GPT3

winlinvip commented 2 years ago

It's because the SPS/PPS changes every N seconds.

SRS can not fix it because it's the codec gap between WebRTC and RTMP.

However, there is a workaround, please use FFmpeg to transcode RTMP stream:

  1. Publish by WebRTC, like webrtc://localhost/live/livestream
  2. Transcode by FFmpeg, like rtmp://localhost/live/livestream_ffmpeg
  3. Play the transcoded stream http://localhost:8080/live/livestream_ffmpeg.flv

Is this solution OK?

thegobot commented 2 years ago
vhost webrtc {

    rtc {
        enabled     on;
        rtc_to_rtmp on;
    }

    transcode {
        enabled     on;
        ffmpeg      /var/www/cli/ffmpeg;

        engine ff {
            enabled         on;
            vcodec libx264;
            acodec          aac;
            asample_rate    44100;
            achannels       2;
            output          rtmp://127.0.0.1:[port]/html5/[stream]?vhost=html5;
        }
    }

    mix_correct             on;

    http_remux {
        enabled     on;
        mount       /[app]/[stream].flv;

    }
}

vhost html5 {

}

play webrtc with ffplay...

[h264 @ 0000000000360440] missing picture in access unit with size 344
[AVBSFContext @ 0000000000360980] nal_unit_type: 20, nal_ref_idc: 2
[h264 @ 0000000000360440] nal_unit_type: 20, nal_ref_idc: 2
[h264 @ 0000000000360440] Unknown NAL code: 20 (2721 bits)
[h264 @ 0000000000360440] no frame!
[flv @ 0000000000335080] type:8, size:119, last:-1, dts:609 pos:6769
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:135, last:-1, dts:649 pos:6903
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:126, last:-1, dts:669 pos:7053
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:134, last:-1, dts:689 pos:7194
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:9, size:322, last:-1, dts:690 pos:7343
[flv @ 0000000000335080] 0 27 0
[h264 @ 0000000000360440] missing picture in access unit with size 317
[AVBSFContext @ 0000000000360980] nal_unit_type: 25, nal_ref_idc: 1
[h264 @ 0000000000360440] nal_unit_type: 25, nal_ref_idc: 1
[h264 @ 0000000000360440] Unknown NAL code: 25 (2509 bits)
[h264 @ 0000000000360440] no frame!
[flv @ 0000000000335080] type:8, size:137, last:-1, dts:709 pos:7680
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:124, last:-1, dts:729 pos:7832
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:128, last:-1, dts:749 pos:7971
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:127, last:-1, dts:769 pos:8114
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:8, size:130, last:-1, dts:789 pos:8256
[flv @ 0000000000335080] 1 AF 0
[flv @ 0000000000335080] type:9, size:1707, last:-1, dts:792 pos:8401
[flv @ 0000000000335080] 0 27 0
[h264 @ 0000000000360440] missing picture in access unit with size 1702
[AVBSFContext @ 0000000000360980] No start code is found.
[flv @ 0000000000335080] After avformat_find_stream_info() pos: 10115 bytes read:10115 seeks:0 frames:46
rtmp://127.0.0.1:1940/webrtc?vhost=webrtc/stream: could not find codec parameters
[AVIOContext @ 00000000003379c0] Statistics: 10115 bytes read, 0 seeks
[rtmp @ 000000000032c1c0] Deleting stream...

Screenshot_137

thegobot commented 2 years ago

i was able to transcode

1) The problem was in the rtmp ports. In the config I changed the default rtmp port 1935 to 1940 (listen). The problem is that SRS still uses port 1935 instead 1940. Template doesn't work (I am currently using version SRS 2, everything is fine there)

output          rtmp://127.0.0.1:[port]

Check this moment

2) Transcoding didn't solve the problem.

I researched a similar problem a year ago with freezing a video received from a WebRTC stream (project Intel OWT). I started debugging chrominum and came to the conclusion that the video freezes due to the SPS\PPS (as it turned out, there were other bugs along the way). At the moment, I successfully send a WebRTC stream to the server (OWT), converted into rtmp and distributed through the SRS into HTTP-FLV, HLS etc.

Recently I noticed and was glad that you managed to make friends with WebRTC, but unfortunately the current implementation is not suitable for production

Take a look at this thread, it discusses a problem similar to ours. https://bugs.chromium.org/p/chromium/issues/detail?id=1111273#c170

In particular, pay attention to https://bugs.chromium.org/p/chromium/issues/detail?id=1111273#c170

Perhaps your ID changes in SPS\PPS. The main thing: do not send SPS\PPS unnecessarily, this will reset the configuration in the players and the video will freezes. Send SPS\PPS only when the configuration is changed (width, height, etc).

I have uploaded sample videos.

https://github.com/thegobot/srs/raw/master/webrtc_from_http_remux.flv https://github.com/thegobot/srs/raw/master/html5_from_rtmp.flv

thegobot commented 2 years ago

Also, a similar error is very common. Through time. Through two. Randomly

GET https://127.0.0.1/webrtc/stream.flv net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)

Response headers

HTTP/1.1 200 OK
Date: Mon, 18 Oct 2021 05:27:13 GMT
Content-Type: video/x-flv
Transfer-Encoding: chunked
Connection: keep-alive
Access-Control-Allow-Origin: *

Simple test to reproduce

window.fetch("https://127.0.0.1/webrtc/stream.flv").then((res)=>{

    let reader = res.body.getReader();
    function pump(){
        reader.read().then((result) => {

            if(!result.done){
                pump();
            }
        }).catch((e)=>{
            error(e); //TypeError: network error
        });
    }

    pump();
})

UPD: it seems the problem is Nginx proxy...

thegobot commented 2 years ago

I found a place in the code, SrsRtmpFromRtcBridger::packet_video_key_frame

https://github.com/ossrs/srs/blob/e222f0da1b58de0d105134be9b4cf2acdffec2c1/trunk/src/app/srs_app_rtc_source.cpp#L1486

Always mux as an AVCSequenceHeader(type=)0, instead of NALU (type=1 in flv format). This is not true. I'm not strong in C++, I fixed similar code in Java, but I can't do it here. If you find the strength, correct this code, there are actually 10 lines to write.

Well, I on the client (chrome player) then ignore the second header, just skip it if it comes again from the server. That's how it works.

TRANS_BY_GPT3