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 anyhow::Result;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPacket; use ffmpeg_rs_raw::ffmpeg_sys_the_third::AVPacket;
use ffmpeg_rs_raw::{Encoder, Muxer}; use ffmpeg_rs_raw::{Encoder, Muxer};
use log::info;
use std::collections::HashMap; use std::collections::HashMap;
use std::fs; use std::fs;
use std::path::PathBuf; use std::path::PathBuf;
@ -21,7 +22,7 @@ impl RecorderEgress {
out_dir: PathBuf, out_dir: PathBuf,
variants: impl Iterator<Item = (&'a VariantStream, &'a Encoder)>, variants: impl Iterator<Item = (&'a VariantStream, &'a Encoder)>,
) -> Result<Self> { ) -> 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 mut var_map = HashMap::new();
let muxer = unsafe { let muxer = unsafe {
let mut m = Muxer::builder() let mut m = Muxer::builder()
@ -31,7 +32,10 @@ impl RecorderEgress {
let stream = m.add_stream_encoder(enc)?; let stream = m.add_stream_encoder(enc)?;
var_map.insert(var.id(), (*stream).index); 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 m
}; };
Ok(Self { muxer, var_map }) 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::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::AVPixelFormat::AV_PIX_FMT_YUV420P;
use ffmpeg_rs_raw::ffmpeg_sys_the_third::{ 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, av_frame_clone, av_frame_free, av_get_sample_fmt, av_packet_clone, av_packet_free,
AVPacket, AV_NOPTS_VALUE, av_rescale_q, AVFrame, AVPacket, AV_NOPTS_VALUE,
}; };
use ffmpeg_rs_raw::{ use ffmpeg_rs_raw::{
cstr, get_frame_from_hw, AudioFifo, Decoder, Demuxer, Encoder, Resample, Scaler, StreamType, cstr, get_frame_from_hw, AudioFifo, Decoder, Demuxer, Encoder, Resample, Scaler, StreamType,
@ -529,7 +529,8 @@ impl PipelineRunner {
// pass new packets to egress // pass new packets to egress
for mut pkt in packets { for mut pkt in packets {
for eg in egress.iter_mut() { 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); ret.push(er);
} }
av_packet_free(&mut pkt); av_packet_free(&mut pkt);

View File

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