1. The background
Realize the video recording function in SRS.
2. The train of thought
Solution 1: Real-time mode
- Photo taking: The operator clicks the photo button to trigger a network request. After receiving the request, the back end starts an FFMPEG command line to take a screenshot.
- Recording: The operator clicks the “Start recording” button to trigger a network request. After receiving the request, the back end starts an FFMPEG command line recording. The recording is completed after the operator clicks the “End recording” button.
- Advantages: Easy to implement
- Disadvantages: delay of operation and response, that is, after clicking the button, there is about 2-5 seconds delay (network response time + FFMPEG start time + FFMPEG open stream time + FFMPEG photo response time). Controversy: See the current playing content of the video (time)! = Button click time! = ffmpeg photo time
Scheme 2: DVR recording after taking pictures and interception
- Premise: With DVR enabled, each stream released from the client is recorded and segmtioned into multiple physical files over time. Then file screenshots and video intercepts can be manipulated.
- Take photos: Click the button to get the click time, identify the file name (including the time) from the completed DVR file, and take screenshots according to the specified time difference after reading the file.
- Recording: Obtain the start time and end time of recording. Identify the file name (including the time) from the completed DVR file and read the screenshot of the time period during which the file was captured.
- Scheme advantage: Compared with scheme 1, the delay of time error is small.
- Disadvantages: It depends on the DVR recorded file. Need to consider the cleaning and disposal of DVR temporary recording files.
3. The implementation
DVR video recording: SRS supports recording RTMP streams as FLV or MP4 files. The following description uses FLV as an example.
vhost your_vhost { # DVR RTMP stream to file, # start to record to file when encoder publish, # reap flv/mp4 according by specified dvr_plan. dvr { # whether enabled dvr features # default: off enabled on; # the filter for dvr to apply to. # all, dvr all streams of all apps. # <app>/<stream>, apply to specified stream of app. # for example, to dvr the following two streams: # live/stream1 live/stream2 # default: all dvr_apply all; # the dvr plan. canbe: # session reap flv/mp4 when session end(unpublish). # segment reap flv/mp4 when flv duration exceed the specified dvr_duration. # @remark The plan append is removed in SRS3+, for it's no use. # default: session dvr_plan session; # the dvr output path, *.flv or *.mp4. # we supports some variables to generate the filename. # [vhost], the vhost of stream. # [app], the app of stream. # [stream], the stream name of stream. # [2006], replace this const to current year. # [01], replace this const to current month. # [02], replace this const to current date. # [15], replace this const to current hour. # [04], replace this const to current minute. # [05], replace this const to current second. # [999], replace this const to current millisecond. # [timestamp],replace this const to current UNIX timestamp in ms. # @remark We use golang time format "2006-01-02 15:04:05.999" as "[2006]-[01]-[02]_[15].[04]. For the url rtmp://ossrs.net/live/livestream and the time the 2015-01-03 10:57:30. 776 # 1. No variables, Rule of SRS1.0(auto add [stream].[timestamp].flv as filename): # dvr_path./objs/nginx/ HTML; # => # dvr_path ./objs/nginx/html/live/livestream.1420254068776.flv; # 2. Use stream and date as dir name, time as filename: # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv; # # = > dvr_path/data/ossrs.net/live/livestream/2015/01/03/10.57.30.776.flv; # 3. Use stream and year/month as dir name, date and time as filename: # dvr_path /data/[vhost]/[app]/[stream]/[2006]/[01]/[02]-[15].[04].[05].[999].flv; # # = > dvr_path/data/ossrs.net/live/livestream/2015/01/03-10.57.30.776.flv; # 4. Use vhost/app and year/month as dir name, stream/date/time as filename: # dvr_path /data/[vhost]/[app]/[2006]/[01]/[stream]-[02]-[15].[04].[05].[999].flv; # # = > dvr_path/data/ossrs.net/live/2015/01/livestream-03-10.57.30.776.flv; # 5. DVR to mp4: # dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].mp4; # => # dvr_path ./objs/nginx/html/live/livestream.1420254068776.mp4; # @see https://github.com/ossrs/srs/wiki/v3_CN_DVR#custom-path # @see https://github.com/ossrs/srs/wiki/v3_CN_DVR#custom-path # segment,session apply it. # default: ./objs/nginx/html/[app]/[stream].[timestamp].flv dvr_path ./objs/nginx/html/[app]/[stream].[timestamp].flv; # the duration for dvr file, reap if exceed, in seconds. # segment apply it. # session,append ignore. # default: 30 dvr_duration 30; # whether wait keyframe to reap segment, # if off, reap segment when duration exceed the dvr_duration, # if on, reap segment when duration exceed and got keyframe. # segment apply it. # session,append ignore. # default: on dvr_wait_keyframe on; # about the stream monotonically increasing: # 1. video timestamp is monotonically increasing, # 2. audio timestamp is monotonically increasing, # 3. video and audio timestamp is interleaved monotonically increasing. # it's specified by RTMP specification, @see 3. Byte Order, Alignment, and Time Format # however, some encoder cannot provides this feature, please set this to off to ignore time jitter. # the time jitter algorithm: # 1. full, to ensure stream start at zero, and ensure stream monotonically increasing. # 2. zero, only ensure stream start at zero, ignore timestamp jitter. # 3. off, disable the time jitter algorithm, like atc. # apply for all dvr plan. # default: full time_jitter full; # on_dvr, never config in here, should config in http_hooks. # for the dvr http callback, @see http_hooks.on_dvr of vhost hooks.callback.srs.com # @read https://github.com/ossrs/srs/wiki/v3_CN_DVR#http-callback # @read https://github.com/ossrs/srs/wiki/v3_CN_DVR#http-callback } }Copy the code
You still need to configure HTTP callbacks
vhost your_vhost { dvr { enabled on; dvr_path ./objs/nginx/html/[app]/[stream]/[2006]/[01]/[02]/[15].[04].[05].[999].flv; dvr_plan segment; dvr_duration 30; dvr_wait_keyframe on; } http_hooks { enabled on; On_dvr http://127.0.0.1:8085/api/v1/dvrs; }}Copy the code
The recorded file path is received via an HTTP callback
[2015-01-03 15:25:48][trace] post to dvrs, The req = {" action ":" on_dvr ", "client_id:" 108, "IP" : "127.0.0.1", "vhost" : "__defaultVhost__", "app" : "live", "stream" : "livestream", "c Wd ":"/home/winlin/git/SRS/trunk ", "file" : ". / objs/nginx/HTML/live/livestream / 2015/1/3/15.25.18.442. FLV}"Copy the code
4. Reference
Gitee.com/winlinvip/s…