fix client side record

Signed-off-by: 21pages <pages21@163.com>
This commit is contained in:
21pages
2023-10-18 22:39:28 +08:00
parent 510cffb305
commit 7a5bc864fa
10 changed files with 119 additions and 59 deletions

View File

@@ -49,8 +49,8 @@ impl RecorderContext {
}
let file = if self.server { "s" } else { "c" }.to_string()
+ &self.id.clone()
+ &chrono::Local::now().format("_%Y%m%d%H%M%S_").to_string()
+ &self.format.to_string()
+ &chrono::Local::now().format("_%Y%m%d%H%M%S%3f_").to_string()
+ &self.format.to_string().to_lowercase()
+ if self.format == CodecFormat::VP9
|| self.format == CodecFormat::VP8
|| self.format == CodecFormat::AV1
@@ -86,6 +86,7 @@ pub enum RecordState {
pub struct Recorder {
pub inner: Box<dyn RecorderApi>,
ctx: RecorderContext,
pts: Option<i64>,
}
impl Deref for Recorder {
@@ -109,11 +110,13 @@ impl Recorder {
CodecFormat::VP8 | CodecFormat::VP9 | CodecFormat::AV1 => Recorder {
inner: Box::new(WebmRecorder::new(ctx.clone())?),
ctx,
pts: None,
},
#[cfg(feature = "hwcodec")]
_ => Recorder {
inner: Box::new(HwRecorder::new(ctx.clone())?),
ctx,
pts: None,
},
#[cfg(not(feature = "hwcodec"))]
_ => bail!("unsupported codec type"),
@@ -134,6 +137,7 @@ impl Recorder {
_ => bail!("unsupported codec type"),
};
self.ctx = ctx;
self.pts = None;
self.send_state(RecordState::NewFile(self.ctx.filename.clone()));
Ok(())
}
@@ -155,7 +159,10 @@ impl Recorder {
..self.ctx.clone()
})?;
}
vp8s.frames.iter().map(|f| self.write_video(f)).count();
for f in vp8s.frames.iter() {
self.check_pts(f.pts)?;
self.write_video(f);
}
}
video_frame::Union::Vp9s(vp9s) => {
if self.ctx.format != CodecFormat::VP9 {
@@ -164,7 +171,10 @@ impl Recorder {
..self.ctx.clone()
})?;
}
vp9s.frames.iter().map(|f| self.write_video(f)).count();
for f in vp9s.frames.iter() {
self.check_pts(f.pts)?;
self.write_video(f);
}
}
video_frame::Union::Av1s(av1s) => {
if self.ctx.format != CodecFormat::AV1 {
@@ -173,7 +183,10 @@ impl Recorder {
..self.ctx.clone()
})?;
}
av1s.frames.iter().map(|f| self.write_video(f)).count();
for f in av1s.frames.iter() {
self.check_pts(f.pts)?;
self.write_video(f);
}
}
#[cfg(feature = "hwcodec")]
video_frame::Union::H264s(h264s) => {
@@ -183,8 +196,9 @@ impl Recorder {
..self.ctx.clone()
})?;
}
if self.ctx.format == CodecFormat::H264 {
h264s.frames.iter().map(|f| self.write_video(f)).count();
for f in h264s.frames.iter() {
self.check_pts(f.pts)?;
self.write_video(f);
}
}
#[cfg(feature = "hwcodec")]
@@ -195,8 +209,9 @@ impl Recorder {
..self.ctx.clone()
})?;
}
if self.ctx.format == CodecFormat::H265 {
h265s.frames.iter().map(|f| self.write_video(f)).count();
for f in h265s.frames.iter() {
self.check_pts(f.pts)?;
self.write_video(f);
}
}
_ => bail!("unsupported frame type"),
@@ -205,6 +220,17 @@ impl Recorder {
Ok(())
}
fn check_pts(&mut self, pts: i64) -> ResultType<()> {
// https://stackoverflow.com/questions/76379101/how-to-create-one-playable-webm-file-from-two-different-video-tracks-with-same-c
let old_pts = self.pts;
self.pts = Some(pts);
if old_pts.clone().unwrap_or_default() > pts {
log::info!("pts {:?}->{}, change record filename", old_pts, pts);
self.change(self.ctx.clone())?;
}
Ok(())
}
fn send_state(&self, state: RecordState) {
self.ctx.tx.as_ref().map(|tx| tx.send(state));
}
@@ -250,7 +276,9 @@ impl RecorderApi for WebmRecorder {
if ctx.format == CodecFormat::AV1 {
// [129, 8, 12, 0] in 3.6.0, but zero works
let codec_private = vec![0, 0, 0, 0];
webm.set_codec_private(vt.track_number(), &codec_private);
if !webm.set_codec_private(vt.track_number(), &codec_private) {
bail!("Failed to set codec private");
}
}
Ok(WebmRecorder {
vt,