more reshape that i missed

This commit is contained in:
2026-06-17 11:55:27 +01:00
parent b2ad096f95
commit cbfa07f8e8
10 changed files with 48 additions and 715 deletions
-5
View File
@@ -8,13 +8,8 @@ name = "rtmp-to-whip"
path = "src/main.rs"
[dependencies]
entity = { path = "../entity" }
migration = { path = "../migration" }
sea-orm = { version = "1", features = ["sqlx-sqlite", "runtime-tokio-rustls", "macros"] }
async-broadcast = "0.7.2"
bytes = "1.11.1"
chrono = "0.4"
dashmap = "6.2.1"
rand = "0.10.1"
rml_rtmp = "0.8.0"
+10 -65
View File
@@ -1,19 +1,11 @@
use std::{error::Error, sync::Arc};
use async_broadcast::broadcast;
use chrono::Utc;
use dashmap::DashMap;
use entity::stream_key;
use entity::stream_session;
use migration::{Migrator, MigratorTrait};
use rml_rtmp::{
handshake::{Handshake, HandshakeProcessResult, PeerType},
sessions::{ServerSession, ServerSessionConfig, ServerSessionEvent, ServerSessionResult},
};
use sea_orm::{
ActiveModelTrait, ActiveValue::Set, ColumnTrait, Database, DatabaseConnection, EntityTrait,
QueryFilter,
};
use tokio::{
io::{AsyncReadExt, AsyncWriteExt},
net::TcpListener,
@@ -32,24 +24,18 @@ mod webrtc;
pub struct AppState {
pub stream_sessions: Arc<DashMap<String, StreamSession>>,
pub db: DatabaseConnection,
}
pub struct StreamSession {
pub stream_key: String,
pub frame_channel: async_broadcast::Sender<Arc<VideoFrame>>,
pub db_session_id: i32,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let db = Database::connect("sqlite://stream.db?mode=rwc").await?;
Migrator::up(&db, None).await?;
let listener = TcpListener::bind("0.0.0.0:8123").await?;
let appstate = Arc::new(Mutex::new(AppState {
stream_sessions: Arc::new(DashMap::new()),
db: db.clone(),
}));
let (offer_tx, offer_rx) = tokio::sync::mpsc::channel::<(String, String)>(4);
let (answer_tx, answer_rx) = tokio::sync::mpsc::channel::<(String, String)>(4);
@@ -73,7 +59,6 @@ async fn main() -> Result<(), Box<dyn Error>> {
loop {
let (stream, _) = listener.accept().await?;
let appstate = appstate.clone();
let db = db.clone();
tokio::spawn(async move {
let mut stream = stream;
@@ -123,64 +108,24 @@ async fn main() -> Result<(), Box<dyn Error>> {
}
ServerSessionResult::RaisedEvent(x) => match x {
ServerSessionEvent::PublishStreamFinished { stream_key, .. } => {
let removed = {
appstate
.lock()
.await
.stream_sessions
.remove(&stream_key)
};
if let Some((_, session)) = removed {
let mut record: stream_session::ActiveModel =
stream_session::Entity::find_by_id(session.db_session_id)
.one(&db)
.await
.unwrap()
.unwrap()
.into();
record.ended_at = Set(Some(Utc::now()));
record.update(&db).await.unwrap();
}
appstate.lock().await.stream_sessions.remove(&stream_key);
}
ServerSessionEvent::PublishStreamRequested {
request_id,
stream_key,
..
} => {
let key_record = stream_key::Entity::find()
.filter(stream_key::Column::KeyValue.eq(&stream_key))
.filter(stream_key::Column::IsActive.eq(true))
.one(&db)
.await
.unwrap();
let reply = if let Some(key_record) = key_record {
let session_record = stream_session::ActiveModel {
stream_key_id: Set(key_record.id),
started_at: Set(Utc::now()),
ended_at: Set(None),
..Default::default()
};
let session_record =
session_record.insert(&db).await.unwrap();
let session = StreamSession {
stream_key: stream_key.clone(),
frame_channel: video_channel.clone(),
db_session_id: session_record.id,
};
appstate
.lock()
.await
.stream_sessions
.insert(stream_key.clone(), session);
rtmp_session.accept_request(request_id).unwrap()
} else {
println!("Rejected unknown/inactive stream key: {stream_key}");
rtmp_session.reject_request(request_id, "", "").unwrap()
let session = StreamSession {
stream_key: stream_key.clone(),
frame_channel: video_channel.clone(),
};
appstate
.lock()
.await
.stream_sessions
.insert(stream_key.clone(), session);
let reply = rtmp_session.accept_request(request_id).unwrap();
for x in reply {
if let ServerSessionResult::OutboundResponse(y) = x {
stream.write_all(&y.bytes).await.unwrap();