ossrs / srs

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

RTMP stream of H265 format can only be played by FLV/HLS #4107

Closed HenryTree closed 2 months ago

HenryTree commented 3 months ago

Describe the bug Use Javacv-FFmpeg push RTSP stream of H265 format to SRS server with RTMP protocol, but the video can only be played by FLV/HLS, video cannot be played by FLV and HLS at the same time, also can not be played by RTMP/RTC. Use FFmpeg will have the same problem. Without changing any other settings, just changing the camera encoder to H264, the video can be played normally by RTMP/RTC.

Version SRS/6.0.129(Hang) image

FFmepg6.1

To Reproduce Steps to reproduce the behavior:

  1. srs: CANDIDATE=192.168.50.21 docker run -d --env CANDIDATE=$CANDIDATE -p 1935:1935 -p 8502:8080 -p 1985:1985 -p 8000:8000/udp -v /home/energy/srs/live/:/usr/local/srs/objs/nginx/html/energy/srs/live/ -v /home/energy/srs/replay/:/usr/local/srs/objs/nginx/html/energy/srs/replay/ -v /home/energy/srs/download/:/usr/local/srs/objs/nginx/html/download/ -v /home/energy/srs/conf/camera-docker.conf:/usr/local/srs/conf/camera-docker.conf -v /etc/hosts:/etc/hosts --restart unless-stopped --name srs registry.cn-hangzhou.aliyuncs.com/ossrs/srs:6 ./objs/srs -c /usr/local/srs/conf/camera-docker.conf

  2. Javacv code: String streamUrl = "rtsp://admin:admin@192.168.50.83:554/LiveMedia/ch1/Media1"; FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(streamUrl); grabber.setOption("rtsp_transport", "tcp"); grabber.setOption("stimeout", "2000000"); grabber.start();

        FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("rtmp://localhost/live/livestream", grabber.getImageWidth(), grabber.getImageHeight());
        recorder.setVideoOption("crf", "28");
        recorder.setGopSize(2);
        recorder.setFrameRate(grabber.getFrameRate());
        recorder.setVideoBitrate(grabber.getVideoBitrate());
        recorder.setAudioChannels(grabber.getAudioChannels());
        recorder.setAudioBitrate(grabber.getAudioBitrate());
        recorder.setSampleRate(grabber.getSampleRate());
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.setFormat("flv");
        recorder.setVideoCodec(grabber.getVideoCodec());
        AVFormatContext avFormatContext = grabber.getFormatContext();
        recorder.start(avFormatContext);
        grabber.flush();
    
        long err_index = 0;
        for (int no_frame_index = 0; no_frame_index < 5 || err_index < 5;) {
            try {
                AVPacket pkt = null;
                pkt = grabber.grabPacket();
                if (pkt == null || pkt.size() <= 0 || pkt.data() == null) {
                    no_frame_index++;
                    err_index++;
                    continue;
                }
                else {
                    log.info("dts: {}, pts: {}", pkt.dts(), pkt.pts());
                }
                err_index += (recorder.recordPacket(pkt) ? 0 : 1);
                av_packet_unref(pkt);
            } catch (org.bytedeco.javacv.FrameGrabber.Exception e) {
                err_index++;
            } catch (org.bytedeco.javacv.FrameRecorder.Exception e) {
                err_index++;
            }
        }
        grabber.close();
        grabber.release();
        recorder.close();
        recorder.release();

FFmpeg: ./ffmpeg -y -i "rtsp://admin:admin@192.168.50.83:554/LiveMedia/ch1/Media1" -acodec copy -vcodec libx265 -f flv rtmp://localhost/live/livestream image image

Expected behavior Stream can be played by RTMP/webRTC.

Screenshots srs logs: image image

HLS: image

RTMP: image

WHEP: image

Additional context conf:

listen 1935; max_connections 1000; srs_log_tank console; daemon off; http_api { enabled on; listen 1985; auth { enabled on; username admin; password admin; } } http_server { enabled on; listen 8080; dir ./objs/nginx/html; } rtc_server { enabled on; listen 8000; candidate $CANDIDATE; }

vhost defaultVhost { hls { enabled on; hls_path ./objs/nginx/html; hls_fragment 5; hls_window 300; } rtc { enabled on; rtmp_to_rtc on; rtc_to_rtmp on; }

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

}

TRANS_BY_GPT4

suzp1984 commented 3 months ago

https://github.com/ossrs/srs/blob/6bbd461ec960652c65deaaa9356d79fac691dd6d/trunk/src/app/srs_app_rtc_source.cpp#L1070-L1075

H.265(HEVC) is not supported by WebRTC.

It's SRS not support H.265, which is not list in Webrtc spec, but some implementation can support it.

And here is the codecs supported by webrtc, h.265(hevc) is not included.

HenryTree commented 2 months ago

https://github.com/ossrs/srs/blob/6bbd461ec960652c65deaaa9356d79fac691dd6d/trunk/src/app/srs_app_rtc_source.cpp#L1070-L1075

~H.265(HEVC) is not supported by WebRTC.~

It's SRS not support H.265, which is not list in Webrtc spec, but some implementation can support it.

And here is the codecs ~supported~ by webrtc, h.265(hevc) is not included.

Thanks a lot, it seems I have to find another way to deal with stream of h265 format .