fix(recording): remux bbb-webrtc-recorder and KMS files during archive

Kurento may *rarely* generate WebM/MKV files with corrupt or absent
SeekHead sectors. bbb-webrtc-recorder also doesn't generate SeekHead or
even the Cues sectors by default.

While those are are *optional* fields by spec, files need to be seekable
for our recording processing scripts to work.

This commit adds a remuxing step for Kurento and bbb-webrtc-recorder raw
files that is executed during the archive phase. It should re-include
any of the missing fields that make files seekable and restore the Cues
sector in WebM files.
This commit is contained in:
prlanzarin 2023-08-15 22:03:09 -03:00
parent d6316aa213
commit bba4658dd3

View File

@ -111,6 +111,37 @@ def delete_audio(meeting_id, audio_dir)
end
end
def remux_and_archive(source_dir, dest_dir)
files = Dir.glob("#{source_dir}/*")
if files.empty?
BigBlueButton.logger.warn("No media files found in #{source_dir}")
return
end
BigBlueButton.logger.info("Remuxing and archiving files at #{source_dir}")
FileUtils.mkdir_p(dest_dir)
files .each do |file|
ext = File.extname(file)
next if ext.empty?
# These can potentially be webm (VP8/VP9), mp4 (H.264), or mkv (VP8/VP9/H.264)
output_basename = File.join(dest_dir, File.basename(file, ext))
format = {
extension: ext.delete_prefix('.'),
parameters: [
%w[-c copy],
]
}
BigBlueButton::EDL.encode(
nil,
file,
format,
output_basename
)
end
end
def archive_directory(source, dest)
BigBlueButton.logger.info("Archiving contents of #{source}")
FileUtils.mkdir_p(dest)
@ -207,14 +238,14 @@ archive_notes(meeting_id, notes_endpoint, notes_formats, raw_archive_dir)
# Presentation files
archive_directory("#{presentation_dir}/#{meeting_id}/#{meeting_id}", "#{target_dir}/presentation")
# Kurento media
archive_directory("#{kurento_screenshare_dir}/#{meeting_id}", "#{target_dir}/deskshare")
archive_directory("#{kurento_video_dir}/#{meeting_id}", "#{target_dir}/video/#{meeting_id}")
remux_and_archive("#{kurento_screenshare_dir}/#{meeting_id}", "#{target_dir}/deskshare")
remux_and_archive("#{kurento_video_dir}/#{meeting_id}", "#{target_dir}/video/#{meeting_id}")
# mediasoup media
archive_directory("#{mediasoup_screenshare_dir}/#{meeting_id}", "#{target_dir}/deskshare")
archive_directory("#{mediasoup_video_dir}/#{meeting_id}", "#{target_dir}/video/#{meeting_id}")
# bbb-webrtc-recorder media
archive_directory("#{webrtc_recorder_screenshare_dir}/#{meeting_id}", "#{target_dir}/deskshare")
archive_directory("#{webrtc_recorder_video_dir}/#{meeting_id}", "#{target_dir}/video/#{meeting_id}")
remux_and_archive("#{webrtc_recorder_screenshare_dir}/#{meeting_id}", "#{target_dir}/deskshare")
remux_and_archive("#{webrtc_recorder_video_dir}/#{meeting_id}", "#{target_dir}/video/#{meeting_id}")
# If this was the last (or only) segment in a recording, delete the original media files
if break_timestamp.nil?