mirror of
https://github.com/BetterCorp/BetterFrame.git
synced 2026-05-26 16:56:33 +00:00
fix(kiosk): extract RTSP creds as rtspsrc properties for digest auth
Credentials embedded in RTSP URL can skip digest negotiation on some cameras. Now extract user:pass from URL, set as user-id/user-pw properties on rtspsrc, pass clean URL as location. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
36a787cc1e
commit
7b9ba13e3a
1 changed files with 35 additions and 3 deletions
|
|
@ -6,10 +6,20 @@ pub fn create_camera_pipeline(name: &str, rtsp_uri: &str) -> Option<(Pipeline, E
|
||||||
let pipeline_name = format!("cam-{name}");
|
let pipeline_name = format!("cam-{name}");
|
||||||
let pipeline = Pipeline::with_name(&pipeline_name);
|
let pipeline = Pipeline::with_name(&pipeline_name);
|
||||||
|
|
||||||
let src = gst::ElementFactory::make("rtspsrc")
|
// Parse user:pass from RTSP URL and set as properties so rtspsrc
|
||||||
.property("location", rtsp_uri)
|
// does proper digest auth negotiation (embedding in URL can skip it).
|
||||||
|
let (location, user, pass) = extract_rtsp_creds(rtsp_uri);
|
||||||
|
let mut builder = gst::ElementFactory::make("rtspsrc")
|
||||||
|
.property("location", &location)
|
||||||
.property("latency", 300u32)
|
.property("latency", 300u32)
|
||||||
.property_from_str("protocols", "tcp")
|
.property_from_str("protocols", "tcp");
|
||||||
|
if let Some(ref u) = user {
|
||||||
|
builder = builder.property("user-id", u.as_str());
|
||||||
|
}
|
||||||
|
if let Some(ref p) = pass {
|
||||||
|
builder = builder.property("user-pw", p.as_str());
|
||||||
|
}
|
||||||
|
let src = builder
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| error!("[{pipeline_name}] rtspsrc: {e}"))
|
.map_err(|e| error!("[{pipeline_name}] rtspsrc: {e}"))
|
||||||
.ok()?;
|
.ok()?;
|
||||||
|
|
@ -123,3 +133,25 @@ pub fn play(pipeline: &Pipeline) {
|
||||||
pub fn stop(pipeline: &Pipeline) {
|
pub fn stop(pipeline: &Pipeline) {
|
||||||
let _ = pipeline.set_state(gst::State::Null);
|
let _ = pipeline.set_state(gst::State::Null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract user:pass from rtsp://user:pass@host/... URL.
|
||||||
|
/// Returns (url_without_creds, Option<user>, Option<pass>).
|
||||||
|
fn extract_rtsp_creds(uri: &str) -> (String, Option<String>, Option<String>) {
|
||||||
|
if let Some(after_scheme) = uri.strip_prefix("rtsp://") {
|
||||||
|
if let Some(at_pos) = after_scheme.find('@') {
|
||||||
|
let creds = &after_scheme[..at_pos];
|
||||||
|
let rest = &after_scheme[at_pos + 1..];
|
||||||
|
let clean_url = format!("rtsp://{rest}");
|
||||||
|
let (user, pass) = match creds.find(':') {
|
||||||
|
Some(colon) => {
|
||||||
|
let u = urlencoding::decode(&creds[..colon]).unwrap_or_default().to_string();
|
||||||
|
let p = urlencoding::decode(&creds[colon + 1..]).unwrap_or_default().to_string();
|
||||||
|
(Some(u), Some(p))
|
||||||
|
}
|
||||||
|
None => (Some(creds.to_string()), None),
|
||||||
|
};
|
||||||
|
return (clean_url, user, pass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(uri.to_string(), None, None)
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue