feat: implémentation du WebRenderer UPnP privé par navigateur

Ajout de la fonctionnalité WebRenderer permettant à chaque navigateur connecté de devenir un MediaRenderer UPnP privé.

- Création du crate pmowebrenderer avec l'architecture complète
- Implémentation des handlers SOAP → WebSocket pour les services AVTransport, RenderingControl et ConnectionManager
- Intégration avec le ControlPoint pour l'enregistrement dynamique des renderers
- Gestion des sessions avec timeout et cleanup automatique
- Support des commandes de transport (play, pause, stop, seek) et du contrôle du volume
- Mise à jour des dépendances dans Cargo.toml et Cargo.lock
- Documentation de l'architecture dans Blackboard/Architecture/webrenderer.md
This commit is contained in:
2026-02-09 07:18:13 +01:00
parent b987decb8d
commit 1e882ba6c3
19 changed files with 2028 additions and 215 deletions

View File

@@ -0,0 +1,57 @@
//! Intégration avec pmoserver — enregistrement des routes WebRenderer
#[cfg(feature = "pmoserver")]
use std::sync::Arc;
#[cfg(feature = "pmoserver")]
use std::time::Duration;
#[cfg(feature = "pmoserver")]
use async_trait::async_trait;
#[cfg(feature = "pmoserver")]
use pmocontrol::ControlPoint;
#[cfg(feature = "pmoserver")]
use crate::error::WebRendererError;
#[cfg(feature = "pmoserver")]
use crate::session::SessionManager;
#[cfg(feature = "pmoserver")]
use crate::websocket::{websocket_handler, WebSocketState};
/// Trait pour étendre pmoserver::Server avec les routes WebRenderer
#[cfg(feature = "pmoserver")]
#[async_trait]
pub trait WebRendererExt {
async fn register_web_renderer(
&mut self,
control_point: Arc<ControlPoint>,
) -> Result<(), WebRendererError>;
}
#[cfg(feature = "pmoserver")]
#[async_trait]
impl WebRendererExt for pmoserver::Server {
async fn register_web_renderer(
&mut self,
control_point: Arc<ControlPoint>,
) -> Result<(), WebRendererError> {
let session_manager = Arc::new(SessionManager::new(Duration::from_secs(30 * 60)));
let ws_state = WebSocketState {
session_manager,
control_point,
};
self.add_any_handler_with_state("/api/webrenderer/ws", websocket_handler, ws_state)
.await;
tracing::info!("WebRenderer WebSocket endpoint registered at /api/webrenderer/ws");
Ok(())
}
}
#[cfg(not(feature = "pmoserver"))]
pub trait WebRendererExt {}
#[cfg(not(feature = "pmoserver"))]
impl WebRendererExt for () {}