From b4836f3abb82bda8f763bdb93cf08b069ae66a59 Mon Sep 17 00:00:00 2001 From: Scott Lamb Date: Tue, 28 Jan 2025 09:04:59 -0800 Subject: [PATCH] v0.7.18: support H.265 There's no transcoding, so if the browser/player doesn't support these formats, they don't play. But it will record and allow downloads, and it seems to be working with Chrome on macOS at least. Fixes #33 --- CHANGELOG.md | 4 +++- server/Cargo.lock | 26 ++++++++++++-------------- server/Cargo.toml | 4 ++-- server/db/upgrade/v5_to_v6.rs | 2 +- server/src/stream.rs | 6 ++++-- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ac62f7f..40e3b16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,8 +8,10 @@ upgrades, e.g. `v0.6.x` -> `v0.7.x`. The config file format and [API](ref/api.md) currently have no stability guarantees, so they may change even on minor releases, e.g. `v0.7.5` -> `v0.7.6`. -## unreleased +## v0.7.18 (2025-01-28) +* support recording H.265 ([#33](https://github.com/scottlamb/moonfire-nvr/issues/33)). + Browser support may vary. * bump minimum Rust version to 1.82. * improve error message on timeout opening stream. * use `jiff` for time manipulations. diff --git a/server/Cargo.lock b/server/Cargo.lock index 6a55956..3ef3dcc 100644 --- a/server/Cargo.lock +++ b/server/Cargo.lock @@ -98,9 +98,9 @@ checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" [[package]] name = "bitstream-io" -version = "1.10.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e445576659fd04a57b44cbd00aa37aaa815ebefa0aa3cb677a6b5e63d883074f" +checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2" [[package]] name = "blake3" @@ -536,9 +536,9 @@ dependencies = [ [[package]] name = "four-cc" -version = "0.1.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3958af68a31b1d1384d3f39b6aa33eb14b6009065b5ca305ddd9712a4237124f" +checksum = "795cbfc56d419a7ce47ccbb7504dd9a5b7c484c083c356e797de08bd988d9629" [[package]] name = "futures" @@ -658,9 +658,9 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "h264-reader" -version = "0.7.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd118dcc322cc71cfc33254a19ebece92cfaaf6d4b4793fec3f7f44fbc4150df" +checksum = "036a78b2620d92f0ec57690bc792b3bb87348632ee5225302ba2e66a48021c6c" dependencies = [ "bitstream-io", "hex-slice", @@ -1346,9 +1346,9 @@ dependencies = [ [[package]] name = "mp4ra-rust" -version = "0.1.0" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be9daf03b43bf3842962947c62ba40f411e46a58774c60838038f04a67d17626" +checksum = "fdbc3d3867085d66ac6270482e66f3dd2c5a18451a3dc9ad7269e94844a536b7" dependencies = [ "four-cc", ] @@ -1826,9 +1826,9 @@ dependencies = [ [[package]] name = "retina" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d83a8e0892d8e0836cd9be6cc413ab3f1c574276e047ac6e27e3027832d00e" +checksum = "2135e9c5a2ffcab6428221605faa39f1cca4bef6fc5756dbfd02ab57cf68f670" dependencies = [ "base64", "bitstream-io", @@ -1840,7 +1840,6 @@ dependencies = [ "jiff", "log", "memchr", - "once_cell", "pin-project", "pretty-hex", "rand", @@ -1855,11 +1854,10 @@ dependencies = [ [[package]] name = "rfc6381-codec" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4395f46a67f0d57c57f6a5361f3a9a0c0183a19cab3998892ecdc003de6d8037" +checksum = "ed54c20f5c3ec82eab6d998b313dc75ec5d5650d4f57675e61d72489040297fd" dependencies = [ - "four-cc", "mp4ra-rust", "mpeg4-audio-const", ] diff --git a/server/Cargo.toml b/server/Cargo.toml index 9299818..5d0b6af 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -24,7 +24,7 @@ members = ["base", "db"] [workspace.dependencies] base64 = "0.22.0" -h264-reader = "0.7.0" +h264-reader = "0.8.0" itertools = "0.12.0" jiff = "0.1.8" nix = "0.27.0" @@ -62,7 +62,7 @@ password-hash = "0.5.0" pretty-hex = { workspace = true } protobuf = "3.0" reffers = "0.7.0" -retina = "0.4.11" +retina = "0.4.12" ring = { workspace = true } rusqlite = { workspace = true } serde = { version = "1.0", features = ["derive"] } diff --git a/server/db/upgrade/v5_to_v6.rs b/server/db/upgrade/v5_to_v6.rs index c3c215f..64b4f28 100644 --- a/server/db/upgrade/v5_to_v6.rs +++ b/server/db/upgrade/v5_to_v6.rs @@ -133,7 +133,7 @@ pub fn run(_args: &super::Args, tx: &rusqlite::Transaction) -> Result<(), Error> ) })?; let sps = ctx - .sps_by_id(h264_reader::nal::pps::ParamSetId::from_u32(0).unwrap()) + .sps_by_id(h264_reader::nal::sps::SeqParamSetId::from_u32(0).unwrap()) .ok_or_else(|| { err!( Unimplemented, diff --git a/server/src/stream.rs b/server/src/stream.rs index 923b3b9..101e010 100644 --- a/server/src/stream.rs +++ b/server/src/stream.rs @@ -170,7 +170,7 @@ fn params_to_sample_entry( .with_aspect_ratio(aspect) .build() .map_err(|e| err!(Unknown, source(e)))?, - rfc6381_codec: "avc1.4d401e".to_string(), + rfc6381_codec: params.rfc6381_codec().to_owned(), width, height, pasp_h_spacing: aspect.0, @@ -192,7 +192,9 @@ impl RetinaStreamInner { let video_i = session .streams() .iter() - .position(|s| s.media() == "video" && matches!(s.encoding_name(), "h264" | "jpeg")) + .position(|s| { + s.media() == "video" && matches!(s.encoding_name(), "h264" | "h265" | "jpeg") + }) .ok_or_else(|| { err!( FailedPrecondition,