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.32k stars 5.33k forks source link

RTMP: Allow for extended pause durations or manage pausing through an API. #3547

Closed xiangzi1 closed 1 year ago

xiangzi1 commented 1 year ago

Note: Please read FAQ before file an issue, see #2716

Description

The client temporarily stops sending the stream to SRS. Due to the uncertainty of the pause time, if the time is too long, it may cause the SRS service to destroy the RTMP connection. Then, when requesting to push the stream to SRS again, an error occurs.

  1. SRS Version: v5.0.155

  2. SRS Log:

[2023-05-22 16:49:05.122][INFO][16][65ek65t4] RTMP client ip=10.67.65.194:37140, fd=13
[2023-05-22 16:49:05.122][INFO][16][65ek65t4] simple handshake success.
[2023-05-22 16:49:05.165][INFO][16][65ek65t4] connect app, tcUrl=rtmp://10.67.65.194/live, pageUrl=, swfUrl=, schema=rtmp, vhost=10.67.65.194, port=1935, app=live, args=null
[2023-05-22 16:49:05.165][INFO][16][65ek65t4] protocol in.buffer=0, in.ack=0, out.ack=0, in.chunk=128, out.chunk=128
[2023-05-22 16:49:05.210][INFO][16][65ek65t4] client identified, type=fmle-publish, vhost=10.67.65.194, app=live, stream=11020000001322000002_c85364876603474295de3b3545030fec2, param=, duration=0ms
[2023-05-22 16:49:05.210][INFO][16][65ek65t4] connected stream, tcUrl=rtmp://10.67.65.194/live, pageUrl=, swfUrl=, schema=rtmp, vhost=__defaultVhost__, port=1935, app=live, stream=11020000001322000002_c85364876603474295de3b3545030fec2, param=, args=null
[2023-05-22 16:49:05.210][INFO][16][65ek65t4] new live source, stream_url=/live/11020000001322000002_c85364876603474295de3b3545030fec2
[2023-05-22 16:49:05.211][INFO][16][65ek65t4] source url=/live/11020000001322000002_c85364876603474295de3b3545030fec2, ip=10.67.65.194, cache=1/2500, is_edge=0, source_id=/
[2023-05-22 16:49:05.254][INFO][16][65ek65t4] new rtc source, stream_url=/live/11020000001322000002_c85364876603474295de3b3545030fec2
[2023-05-22 16:49:05.256][INFO][16][65ek65t4] RTC bridge from RTMP, rtmp2rtc=1, keep_bframe=0, merge_nalus=0
[2023-05-22 16:49:05.256][INFO][16][65ek65t4] ignore disabled exec for vhost=__defaultVhost__
[2023-05-22 16:49:05.256][INFO][16][65ek65t4] http: mount flv stream for sid=/live/11020000001322000002_c85364876603474295de3b3545030fec2, mount=/live/11020000001322000002_c85364876603474295de3b3545030fec2.flv
[2023-05-22 16:49:05.257][INFO][16][65ek65t4] start publish mr=0/350, p1stpt=20000, pnt=60000, tcp_nodelay=0
[2023-05-22 16:49:05.459][INFO][16][k4a97351] RTC: start play url=/live/11020000001322000002_c85364876603474295de3b3545030fec2, source_id=65ek65t4/65ek65t4, realtime=1, mw_msgs=0
[2023-05-22 16:49:05.885][INFO][16][65ek65t4] 36B video sh,  codec(7, profile=Baseline, level=Other, 1920x1080, 0kbps, 0.0fps, 0.0s)
[2023-05-22 16:49:25.254][INFO][16][65ek65t4] <- CPB time=0, okbps=0,0,0, ikbps=0,0,0, mr=0/350, p1stpt=20000, pnt=60000
[2023-05-22 16:50:25.255][INFO][16][65ek65t4] cleanup when unpublish
[2023-05-22 16:50:25.256][INFO][16][65ek65t4] cleanup when unpublish, created=1, deliver=1
[2023-05-22 16:50:25.257][INFO][16][65ek65t4] TCP: before dispose resource(RtmpConn)(0x6120000904c0), conns=1, zombies=0, ign=0, inz=0, ind=0
[2023-05-22 16:50:25.257][ERROR][16][65ek65t4][4] serve error code=1011(SocketTimeout)(Socket io timeout) : service cycle : rtmp: stream service : rtmp: publish timeout 60000ms, nb_msgs=82
thread [16][65ek65t4]: do_cycle() [./src/app/srs_app_rtmp_conn.cpp:262][errno=4]
thread [16][65ek65t4]: service_cycle() [./src/app/srs_app_rtmp_conn.cpp:456][errno=4]
thread [16][65ek65t4]: do_publishing() [./src/app/srs_app_rtmp_conn.cpp:1035][errno=62](Interrupted system call)
[2023-05-22 16:50:25.257][INFO][16][65ek65t4] TCP: disposing #0 resource(RtmpConn)(0x6120000904c0), conns=1, disposing=1, zombies=0
  1. SRS Config:
# docker config for srs.
# @see full.conf for detail config.

listen              1935;
max_connections     1000;
# For docker, please use docker logs to manage the logs of SRS.
# See https://docs.docker.com/config/containers/logging/
srs_log_tank        console;
daemon              off;
http_api {
    enabled         on;
    listen          1985;
    raw_api {
        enabled             on;
        allow_reload        on;
    }
}
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
rtc_server {
    enabled on;
    listen 8000;
    # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
    candidate 10.67.65.194;
}
vhost __defaultVhost__ {
    http_hooks {
        enabled         on;
        on_play         http://10.67.65.194:13002/api/v1/sessions;
        on_stop         http://10.67.65.194:13002/api/v1/sessions;
    }
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
    }
    rtc {
        enabled     on;
        # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtmp-to-rtc
        rtmp_to_rtc on;
        # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#rtc-to-rtmp
        rtc_to_rtmp off;
        stun_timeout 5;
        stun_strict_check on;
    }
        publish {
        normal_timeout 60000;
    }
}

Replay

Please describe how to replay the bug?

Step 1: Request to play the recorded video.

Step 2: Use the pause function for the recording, and the client stops pushing the stream.

Step 3: If the pause time exceeds 1 minute, let the original client push the stream again.

Step 4: Pushing the stream results in an error (checking the SRS log, the RTMP stream is disconnected, and after exceeding the timeout, the SRS service actively destroys the connection).

Expect

Using RTMP to push the stream to SRS can achieve the pause function. There are many external requirements, and I hope the experts can adopt the implementation of this requirement. (Suggestion: Can the timeout of the RTMP stream be dynamically set by controlling the stream ID when the stream is paused? It can also be triggered by a hook to reset the timeout.)

winlinvip commented 1 year ago

Question

Requirement scenario: Implement the pause and resume function of recording on the web interface. The recording stream is pushed to SRS through RTMP, and the web interface pulls the stream from SRS through WebRTC. Problem description: When the recording is paused, the RTMP client will stop pushing the stream to SRS. SRS will clean up the RTMP push client due to timeout, causing the failure to resume playing the recording. Is there any way to keep the RTMP client alive and not be cleaned up?

Answer

Check the configuration, there is a maximum waiting time for pushing the stream, by default, it will kick if there is no stream for 5 seconds, you can set it to a larger value.

There is another solution, you can use FFmpeg to pull the stream and record it by yourself. In this way, users do not need to pause the stream, but keep pushing the stream. However, you can control when FFmpeg stops recording.

A similar solution can also be used with HLS callback. The stream is always being pushed, and after generating the slice, it will callback to your system. You can decide whether to copy the slice based on your own needs. If paused, do not copy.

There is another solution: you can use FFmpeg to pull the stream and record it yourself. This way, the user doesn't need to pause the stream push, but the stream is pushed continuously, and you can control when FFmpeg stops recording.

A similar solution can also be achieved using HLS callback. The stream is always being pushed, and after generating the slice, it will callback to your system. You can decide whether to copy the slice based on your own needs. If paused, don't copy the slice.