🗑️ Remove unused imports, macros and dead code
- Drop `Path`/``State``` from unused Axum imports in config.rs and registry - Mark `_position_sec` field as `#[allow(dead_code)]`` in PositionUpdateRequest and PlayerStateReport - Remove unused macro rules (`add_action_arg!`, `add_action!``, `` add_var!)`` - Delete unused PlayerReport struct and related handler code
This commit is contained in:
@@ -7,7 +7,11 @@ use std::sync::Arc;
|
||||
use async_trait::async_trait;
|
||||
|
||||
#[cfg(feature = "pmoserver")]
|
||||
use axum::{Router, routing::{delete, get, post}};
|
||||
use axum::{
|
||||
Router,
|
||||
extract::{Path, State},
|
||||
routing::{delete, get, post},
|
||||
};
|
||||
|
||||
#[cfg(feature = "pmoserver")]
|
||||
use pmocontrol::ControlPoint;
|
||||
@@ -15,7 +19,10 @@ use pmocontrol::ControlPoint;
|
||||
#[cfg(feature = "pmoserver")]
|
||||
use crate::error::WebRendererError;
|
||||
#[cfg(feature = "pmoserver")]
|
||||
use crate::register::{position_update_handler, register_handler, unregister_handler};
|
||||
use crate::register::{
|
||||
pause_handler, play_handler, position_update_handler, register_handler,
|
||||
report_handler, set_uri_handler, unregister_handler,
|
||||
};
|
||||
#[cfg(feature = "pmoserver")]
|
||||
use crate::registry::RendererRegistry;
|
||||
#[cfg(feature = "pmoserver")]
|
||||
@@ -48,18 +55,25 @@ impl WebRendererExt for pmoserver::Server {
|
||||
)
|
||||
.await;
|
||||
|
||||
// GET /api/webrenderer/{id}/stream + DELETE /api/webrenderer/{id} + POST /api/webrenderer/{id}/position
|
||||
// GET /api/webrenderer/{id}/stream + DELETE /api/webrenderer/{id}
|
||||
// POST /api/webrenderer/{id}/play -> tell player to start streaming
|
||||
// POST /api/webrenderer/{id}/pause, /set_uri, /report
|
||||
// GET /api/webrenderer/{id}/command, /position
|
||||
let dynamic_router = Router::new()
|
||||
.route("/{id}/stream", get(stream_handler))
|
||||
.route("/{id}/position", post(position_update_handler))
|
||||
.route("/{id}", delete(unregister_handler))
|
||||
.route("/{id}/play", post(play_handler))
|
||||
.route("/{id}/pause", post(pause_handler))
|
||||
.route("/{id}/set_uri", post(set_uri_handler))
|
||||
.route("/{id}/report", post(report_handler))
|
||||
.route("/{id}/command", get(crate::register::command_handler))
|
||||
.route("/{id}/position", post(position_update_handler))
|
||||
.with_state(registry.clone());
|
||||
self.add_router("/api/webrenderer", dynamic_router).await;
|
||||
|
||||
tracing::info!("WebRenderer server-side streaming endpoints registered");
|
||||
tracing::info!(" POST /api/webrenderer/register");
|
||||
tracing::info!(" GET /api/webrenderer/{{id}}/stream");
|
||||
tracing::info!(" POST /api/webrenderer/{{id}}/position");
|
||||
tracing::info!(" DELETE /api/webrenderer/{{id}}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -24,10 +24,30 @@ pub fn play_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHandl
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
tracing::info!("[WebRenderer] UPnP Play action invoked");
|
||||
// Ne pas écrire Playing ici : c'est stream_source qui le fera
|
||||
// une fois que les premiers bytes FLAC ont été produits.
|
||||
// Écrire Transitioning pour signaler que la lecture va démarrer.
|
||||
state.write().playback_state = PlaybackState::Transitioning;
|
||||
|
||||
// Check if URI is loaded FIRST, then write state
|
||||
let has_uri = state.read().current_uri.is_some();
|
||||
|
||||
// Single write to update playback_state - avoid holding read lock
|
||||
{
|
||||
let mut s = state.write();
|
||||
s.playback_state = PlaybackState::Transitioning;
|
||||
}
|
||||
|
||||
// Tell frontend to start streaming - include the stream URL
|
||||
if has_uri {
|
||||
// Use a single write to set player_command
|
||||
state.write().player_command = Some(serde_json::json!({
|
||||
"type": "stream",
|
||||
"url": "/api/webrenderer/stream" // Frontend will prefix with instance ID
|
||||
}));
|
||||
tracing::info!("UPnP Play: stored stream command for frontend polling");
|
||||
}
|
||||
|
||||
pipeline.send(PipelineControl::Play).await;
|
||||
Ok(data)
|
||||
})
|
||||
@@ -95,6 +115,7 @@ pub fn set_uri_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHa
|
||||
let pipeline = pipeline.clone();
|
||||
let state = state.clone();
|
||||
Box::pin(async move {
|
||||
tracing::info!("[WebRenderer] UPnP SetAVTransportURI action invoked");
|
||||
let uri: String = get!(&data, "CurrentURI", String);
|
||||
let metadata: String = get_value::<String>(&data, "CurrentURIMetaData")
|
||||
.or_else(|_| {
|
||||
@@ -103,6 +124,8 @@ pub fn set_uri_handler(pipeline: PipelineHandle, state: SharedState) -> ActionHa
|
||||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
tracing::info!(uri = %uri, "SetAVTransportURI handler called - loading URI into pipeline");
|
||||
|
||||
// Envoyer l'URI au pipeline serveur (remplace l'envoi WebSocket)
|
||||
pipeline.send(PipelineControl::LoadUri(uri.clone())).await;
|
||||
|
||||
|
||||
@@ -47,6 +47,8 @@ pub enum TransportAction {
|
||||
Seek,
|
||||
SetUri,
|
||||
SetNextUri,
|
||||
/// Flush buffer immediatement - pour reponse rapide
|
||||
Flush,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
@@ -84,6 +86,11 @@ pub enum ClientMessage {
|
||||
/// Envoyé quand la piste courante se termine naturellement (gapless).
|
||||
/// Le backend fait avancer current → next dans l'état partagé.
|
||||
TrackEnded,
|
||||
/// Ready state du player HTML5 audio
|
||||
/// have_nothing, have_metadata, have_current_data, have_future_data, can_play, can_play_through
|
||||
ReadyStateUpdate {
|
||||
ready_state: String,
|
||||
},
|
||||
Pong,
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
http::StatusCode,
|
||||
http::{StatusCode, header::HeaderMap},
|
||||
response::IntoResponse,
|
||||
Json,
|
||||
};
|
||||
@@ -24,9 +24,12 @@ pub struct RegisterRequest {
|
||||
pub struct RegisterResponse {
|
||||
pub stream_url: String,
|
||||
pub udn: String,
|
||||
/// true si le backend est déjà en lecture — le frontend doit démarrer immédiatement
|
||||
pub should_play: bool,
|
||||
}
|
||||
|
||||
/// POST /api/webrenderer/register
|
||||
#[axum::debug_handler]
|
||||
pub async fn register_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Json(req): Json<RegisterRequest>,
|
||||
@@ -41,14 +44,15 @@ pub async fn register_handler(
|
||||
.register_or_reconnect(&req.instance_id, &req.user_agent)
|
||||
.await
|
||||
{
|
||||
Ok((stream_url, udn)) => {
|
||||
Ok((stream_url, udn, should_play)) => {
|
||||
tracing::info!(
|
||||
instance_id = %req.instance_id,
|
||||
stream_url = %stream_url,
|
||||
udn = %udn,
|
||||
should_play = %should_play,
|
||||
"WebRenderer: registered"
|
||||
);
|
||||
(StatusCode::OK, Json(RegisterResponse { stream_url, udn })).into_response()
|
||||
(StatusCode::OK, Json(RegisterResponse { stream_url, udn, should_play })).into_response()
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(
|
||||
@@ -70,6 +74,7 @@ pub struct PositionUpdateRequest {
|
||||
/// POST /api/webrenderer/{id}/position
|
||||
/// position_sec est ignoré (géré par PlayerEvent::Position côté serveur).
|
||||
/// duration_sec est utilisé comme fallback si la source ne connaît pas la durée (flux radio).
|
||||
#[axum::debug_handler]
|
||||
pub async fn position_update_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
@@ -80,6 +85,7 @@ pub async fn position_update_handler(
|
||||
}
|
||||
|
||||
/// DELETE /api/webrenderer/{id}
|
||||
#[axum::debug_handler]
|
||||
pub async fn unregister_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
@@ -88,3 +94,106 @@ pub async fn unregister_handler(
|
||||
registry.schedule_unregister(&instance_id);
|
||||
StatusCode::NO_CONTENT
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct UriRequest {
|
||||
pub uri: String,
|
||||
}
|
||||
|
||||
/// POST /api/webrenderer/{id}/set_uri - charge une URI et joue
|
||||
#[axum::debug_handler]
|
||||
pub async fn set_uri_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
Json(req): Json<UriRequest>,
|
||||
) -> impl IntoResponse {
|
||||
tracing::info!(instance_id = %instance_id, uri = %req.uri, "WebRenderer: set_uri request");
|
||||
registry.load_uri(&instance_id, req.uri).await;
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
/// POST /api/webrenderer/{id}/pause
|
||||
#[axum::debug_handler]
|
||||
pub async fn pause_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
tracing::info!(instance_id = %instance_id, "WebRenderer: pause request");
|
||||
registry.send_pause_command(&instance_id).await;
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
// ─── Rapports du player ─────────────────────────────────────────────────────
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct PlayerStateReport {
|
||||
pub position_sec: Option<f64>,
|
||||
pub duration_sec: Option<f64>,
|
||||
pub state: Option<String>,
|
||||
pub ready_state: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct PlayerReport {
|
||||
pub instance_id: String,
|
||||
#[serde(flatten)]
|
||||
pub report: PlayerStateReport,
|
||||
}
|
||||
|
||||
/// POST /api/webrenderer/{id}/report - recoit rapports position/state du player
|
||||
#[axum::debug_handler]
|
||||
pub async fn report_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
Json(report): Json<PlayerStateReport>,
|
||||
) -> impl IntoResponse {
|
||||
// Registry met à jour l'état avec les rapports du player
|
||||
registry.update_player_state(&instance_id, report).await;
|
||||
StatusCode::OK
|
||||
}
|
||||
|
||||
// ─── Commandes vers le player ─────────────────────────────────
|
||||
|
||||
/// GET /api/webrenderer/{id}/command - recupere commande pending pour le player
|
||||
#[axum::debug_handler]
|
||||
pub async fn command_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
match registry.get_pending_command(&instance_id).await {
|
||||
Some(cmd) => (StatusCode::OK, Json(cmd)).into_response(),
|
||||
None => StatusCode::NO_CONTENT.into_response(),
|
||||
}
|
||||
}
|
||||
|
||||
/// POST /api/webrenderer/{id}/play - tell player to stream and play
|
||||
#[axum::debug_handler]
|
||||
pub async fn play_handler(
|
||||
State(registry): State<Arc<RendererRegistry>>,
|
||||
Path(instance_id): Path<String>,
|
||||
) -> impl IntoResponse {
|
||||
// Check if there's a valid URI loaded - if not, ignore the play command
|
||||
if !registry.has_current_uri(&instance_id) {
|
||||
tracing::warn!(instance_id = %instance_id, "Play command ignored: no URI loaded");
|
||||
let mut headers = HeaderMap::new();
|
||||
headers.insert(axum::http::header::CONTENT_TYPE, "text/plain".parse().unwrap());
|
||||
return (StatusCode::BAD_REQUEST, headers, "No URI loaded").into_response();
|
||||
}
|
||||
|
||||
tracing::info!(instance_id = %instance_id, "WebRenderer: play request");
|
||||
|
||||
// Get stream URL and tell player to play it
|
||||
let stream_url = format!("/api/webrenderer/{}/stream", instance_id);
|
||||
|
||||
// Set command for player to start streaming
|
||||
let command = serde_json::json!({
|
||||
"type": "stream",
|
||||
"url": stream_url
|
||||
});
|
||||
registry.set_player_command(&instance_id, command);
|
||||
|
||||
// Also tell pipeline to play (if not already) - use existing method
|
||||
registry.send_play_command(&instance_id).await;
|
||||
|
||||
(StatusCode::OK, "OK").into_response()
|
||||
}
|
||||
|
||||
@@ -3,6 +3,11 @@
|
||||
//! Remplace `SessionManager` et `websocket.rs`. La session est maintenant liée
|
||||
//! au flux FLAC HTTP, pas à une connexion WebSocket.
|
||||
|
||||
use axum::{
|
||||
extract::{Path, State},
|
||||
http::StatusCode,
|
||||
response::IntoResponse,
|
||||
};
|
||||
use parking_lot::RwLock;
|
||||
use std::collections::HashMap;
|
||||
use std::sync::Arc;
|
||||
@@ -68,12 +73,13 @@ impl RendererRegistry {
|
||||
}
|
||||
|
||||
/// Enregistre ou reconnecte une instance.
|
||||
/// Retourne `(stream_url, udn)`.
|
||||
/// Retourne `(stream_url, udn, should_play)`.
|
||||
/// `should_play` est true si le backend est déjà en lecture : le frontend doit démarrer immédiatement.
|
||||
pub async fn register_or_reconnect(
|
||||
&self,
|
||||
instance_id: &str,
|
||||
user_agent: &str,
|
||||
) -> Result<(String, String), WebRendererError> {
|
||||
) -> Result<(String, String, bool), WebRendererError> {
|
||||
// Annuler tout unregister différé pour cet instance_id
|
||||
if let Some(cancel) = self.pending_unregister.write().remove(instance_id) {
|
||||
tracing::info!(instance_id = %instance_id, "WebRenderer: cancelled pending unregister (page reload)");
|
||||
@@ -88,7 +94,14 @@ impl RendererRegistry {
|
||||
#[cfg(feature = "pmoserver")]
|
||||
self.register_with_control_point(&existing.device_instance)?;
|
||||
let stream_url = format!("/api/webrenderer/{}/stream", instance_id);
|
||||
return Ok((stream_url, existing.udn.clone()));
|
||||
let should_play = {
|
||||
let s = existing.state.read();
|
||||
s.current_uri.is_some() && matches!(
|
||||
s.playback_state,
|
||||
crate::messages::PlaybackState::Playing | crate::messages::PlaybackState::Transitioning
|
||||
)
|
||||
};
|
||||
return Ok((stream_url, existing.udn.clone(), should_play));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +126,7 @@ impl RendererRegistry {
|
||||
"WebRenderer: new instance registered"
|
||||
);
|
||||
|
||||
Ok((stream_url, udn))
|
||||
Ok((stream_url, udn, false))
|
||||
}
|
||||
|
||||
/// Retourne un OggFlacClientStream indépendant pour l'endpoint /stream.
|
||||
@@ -122,10 +135,17 @@ impl RendererRegistry {
|
||||
&self,
|
||||
instance_id: &str,
|
||||
) -> Option<pmoaudio_ext::sinks::OggFlacClientStream> {
|
||||
self.instances
|
||||
.read()
|
||||
.get(instance_id)
|
||||
.map(|i| i.flac_handle.subscribe())
|
||||
let instances = self.instances.read();
|
||||
match instances.get(instance_id) {
|
||||
Some(i) => {
|
||||
tracing::debug!(instance_id = %instance_id, "Found instance, getting flac_handle");
|
||||
Some(i.flac_handle.subscribe())
|
||||
}
|
||||
None => {
|
||||
tracing::error!(instance_id = %instance_id, "Instance not found in registry!");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Retourne le PipelineHandle par UDN (pour les handlers UPnP)
|
||||
@@ -208,6 +228,97 @@ impl RendererRegistry {
|
||||
});
|
||||
}
|
||||
|
||||
/// Met à jour l'état avec les rapports du player
|
||||
pub async fn update_player_state(
|
||||
&self,
|
||||
instance_id: &str,
|
||||
report: crate::register::PlayerStateReport,
|
||||
) {
|
||||
let instances = self.instances.read();
|
||||
if let Some(instance) = instances.get(instance_id) {
|
||||
let mut state = instance.state.write();
|
||||
if let Some(pos) = report.position_sec {
|
||||
state.position = Some(pos.to_string());
|
||||
}
|
||||
if let Some(dur) = report.duration_sec {
|
||||
state.duration = Some(dur.to_string());
|
||||
}
|
||||
if let Some(s) = &report.state {
|
||||
state.playback_state = match s.as_str() {
|
||||
"playing" => crate::messages::PlaybackState::Playing,
|
||||
"paused" => crate::messages::PlaybackState::Paused,
|
||||
"stopped" => crate::messages::PlaybackState::Stopped,
|
||||
_ => state.playback_state.clone(),
|
||||
};
|
||||
}
|
||||
tracing::debug!(instance_id = %instance_id, position = ?state.position, "player state updated");
|
||||
}
|
||||
}
|
||||
|
||||
/// Récupère et consomme la commande en attente pour le player
|
||||
pub async fn get_pending_command(
|
||||
&self,
|
||||
instance_id: &str,
|
||||
) -> Option<serde_json::Value> {
|
||||
self.instances
|
||||
.read()
|
||||
.get(instance_id)
|
||||
.and_then(|instance| instance.state.write().player_command.take())
|
||||
}
|
||||
|
||||
/// Stocke une commande pour le player (consommée via GET /command)
|
||||
pub fn set_player_command(&self, instance_id: &str, command: serde_json::Value) {
|
||||
if let Some(instance) = self.instances.read().get(instance_id) {
|
||||
instance.state.write().player_command = Some(command);
|
||||
}
|
||||
}
|
||||
|
||||
/// Charge une URI dans le pipeline
|
||||
pub async fn load_uri(&self, instance_id: &str, uri: String) {
|
||||
// Get pipeline handle before async call to avoid holding lock across await
|
||||
let pipeline = self.instances.read().get(instance_id).map(|i| i.pipeline.clone());
|
||||
if let Some(pipeline) = pipeline {
|
||||
use pmoaudio_ext::PlayerCommand;
|
||||
pipeline.send(PlayerCommand::LoadUri(uri.clone())).await;
|
||||
pipeline.send(PlayerCommand::Play).await;
|
||||
tracing::info!(instance_id = %instance_id, uri = %uri, "loaded URI");
|
||||
}
|
||||
}
|
||||
|
||||
/// Envoie commande play au pipeline
|
||||
pub async fn send_play_command(&self, instance_id: &str) {
|
||||
tracing::info!(instance_id = %instance_id, "send_play_command called");
|
||||
// Get pipeline handle before async call to avoid holding lock across await
|
||||
let pipeline = self.instances.read().get(instance_id).map(|i| i.pipeline.clone());
|
||||
if let Some(pipeline) = pipeline {
|
||||
tracing::info!(instance_id = %instance_id, "Instance found, sending PlayerCommand::Play");
|
||||
use pmoaudio_ext::PlayerCommand;
|
||||
pipeline.send(PlayerCommand::Play).await;
|
||||
tracing::info!(instance_id = %instance_id, "PlayerCommand::Play sent");
|
||||
} else {
|
||||
tracing::error!(instance_id = %instance_id, "Instance not found in send_play_command!");
|
||||
}
|
||||
}
|
||||
|
||||
/// Envoie commande pause au pipeline
|
||||
pub async fn send_pause_command(&self, instance_id: &str) {
|
||||
// Get pipeline handle before async call to avoid holding lock across await
|
||||
let pipeline = self.instances.read().get(instance_id).map(|i| i.pipeline.clone());
|
||||
if let Some(pipeline) = pipeline {
|
||||
use pmoaudio_ext::PlayerCommand;
|
||||
pipeline.send(PlayerCommand::Pause).await;
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the instance has a current URI loaded
|
||||
pub fn has_current_uri(&self, instance_id: &str) -> bool {
|
||||
self.instances
|
||||
.read()
|
||||
.get(instance_id)
|
||||
.map(|i| i.state.read().current_uri.is_some())
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
// ── Création d'instance ────────────────────────────────────────────────────
|
||||
|
||||
async fn create_instance(
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//! État partagé du renderer (backend ↔ pipeline)
|
||||
|
||||
use parking_lot::RwLock;
|
||||
use serde_json::Value;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::messages::PlaybackState;
|
||||
@@ -17,6 +18,8 @@ pub struct RendererState {
|
||||
pub duration: Option<String>,
|
||||
pub volume: u16,
|
||||
pub mute: bool,
|
||||
/// Commande en attente pour le player frontend (polled via /command)
|
||||
pub player_command: Option<Value>,
|
||||
}
|
||||
|
||||
impl Default for RendererState {
|
||||
@@ -31,6 +34,7 @@ impl Default for RendererState {
|
||||
duration: None,
|
||||
volume: 100,
|
||||
mute: false,
|
||||
player_command: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ use axum::{
|
||||
body::Body,
|
||||
extract::{Path, State},
|
||||
http::{
|
||||
HeaderMap, StatusCode,
|
||||
header::{CACHE_CONTROL, CONNECTION, CONTENT_TYPE, TRANSFER_ENCODING},
|
||||
HeaderMap, StatusCode,
|
||||
},
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use std::sync::Arc;
|
||||
use tokio_util::io::ReaderStream;
|
||||
use tracing::info;
|
||||
use tracing::{error, info};
|
||||
|
||||
use crate::registry::RendererRegistry;
|
||||
|
||||
@@ -29,25 +29,26 @@ pub async fn stream_handler(
|
||||
info!(instance_id = %instance_id, "FLAC stream client connecting");
|
||||
|
||||
// Ignorer le header Range — flux live infini, non seekable.
|
||||
// On ne répond jamais 206 ni 416 : toujours 200 chunked.
|
||||
// Safari (et d'autres clients) envoient parfois Range: bytes=0-N ;
|
||||
// répondre 416 ou 206 leur fait croire à une ressource finie.
|
||||
if let Some(range) = headers.get("range") {
|
||||
info!(instance_id = %instance_id, "Range header ignored (live stream): {:?}", range);
|
||||
info!(instance_id = %instance_id, "Range header ignored: {:?}", range);
|
||||
}
|
||||
|
||||
let stream = match registry.get_stream(&instance_id) {
|
||||
Some(s) => s,
|
||||
Some(s) => {
|
||||
info!(instance_id = %instance_id, "Found instance, getting stream");
|
||||
s
|
||||
}
|
||||
None => {
|
||||
error!(instance_id = %instance_id, "No WebRenderer instance found!");
|
||||
return (
|
||||
StatusCode::NOT_FOUND,
|
||||
format!("No WebRenderer instance for id={}", instance_id),
|
||||
)
|
||||
.into_response()
|
||||
.into_response();
|
||||
}
|
||||
};
|
||||
|
||||
info!(instance_id = %instance_id, "FLAC stream started");
|
||||
info!(instance_id = %instance_id, "FLAC stream started - returning OGG-FLAC");
|
||||
|
||||
Response::builder()
|
||||
.status(StatusCode::OK)
|
||||
|
||||
Reference in New Issue
Block a user