retina/examples/client/metadata.rs
Scott Lamb e9a5e4e34a overhaul error type
*   stop using deprecated failure crate and its deps

*   more uniformly detailed error messages

*   an enum of the type of error, currently internal-only. I'm not
    confident enough I understand what cases a caller might want to
    distinguish, so I added a comment inviting input instead of
    exposing it now.

*   while I'm at it, separate connection context and message contexts.
    This shrinks some of the data memmoved around in PacketItem and
    CodecItem.
2021-07-08 11:28:07 -07:00

50 lines
1.4 KiB
Rust

// Copyright (C) 2021 Scott Lamb <slamb@slamb.org>
// SPDX-License-Identifier: MIT OR Apache-2.0
use anyhow::{anyhow, Error};
use futures::StreamExt;
use log::info;
use retina::codec::CodecItem;
#[derive(structopt::StructOpt)]
pub struct Opts {
#[structopt(flatten)]
src: super::Source,
}
pub async fn run(opts: Opts) -> Result<(), Error> {
let stop = tokio::signal::ctrl_c();
let creds = super::creds(opts.src.username, opts.src.password);
let mut session = retina::client::Session::describe(opts.src.url, creds).await?;
let onvif_stream_i = session
.streams()
.iter()
.position(|s| matches!(s.parameters(), Some(retina::codec::Parameters::Message(..))))
.ok_or_else(|| anyhow!("couldn't find onvif stream"))?;
session.setup(onvif_stream_i).await?;
let session = session
.play(retina::client::PlayPolicy::default().ignore_zero_seq(true))
.await?
.demuxed()?;
tokio::pin!(session);
tokio::pin!(stop);
loop {
tokio::select! {
item = session.next() => {
match item.ok_or_else(|| anyhow!("EOF"))?? {
CodecItem::MessageFrame(m) => {
info!("{}: {}\n", &m.timestamp, std::str::from_utf8(&m.data[..]).unwrap());
},
_ => continue,
};
},
_ = &mut stop => {
break;
},
}
}
Ok(())
}