fix: recording

closes #9
This commit is contained in:
2025-06-20 10:30:22 +01:00
parent aea0feef05
commit b1ebf75244
3 changed files with 21 additions and 9 deletions

View File

@ -1,6 +1,7 @@
use anyhow::Result;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPacket;
use ffmpeg_rs_raw::{Encoder, Muxer};
use log::info;
use std::collections::HashMap;
use std::fs;
use std::path::PathBuf;
@ -21,7 +22,7 @@ impl RecorderEgress {
out_dir: PathBuf,
variants: impl Iterator<Item = (&'a VariantStream, &'a Encoder)>,
) -> Result<Self> {
let out_file = out_dir.join("recording.ts");
let out_file = out_dir.join("recording.mp4");
let mut var_map = HashMap::new();
let muxer = unsafe {
let mut m = Muxer::builder()
@ -31,7 +32,10 @@ impl RecorderEgress {
let stream = m.add_stream_encoder(enc)?;
var_map.insert(var.id(), (*stream).index);
}
m.open(None)?;
let mut options = HashMap::new();
options.insert("movflags".to_string(), "faststart".to_string());
m.open(Some(options))?;
m
};
Ok(Self { muxer, var_map })

View File

@ -22,8 +22,8 @@ use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVCodecID::AV_CODEC_ID_WEBP;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPictureType::AV_PICTURE_TYPE_NONE;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPixelFormat::AV_PIX_FMT_YUV420P;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::{
av_frame_clone, av_frame_free, av_get_sample_fmt, av_packet_free, av_rescale_q, AVFrame,
AVPacket, AV_NOPTS_VALUE,
av_frame_clone, av_frame_free, av_get_sample_fmt, av_packet_clone, av_packet_free,
av_rescale_q, AVFrame, AVPacket, AV_NOPTS_VALUE,
};
use ffmpeg_rs_raw::{
cstr, get_frame_from_hw, AudioFifo, Decoder, Demuxer, Encoder, Resample, Scaler, StreamType,
@ -529,7 +529,8 @@ impl PipelineRunner {
// pass new packets to egress
for mut pkt in packets {
for eg in egress.iter_mut() {
let er = eg.process_pkt(pkt, &var.id())?;
let pkt_clone = av_packet_clone(pkt);
let er = eg.process_pkt(pkt_clone, &var.id())?;
ret.push(er);
}
av_packet_free(&mut pkt);

View File

@ -378,10 +378,17 @@ impl Overseer for ZapStreamOverseer {
_ => false,
});
match var {
Some(var) => egress.push(EgressType::Recorder(EgressConfig {
name: "dvr".to_string(),
variants: [var.id()].into(),
})),
Some(var) => {
// take all streams in the same group as the matching video resolution (video+audio)
let vars_in_group = cfg
.variants
.iter()
.filter(|v| v.group_id() == var.group_id());
egress.push(EgressType::Recorder(EgressConfig {
name: "dvr".to_string(),
variants: vars_in_group.map(|v| v.id()).collect(),
}))
}
None => {
warn!(
"Invalid DVR config, no variant found with height {}",