archive replay: fall back to first segment when init track is absent

This commit is contained in:
every.channel 2026-02-24 03:28:23 -08:00
parent 16c5b28ee4
commit b570175e35
No known key found for this signature in database

View file

@ -5534,13 +5534,25 @@ fn build_hls_segments(records: &[ArchiveIndexRecord]) -> Vec<ArchiveHlsSegment>
out
}
fn latest_init_hash(manifest_root: &Path, broadcast_name: &str) -> Result<Option<String>> {
fn latest_init_hash(
manifest_root: &Path,
broadcast_name: &str,
fallback_track: &str,
) -> Result<Option<String>> {
let mut init_records = dedupe_by_group_sequence(read_archive_records(
manifest_root,
broadcast_name,
"init.mp4",
)?);
Ok(init_records.pop().map(|record| record.blake3))
if let Some(record) = init_records.pop() {
return Ok(Some(record.blake3));
}
let fallback = dedupe_by_group_sequence(read_archive_records(
manifest_root,
broadcast_name,
fallback_track,
)?);
Ok(fallback.first().map(|record| record.blake3.clone()))
}
fn parse_limit(url: &Url) -> Option<usize> {
@ -5762,7 +5774,8 @@ fn handle_archive_http_request(
)
}
"video.m3u8" if parts.len() == 3 => {
let init_hash = match latest_init_hash(&state.manifest_root, &broadcast_name) {
let init_hash =
match latest_init_hash(&state.manifest_root, &broadcast_name, "video0.m4s") {
Ok(Some(hash)) => hash,
Ok(None) => return archive_error(404, "missing init segment"),
Err(err) => return archive_error(500, &format!("{err:#}")),
@ -5789,7 +5802,8 @@ fn handle_archive_http_request(
)
}
"audio.m3u8" if parts.len() == 3 => {
let init_hash = match latest_init_hash(&state.manifest_root, &broadcast_name) {
let init_hash =
match latest_init_hash(&state.manifest_root, &broadcast_name, "audio0.m4s") {
Ok(Some(hash)) => hash,
Ok(None) => return archive_error(404, "missing init segment"),
Err(err) => return archive_error(500, &format!("{err:#}")),
@ -5821,7 +5835,12 @@ fn handle_archive_http_request(
.find(|(k, _)| k == "hash")
.map(|(_, v)| v.to_string())
.or_else(|| {
latest_init_hash(&state.manifest_root, &broadcast_name)
latest_init_hash(&state.manifest_root, &broadcast_name, "video0.m4s")
.ok()
.flatten()
})
.or_else(|| {
latest_init_hash(&state.manifest_root, &broadcast_name, "audio0.m4s")
.ok()
.flatten()
});