mirror of
https://github.com/rustdesk/rustdesk.git
synced 2026-04-10 14:11:29 +03:00
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user