Stabilize live playback audio
Some checks are pending
ci-gates / checks (push) Waiting to run
deploy-cloudflare / checks (push) Waiting to run
deploy-cloudflare / deploy (push) Blocked by required conditions

This commit is contained in:
every.channel 2026-05-03 20:52:41 -07:00
parent 0d86104762
commit 64e5ee3965
No known key found for this signature in database
4 changed files with 122 additions and 6 deletions

View file

@ -751,14 +751,16 @@ async fn start_stream(
let stream_id_clone = stream_id.clone();
let output_dir_clone = output_dir.clone();
let app_clone = app.clone();
let variants = local_playback_cmaf_variants();
let process = tokio::task::spawn_blocking(move || {
spawn_ffmpeg_cmaf_ladder_for_source(
spawn_ffmpeg_cmaf_ladder_for_source_with_variants(
&app_clone,
&source,
&output_dir_clone,
DEFAULT_SEGMENT_MS,
6,
true,
variants,
)
})
.await
@ -3651,6 +3653,13 @@ fn default_cmaf_variants() -> Vec<CmafVariantSpec> {
]
}
fn local_playback_cmaf_variants() -> Vec<CmafVariantSpec> {
default_cmaf_variants()
.into_iter()
.filter(|variant| variant.id == "720p")
.collect()
}
fn write_hls_master_playlist(
output_dir: &Path,
variants: &[CmafVariantSpec],
@ -4730,6 +4739,26 @@ fn spawn_ffmpeg_cmaf_ladder_for_source(
chunk_ms: u64,
hls_list_size: usize,
delete_segments: bool,
) -> Result<Child> {
spawn_ffmpeg_cmaf_ladder_for_source_with_variants(
app,
source,
output_dir,
chunk_ms,
hls_list_size,
delete_segments,
default_cmaf_variants(),
)
}
fn spawn_ffmpeg_cmaf_ladder_for_source_with_variants(
app: &AppHandle,
source: &StreamSource,
output_dir: &Path,
chunk_ms: u64,
hls_list_size: usize,
delete_segments: bool,
variants: Vec<CmafVariantSpec>,
) -> Result<Child> {
if is_nbc_source(source) {
let reader = spawn_nbc_frame_reader(app, source)?;
@ -4739,6 +4768,7 @@ fn spawn_ffmpeg_cmaf_ladder_for_source(
chunk_ms,
hls_list_size,
delete_segments,
&variants,
);
}
@ -4748,6 +4778,7 @@ fn spawn_ffmpeg_cmaf_ladder_for_source(
chunk_ms,
hls_list_size,
delete_segments,
variants,
)
}
@ -4757,8 +4788,8 @@ fn spawn_ffmpeg_cmaf_ladder(
chunk_ms: u64,
hls_list_size: usize,
delete_segments: bool,
variants: Vec<CmafVariantSpec>,
) -> Result<Child> {
let variants = default_cmaf_variants();
let segment_time = format!("{:.3}", chunk_ms as f64 / 1000.0);
let _ = fs::remove_dir_all(output_dir);
@ -4802,17 +4833,17 @@ fn spawn_ffmpeg_cmaf_ladder_from_mjpeg_reader<R: Read + Send + 'static>(
chunk_ms: u64,
hls_list_size: usize,
delete_segments: bool,
variants: &[CmafVariantSpec],
) -> Result<Child> {
let segment_time = format!("{:.3}", chunk_ms as f64 / 1000.0);
let variants = default_cmaf_variants();
let _ = fs::remove_dir_all(output_dir);
fs::create_dir_all(output_dir)
.with_context(|| format!("failed to create {}", output_dir.display()))?;
for v in &variants {
for v in variants {
fs::create_dir_all(output_dir.join(v.id))?;
}
write_hls_master_playlist(output_dir, &variants, 0)?;
write_hls_master_playlist(output_dir, variants, 0)?;
spawn_ffmpeg_cmaf_ladder_with_input(
vec![
@ -4826,7 +4857,7 @@ fn spawn_ffmpeg_cmaf_ladder_from_mjpeg_reader<R: Read + Send + 'static>(
Some(Box::new(reader)),
output_dir,
&segment_time,
&variants,
variants,
hls_list_size,
delete_segments,
)
@ -5203,12 +5234,18 @@ fn default_encoder_args() -> Vec<&'static str> {
vec![
"-c:a",
"aac",
"-profile:a",
"aac_low",
"-b:a",
"128k",
"-ac",
"2",
"-ar",
"48000",
"-af",
ec_chopper::LIVE_AUDIO_RESAMPLE_FILTER,
"-max_muxing_queue_size",
"2048",
"-pix_fmt",
"yuv420p",
"-g",
@ -5321,6 +5358,28 @@ mod tests {
let _ = fs::remove_dir_all(&dir);
}
#[test]
fn local_playback_uses_single_720p_variant() {
let variants = local_playback_cmaf_variants();
assert_eq!(variants.len(), 1);
assert_eq!(variants[0].id, "720p");
assert_eq!(variants[0].video_bitrate_kbps, 3000);
}
#[test]
fn default_encoder_args_stabilize_live_audio() {
let args = default_encoder_args();
assert!(args
.windows(2)
.any(|w| w[0] == "-profile:a" && w[1] == "aac_low"));
assert!(args
.windows(2)
.any(|w| w[0] == "-af" && w[1] == ec_chopper::LIVE_AUDIO_RESAMPLE_FILTER));
assert!(args
.windows(2)
.any(|w| w[0] == "-max_muxing_queue_size" && w[1] == "2048"));
}
#[test]
fn derive_variant_stream_id_is_stable() {
assert_eq!(