use std::time::Duration;
use crate::tapo_vendor::api::rtsp_snapshot::grab_mjpeg_frame;
use crate::tapo_vendor::error::Error;
use crate::tapo_vendor::responses::{RtspStreamUrl, Snapshot};
pub(crate) fn rtsp_stream_url(ip: &str, username: &str, password: &str) -> RtspStreamUrl {
RtspStreamUrl {
hd: rtsp_url(ip, "stream1", username, password),
sd: rtsp_url(ip, "stream2", username, password),
mjpeg: rtsp_url(ip, "stream8", username, password),
}
}
pub(crate) async fn snapshot(
ip: &str,
username: &str,
password: &str,
timeout: Duration,
) -> Result<Snapshot, Error> {
let url = rtsp_url_base(ip, "stream8");
let creds = retina::client::Credentials {
username: username.into(),
password: password.into(),
};
let data = grab_mjpeg_frame(&url, creds, timeout).await?;
Ok(Snapshot {
data,
content_type: "image/jpeg".into(),
})
}
fn rtsp_url_base(ip: &str, stream: &str) -> String {
format!("rtsp://{ip}:554/{stream}")
}
fn rtsp_url(ip: &str, stream: &str, username: &str, password: &str) -> String {
let mut url = reqwest::Url::parse(&rtsp_url_base(ip, stream)).expect("valid RTSP base URL");
url.set_username(username).expect("valid username");
url.set_password(Some(password)).expect("valid password");
url.to_string()
}