Bump: 0.5.0 : unlisted, password and locked stream support

This commit is contained in:
2026-08-16 14:56:29 +01:00
parent 9960434c1c
commit 0c6705badd
13 changed files with 319 additions and 45 deletions
+40 -5
View File
@@ -1,4 +1,8 @@
use std::{net::SocketAddr, sync::Arc, time::{Duration, Instant}};
use std::{
net::SocketAddr,
sync::Arc,
time::{Duration, Instant},
};
use async_broadcast::broadcast;
use axum::{
@@ -298,6 +302,9 @@ pub async fn handle_whip_injest(
stream_key_id: key.id,
stream_key_label: key.label,
stream_key_user: user.username,
custom_id: key.custom_id,
is_unlisted: key.is_unlisted,
password: key.password,
frame_channel: video_tx,
audio_channel: audio_tx,
codec: negotiated_codec,
@@ -372,6 +379,7 @@ async fn detach_inject_rtc(
let sessions_ref = sessions_ref.clone();
let db = db.clone();
async move {
debug!("Cleaning up {:?}", &stream_key_id);
sessions_ref.remove(&stream_key_id);
if let Ok(Some(s)) =
stream_session::Model::get_active_by_stream_key_id(&db, stream_key_id).await
@@ -388,6 +396,7 @@ async fn detach_inject_rtc(
let mut video_tx: Option<async_broadcast::Sender<Arc<VideoFrame>>> = None;
let mut audio_tx: Option<async_broadcast::Sender<Arc<OpusAudioFrame>>> = None;
let mut _connected = false;
let mut disconnect_timer: Option<Instant> = None;
loop {
// Blankly using them so they don't drop (like RTMP).
@@ -398,6 +407,7 @@ async fn detach_inject_rtc(
match rtc.poll_output() {
Ok(Output::Timeout(t)) => break t,
Ok(Output::Transmit(t)) => {
// The keep alive loop, by default is every 1 second.
trace!(
"Whip TX: {} bytes → {}:{}",
t.contents.len(),
@@ -409,6 +419,22 @@ async fn detach_inject_rtc(
cleanup().await;
return;
}
// 30 Sec time out if disconnected, then we clean up and disconnect.
if let Some(instant_since_disconnet) = disconnect_timer
&& Instant::now()
.duration_since(instant_since_disconnet)
.as_secs()
> NO_MEDIA_TIMEOUT.as_secs()
{
info!(
"WHIP connection on stream_key_id: {:?}, has been disconnected for {:?} seconds. Cleaning up and destroying the connection,",
stream_key_id,
NO_MEDIA_TIMEOUT.as_secs()
);
cleanup().await;
rtc.disconnect();
return;
}
}
Ok(Output::Event(e)) => match e {
Event::MediaAdded(ma) => {
@@ -448,10 +474,19 @@ async fn detach_inject_rtc(
}
Event::IceConnectionStateChange(state) => {
info!(stream_key_id, ?state, "Whip ICE state change");
if matches!(state, str0m::IceConnectionState::Disconnected) {
info!("Whip ICE disconnected, closing connection");
cleanup().await;
return;
match state {
str0m::IceConnectionState::Disconnected => {
info!(
"Whip ICE disconnected... (State changed to Disconnected for {:?}) ((This is usually due to network jitter))",
&stream_key_id
);
disconnect_timer = Some(Instant::now());
}
str0m::IceConnectionState::Connected
| str0m::IceConnectionState::Completed => {
disconnect_timer = None;
}
_ => {}
}
}
Event::Connected => {