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
25.16k stars 5.31k forks source link

The flv file recorded by SRS does not support skipping playback. #3698

Closed jiangbo closed 1 year ago

jiangbo commented 1 year ago

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

Description

Please provide a description of your issue here.

  1. SRS Version: 6.0.48

When using SRS, I am pushing the stream through RTMP and then recording it to generate an flv file. The file can be played normally, but it is not possible to click on any position on the progress bar to play, i.e., it does not support skipping playback.

  1. SRS Log:

There is no built-in log from SRS, and I have not seen any error messages. I have checked the metadata information of the recorded flv file, and the format is as follows:


Input #0, flv, from 'test.1689928615095.flv':
  Metadata:
    tb_dar          : 16:9
    metadatacreator : Yet Another Metadata Injector for FLV - Version 1.9
    canSeekToEnd    : false
    videosize       : 553363681
    audiosize       : 1578854
    lastkeyframetimestamp: 1759
    lastkeyframelocation: 552870749
    encoder         : Lavf57.83.100
    server          : SRS/6.0.48(Bee)
    server_version  : 6.0.48
    service         : SRS/6.0.48(Bee)
  Duration: 00:00:29.97, start: 0.066000, bitrate: 2546 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 2502 kb/s, 30 fps, 30 tbr, 1k tbn, 60 tbc
    Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 3 kb/s
File 'in.txt' already exists. Overwrite ? [y/N] y
Output #0, ffmetadata, to 'in.txt':
  Metadata:
    tb_dar          : 16:9
    metadatacreator : Yet Another Metadata Injector for FLV - Version 1.9
    canSeekToEnd    : false
    videosize       : 553363681
    audiosize       : 1578854
    lastkeyframetimestamp: 1759
    lastkeyframelocation: 552870749
    service         : SRS/6.0.48(Bee)
    server          : SRS/6.0.48(Bee)
    server_version  : 6.0.48
    encoder         : Lavf57.83.100
Stream mapping:
Press [q] to stop, [?] for help
size=       0kB time=-577014:32:22.77 bitrate=N/A speed=N/A
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded

After using yamdi -i test.1689928615095.flv -o frame.1689928615095.flv to repair it, the file can be played and skipped normally.


Input #0, flv, from 'frame.1689928615095.flv':
  Metadata:
    metadatacreator : Yet Another Metadata Injector for FLV - Version 1.9
    hasKeyframes    : true
    hasVideo        : true
    hasAudio        : true
    hasMetadata     : true
    canSeekToEnd    : true
    datasize        : 9538691
    videosize       : 9502733
    audiosize       : 26738
    lasttimestamp   : 30
    lastkeyframetimestamp: 30
    lastkeyframelocation: 9539410
  Duration: 00:00:29.97, start: 0.066000, bitrate: 2546 kb/s
    Stream #0:0: Video: h264 (High), yuv420p(tv, bt709, progressive), 1280x720 [SAR 1:1 DAR 16:9], 2534 kb/s, 30.10 fps, 30 tbr, 1k tbn, 60 tbc
    Stream #0:1: Audio: aac (LC), 48000 Hz, stereo, fltp, 3 kb/s
File 'in.txt' already exists. Overwrite ? [y/N] y
Output #0, ffmetadata, to 'in.txt':
  Metadata:
    metadatacreator : Yet Another Metadata Injector for FLV - Version 1.9
    hasKeyframes    : true
    hasVideo        : true
    hasAudio        : true
    hasMetadata     : true
    canSeekToEnd    : true
    datasize        : 9538691
    videosize       : 9502733
    audiosize       : 26738
    lasttimestamp   : 30
    lastkeyframetimestamp: 30
    lastkeyframelocation: 9539410
    encoder         : Lavf57.83.100
Stream mapping:
Press [q] to stop, [?] for help
size=       0kB time=-577014:32:22.77 bitrate=N/A speed=N/A
video:0kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
Output file is empty, nothing was encoded
  1. SRS Config:

# main config for srs.
# @see full.conf for detail config.

listen              1935;
max_connections     1000;
#srs_log_tank        file;
#srs_log_file        ./objs/srs.log;
daemon              on;
http_api {
    enabled         on;
    listen          1985;
}
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
rtc_server {
    enabled on;
    listen 8000; # UDP port
    # @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#config-candidate
    candidate $CANDIDATE;
}
vhost __defaultVhost__ {
    hls {
        enabled         on;
    }
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
    }
    rtc {
        enabled     on;
        # @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtmp-to-rtc
        rtmp_to_rtc on;
        # @see https://ossrs.net/lts/zh-cn/docs/v4/doc/webrtc#rtc-to-rtmp
        rtc_to_rtmp on;
    }

    dvr {
        enabled      on;
        dvr_path ./objs/nginx/html/dvr/[app]/[stream].[timestamp].flv;
    }

    play{
        gop_cache_max_frames 2500;
    }
}

Replay

Please describe how to replay the bug.

Step 1: Start SRS, configure DVR for recording, configure RTMP to RTC.

Step 2: Use ffmpeg for streaming.

ffmpeg -re -i test.flv -c copy -f flv rtmp://192.168.1.120/live/test

Step 3: Check that the flv file is missing metadata information and cannot be played by using the built-in nginx server.

Expect

Please describe your expectation.

Expect to be able to play the file normally and be able to click on the progress bar to jump to different positions for playback.

TRANS_BY_GPT3

winlinvip commented 1 year ago

Playing by jumping, essentially means clicking on the progress bar and jumping to a certain time. At this time, it is necessary to convert the time into file offset and use the HTTP range to return the data.

MP4 files support jumping because there is a corresponding relationship between time and offset in MP4, which can be achieved by combining with HTTP range requests.

FLV generally relies on metadata to inject the relationship between time and offset into the metadata. This data can be injected using ffmpeg.

Of course, FLV requires player support for this operation, not just server support. On the other hand, MP4 is naturally supported by browsers as a player.

TRANS_BY_GPT3