mirror of
https://github.com/scottlamb/moonfire-nvr.git
synced 2025-04-16 09:08:01 -04:00
upgrade to Retina v0.3.9
This alone improves interop and diagnostics, as noted in Retina's release notes. We also now give the camera name to the session group (for improved logging of TEARDOWN operations) and expose the RTSP server's "tool" attribute in debug logs and the config UI's "Test" button. Fixes #209 Fixes #213
This commit is contained in:
parent
3bc410b417
commit
5e7d558f99
@ -6,6 +6,10 @@ changes, see Git history.
|
|||||||
Each release is tagged in Git and on the Docker repository
|
Each release is tagged in Git and on the Docker repository
|
||||||
[`scottlamb/moonfire-nvr`](https://hub.docker.com/r/scottlamb/moonfire-nvr).
|
[`scottlamb/moonfire-nvr`](https://hub.docker.com/r/scottlamb/moonfire-nvr).
|
||||||
|
|
||||||
|
## unreleased
|
||||||
|
|
||||||
|
* upgrade to Retina 0.3.9, improving camera interop and diagnostics
|
||||||
|
|
||||||
## `v0.7.3` (2022-03-22)
|
## `v0.7.3` (2022-03-22)
|
||||||
|
|
||||||
* security fix: check the `Origin` header on live stream WebSocket requests
|
* security fix: check the `Origin` header on live stream WebSocket requests
|
||||||
|
4
server/Cargo.lock
generated
4
server/Cargo.lock
generated
@ -1640,9 +1640,9 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "retina"
|
name = "retina"
|
||||||
version = "0.3.8"
|
version = "0.3.9"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3629d5f6a30d1a0ee184bd2a3e62eba8ffbb121250a8c72ed984575c9ffb0601"
|
checksum = "df90aca400866f8b1327902f7c9e93ab17f195c36b7e06b804e8acd3a79bbe41"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bitreader",
|
"bitreader",
|
||||||
|
@ -46,7 +46,7 @@ parking_lot = "0.12.0"
|
|||||||
password-hash = "0.3.2"
|
password-hash = "0.3.2"
|
||||||
protobuf = "3.0.0-alpha.1"
|
protobuf = "3.0.0-alpha.1"
|
||||||
reffers = "0.7.0"
|
reffers = "0.7.0"
|
||||||
retina = "0.3.7"
|
retina = "0.3.9"
|
||||||
ring = "0.16.2"
|
ring = "0.16.2"
|
||||||
rusqlite = "0.27.0"
|
rusqlite = "0.27.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
@ -214,7 +214,7 @@ fn press_test_inner(
|
|||||||
.enable_io()
|
.enable_io()
|
||||||
.build()?;
|
.build()?;
|
||||||
let _guard = rt.enter();
|
let _guard = rt.enter();
|
||||||
let (extra_data, _stream) = stream::OPENER.open(
|
let (extra_data, stream) = stream::OPENER.open(
|
||||||
&rt,
|
&rt,
|
||||||
"test stream".to_owned(),
|
"test stream".to_owned(),
|
||||||
url,
|
url,
|
||||||
@ -227,8 +227,10 @@ fn press_test_inner(
|
|||||||
.transport(transport),
|
.transport(transport),
|
||||||
)?;
|
)?;
|
||||||
Ok(format!(
|
Ok(format!(
|
||||||
"{}x{} video stream",
|
"{}x{} video stream served by tool {:?}",
|
||||||
extra_data.width, extra_data.height
|
extra_data.width,
|
||||||
|
extra_data.height,
|
||||||
|
stream.tool(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ use fnv::FnvHashMap;
|
|||||||
use hyper::service::{make_service_fn, service_fn};
|
use hyper::service::{make_service_fn, service_fn};
|
||||||
use log::error;
|
use log::error;
|
||||||
use log::{info, warn};
|
use log::{info, warn};
|
||||||
|
use retina::client::SessionGroup;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -324,7 +325,9 @@ async fn inner(
|
|||||||
let syncer = syncers.get(&sample_file_dir_id).unwrap();
|
let syncer = syncers.get(&sample_file_dir_id).unwrap();
|
||||||
let session_group = session_groups_by_camera
|
let session_group = session_groups_by_camera
|
||||||
.entry(camera.id)
|
.entry(camera.id)
|
||||||
.or_default()
|
.or_insert_with(|| {
|
||||||
|
Arc::new(SessionGroup::default().named(camera.short_name.clone()))
|
||||||
|
})
|
||||||
.clone();
|
.clone();
|
||||||
let mut streamer = streamer::Streamer::new(
|
let mut streamer = streamer::Streamer::new(
|
||||||
&env,
|
&env,
|
||||||
|
@ -45,6 +45,7 @@ pub struct VideoFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Stream: Send {
|
pub trait Stream: Send {
|
||||||
|
fn tool(&self) -> Option<&retina::client::Tool>;
|
||||||
fn next(&mut self) -> Result<VideoFrame, Error>;
|
fn next(&mut self) -> Result<VideoFrame, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ impl Opener for RealOpener {
|
|||||||
let options = options.user_agent(format!("Moonfire NVR {}", env!("CARGO_PKG_VERSION")));
|
let options = options.user_agent(format!("Moonfire NVR {}", env!("CARGO_PKG_VERSION")));
|
||||||
let (session, video_params, first_frame) = rt.block_on(tokio::time::timeout(
|
let (session, video_params, first_frame) = rt.block_on(tokio::time::timeout(
|
||||||
RETINA_TIMEOUT,
|
RETINA_TIMEOUT,
|
||||||
RetinaStream::play(url, options),
|
RetinaStream::play(&label, url, options),
|
||||||
))??;
|
))??;
|
||||||
let extra_data = h264::parse_extra_data(video_params.extra_data())?;
|
let extra_data = h264::parse_extra_data(video_params.extra_data())?;
|
||||||
let stream = Box::new(RetinaStream {
|
let stream = Box::new(RetinaStream {
|
||||||
@ -91,6 +92,7 @@ struct RetinaStream<'a> {
|
|||||||
impl<'a> RetinaStream<'a> {
|
impl<'a> RetinaStream<'a> {
|
||||||
/// Plays to first frame. No timeout; that's the caller's responsibility.
|
/// Plays to first frame. No timeout; that's the caller's responsibility.
|
||||||
async fn play(
|
async fn play(
|
||||||
|
label: &str,
|
||||||
url: Url,
|
url: Url,
|
||||||
options: retina::client::SessionOptions,
|
options: retina::client::SessionOptions,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
@ -102,6 +104,7 @@ impl<'a> RetinaStream<'a> {
|
|||||||
Error,
|
Error,
|
||||||
> {
|
> {
|
||||||
let mut session = retina::client::Session::describe(url, options).await?;
|
let mut session = retina::client::Session::describe(url, options).await?;
|
||||||
|
log::debug!("connected to {:?}, tool {:?}", label, session.tool());
|
||||||
let (video_i, mut video_params) = session
|
let (video_i, mut video_params) = session
|
||||||
.streams()
|
.streams()
|
||||||
.iter()
|
.iter()
|
||||||
@ -177,6 +180,10 @@ impl<'a> RetinaStream<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Stream for RetinaStream<'a> {
|
impl<'a> Stream for RetinaStream<'a> {
|
||||||
|
fn tool(&self) -> Option<&retina::client::Tool> {
|
||||||
|
Pin::into_inner(self.session.as_ref()).tool()
|
||||||
|
}
|
||||||
|
|
||||||
fn next(&mut self) -> Result<VideoFrame, Error> {
|
fn next(&mut self) -> Result<VideoFrame, Error> {
|
||||||
let frame = self.first_frame.take().map(Ok).unwrap_or_else(|| {
|
let frame = self.first_frame.take().map(Ok).unwrap_or_else(|| {
|
||||||
self.rt
|
self.rt
|
||||||
@ -247,6 +254,10 @@ pub mod testutil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for Mp4Stream {
|
impl Stream for Mp4Stream {
|
||||||
|
fn tool(&self) -> Option<&retina::client::Tool> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
fn next(&mut self) -> Result<VideoFrame, Error> {
|
fn next(&mut self) -> Result<VideoFrame, Error> {
|
||||||
let sample = self
|
let sample = self
|
||||||
.reader
|
.reader
|
||||||
|
@ -313,6 +313,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for ProxyingStream {
|
impl Stream for ProxyingStream {
|
||||||
|
fn tool(&self) -> Option<&retina::client::Tool> {
|
||||||
|
self.inner.tool()
|
||||||
|
}
|
||||||
|
|
||||||
fn next(&mut self) -> Result<stream::VideoFrame, Error> {
|
fn next(&mut self) -> Result<stream::VideoFrame, Error> {
|
||||||
if self.pkts_left == 0 {
|
if self.pkts_left == 0 {
|
||||||
bail!("end of stream");
|
bail!("end of stream");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user