RaP: Workaround broken seeking in flv after red5 update.

Since the update to the newer red5, seeking in flv files (webcams in
particular are noticable) has been broken, resulting in cameras
appearing to "hang" any time there is a cut in the generated video -
which happens when start/stop button is pushed, or when cameras are
added or removed.

We can detect the problematic video files because the timestamp of the
first frame is large (old red5 versions always set first frame
timestamp to 0.001 seconds). If we see a file like this, having ffmpeg
remux the file - rewriting the timestamps and index - works around the
problem.
This commit is contained in:
Calvin Walton 2018-05-30 11:41:45 -04:00
parent db6b2a18f5
commit 4554e3eac7

View File

@ -171,6 +171,7 @@ module BigBlueButton
videoinfo = {} videoinfo = {}
corrupt_videos = Set.new corrupt_videos = Set.new
remux_flv_videos = Set.new
BigBlueButton.logger.info "Pre-processing EDL" BigBlueButton.logger.info "Pre-processing EDL"
for i in 0...(edl.length - 1) for i in 0...(edl.length - 1)
@ -196,12 +197,50 @@ module BigBlueButton
BigBlueButton.logger.debug " width: #{info[:width]}, height: #{info[:height]}, duration: #{info[:duration]}, start_time: #{info[:start_time]}" BigBlueButton.logger.debug " width: #{info[:width]}, height: #{info[:height]}, duration: #{info[:duration]}, start_time: #{info[:start_time]}"
if info[:video][:deskshare_timestamp_bug] if info[:video][:deskshare_timestamp_bug]
BigBlueButton.logger.debug(" has early 1.1 deskshare timestamp bug") BigBlueButton.logger.debug(" has early 1.1 deskshare timestamp bug")
elsif info[:format][:format_name] == 'flv' and info[:start_time] > Rational(1,1000)
BigBlueButton.logger.debug(" has large start time, needs remuxing")
remux_flv_videos << videofile
end end
end end
videoinfo[videofile] = info videoinfo[videofile] = info
end end
if remux_flv_videos.length > 0
BigBlueButton.logger.info("Remuxing flv files with large start time")
remux_flv_videos.each do |videofile|
BigBlueButton.logger.info(" #{File.basename(videofile)}")
newvideofile = File.join(File.dirname(output_basename), File.basename(videofile))
if !File.exist?(newvideofile)
ffmpeg_cmd = [*FFMPEG]
ffmpeg_cmd += ['-i', videofile, '-c', 'copy', newvideofile]
exitstatus = BigBlueButton.exec_ret(*ffmpeg_cmd)
raise "ffmpeg failed, exit code #{exitstatus}" if exitstatus != 0
end
info = video_info(newvideofile)
if !info[:video]
BigBlueButton.logger.warn(" Result of remux is corrupt, not using it.")
next
end
BigBlueButton.logger.debug " width: #{info[:width]}, height: #{info[:height]}, duration: #{info[:duration]}, start_time: #{info[:start_time]}"
videoinfo[newvideofile] = info
# Update the filename in the EDL
edl.each do |event|
event[:areas].each do |area, videos|
videos.each do |video|
if video[:filename] == videofile
video[:filename] = newvideofile
end
end
end
end
end
end
if corrupt_videos.length > 0 if corrupt_videos.length > 0
BigBlueButton.logger.info "Removing corrupt video files from EDL" BigBlueButton.logger.info "Removing corrupt video files from EDL"
edl.each do |event| edl.each do |event|
@ -389,7 +428,7 @@ module BigBlueButton
BigBlueButton.logger.debug " offset: left: #{offset_x}, top: #{offset_y}" BigBlueButton.logger.debug " offset: left: #{offset_x}, top: #{offset_y}"
BigBlueButton.logger.debug(" start timestamp: #{video[:timestamp]}") BigBlueButton.logger.debug(" start timestamp: #{video[:timestamp]}")
seek_offset = this_videoinfo[:video][:start_time] seek_offset = this_videoinfo[:start_time]
BigBlueButton.logger.debug(" seek offset: #{seek_offset}") BigBlueButton.logger.debug(" seek offset: #{seek_offset}")
BigBlueButton.logger.debug(" codec: #{this_videoinfo[:video][:codec_name].inspect}") BigBlueButton.logger.debug(" codec: #{this_videoinfo[:video][:codec_name].inspect}")
BigBlueButton.logger.debug(" duration: #{this_videoinfo[:duration]}, original duration: #{video[:original_duration]}") BigBlueButton.logger.debug(" duration: #{this_videoinfo[:duration]}, original duration: #{video[:original_duration]}")