Sort la partie média renderer de pmoupnp pour en faire une crate independante
This commit is contained in:
@@ -5,7 +5,6 @@ pub mod upnp_server;
|
||||
pub mod upnp_api;
|
||||
pub mod actions;
|
||||
pub mod devices;
|
||||
pub mod mediarenderer;
|
||||
pub mod services;
|
||||
pub mod soap;
|
||||
pub mod ssdp;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETCURRENTTRANSPORTACTIONS = "GetCurrentTransportActions" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETDEVICECAPABILITIES = "GetDeviceCapabilities" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, NUMBEROFTRACKS, CURRENTTRACK, AVTRANSPORTURI, AVTRANSPORTURIMETADATA, AVTRANSPORTNEXTURI, AVTRANSPORTNEXTURIMETADATA};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETMEDIAINFO = "GetMediaInfo" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
out "NrTracks" => NUMBEROFTRACKS,
|
||||
out "CurrentTrack" => CURRENTTRACK,
|
||||
out "CurrentURI" => AVTRANSPORTURI,
|
||||
out "CurrentURIMetaData" => AVTRANSPORTURIMETADATA,
|
||||
out "NextURI" => AVTRANSPORTNEXTURI,
|
||||
out "NextURIMetaData" => AVTRANSPORTNEXTURIMETADATA,
|
||||
}
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, CURRENTTRACK, CURRENTTRACKDURATION, AVTRANSPORTURI, AVTRANSPORTURIMETADATA, RELATIVETIMEPOSITION, ABSOLUTETIMEPOSITION};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETPOSITIONINFO = "GetPositionInfo" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
out "Track" => CURRENTTRACK,
|
||||
out "TrackDuration" => CURRENTTRACKDURATION,
|
||||
out "TrackURI" => AVTRANSPORTURI,
|
||||
out "TrackMetaData" => AVTRANSPORTURIMETADATA,
|
||||
out "RelTime" => RELATIVETIMEPOSITION,
|
||||
out "AbsTime" => ABSOLUTETIMEPOSITION,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, TRANSPORTSTATE, TRANSPORTSTATUS};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETTRANSPORTINFO = "GetTransportInfo" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
out "CurrentTransportState" => TRANSPORTSTATE,
|
||||
out "CurrentTransportStatus" => TRANSPORTSTATUS,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETTRANSPORTSETTINGS = "GetTransportSettings" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
mod getcurrenttransportactions;
|
||||
mod getdevicecapabilities;
|
||||
mod getmediainfo;
|
||||
mod getpositioninfo;
|
||||
mod gettransportinfo;
|
||||
mod gettransportsettings;
|
||||
mod next;
|
||||
mod pause;
|
||||
mod play;
|
||||
mod previous;
|
||||
mod seek;
|
||||
mod setavtransportnexturi;
|
||||
mod setavtransporturi;
|
||||
mod stop;
|
||||
|
||||
pub use getcurrenttransportactions::GETCURRENTTRANSPORTACTIONS;
|
||||
pub use getdevicecapabilities::GETDEVICECAPABILITIES;
|
||||
pub use getmediainfo::GETMEDIAINFO;
|
||||
pub use getpositioninfo::GETPOSITIONINFO;
|
||||
pub use gettransportinfo::GETTRANSPORTINFO;
|
||||
pub use gettransportsettings::GETTRANSPORTSETTINGS;
|
||||
pub use next::NEXT;
|
||||
pub use pause::PAUSE;
|
||||
pub use play::PLAY;
|
||||
pub use previous::PREVIOUS;
|
||||
pub use seek::SEEK;
|
||||
pub use setavtransportnexturi::SETNEXTAVTRANSPORTURI;
|
||||
pub use setavtransporturi::SETAVTRANSPORTURI;
|
||||
pub use stop::STOP;
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static NEXT = "Next" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static PAUSE = "Pause" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, TRANSPORTPLAYSPEED};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static PLAY = "Play" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "Speed" => TRANSPORTPLAYSPEED,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static PREVIOUS = "Previous" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, A_ARG_TYPE_SEEKMODE, CURRENTTRACKDURATION};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static SEEK = "Seek" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "Unit" => A_ARG_TYPE_SEEKMODE,
|
||||
in "Target" => CURRENTTRACKDURATION,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, AVTRANSPORTNEXTURI, AVTRANSPORTNEXTURIMETADATA};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static SETNEXTAVTRANSPORTURI = "SetNextAVTransportURI" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "NextURI" => AVTRANSPORTNEXTURI,
|
||||
in "NextURIMetaData" => AVTRANSPORTNEXTURIMETADATA,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::{A_ARG_TYPE_INSTANCE_ID, AVTRANSPORTURI, AVTRANSPORTURIMETADATA};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static SETAVTRANSPORTURI = "SetAVTransportURI" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "CurrentURI" => AVTRANSPORTURI,
|
||||
in "CurrentURIMetaData" => AVTRANSPORTURIMETADATA,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::avtransport::variables::A_ARG_TYPE_INSTANCE_ID;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static STOP = "Stop" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
//! # AVTransport Service - Service de contrôle de transport UPnP
|
||||
//!
|
||||
//! Ce module implémente le service AVTransport:1 selon la spécification UPnP AV.
|
||||
//! Le service AVTransport permet de contrôler la lecture de médias **audio**
|
||||
//! sur des rendus multimédias (MediaRenderer Audio).
|
||||
//!
|
||||
//! ## Fonctionnalités
|
||||
//!
|
||||
//! Le service AVTransport permet :
|
||||
//! - **Contrôle de lecture** : Play, Pause, Stop
|
||||
//! - **Navigation** : Next, Previous, Seek
|
||||
//! - **Gestion des URIs** : SetAVTransportURI, SetNextAVTransportURI
|
||||
//! - **Information d'état** : GetTransportInfo, GetPositionInfo, GetMediaInfo
|
||||
//! - **Capacités** : GetDeviceCapabilities, GetCurrentTransportActions
|
||||
//!
|
||||
//! ## Conformité UPnP
|
||||
//!
|
||||
//! Cette implémentation suit la spécification **UPnP AVTransport:1 Service Template**.
|
||||
//! Toutes les actions obligatoires (Required) sont implémentées :
|
||||
//!
|
||||
//! - ✅ SetAVTransportURI
|
||||
//! - ✅ GetMediaInfo
|
||||
//! - ✅ GetTransportInfo
|
||||
//! - ✅ GetPositionInfo
|
||||
//! - ✅ GetDeviceCapabilities
|
||||
//! - ✅ GetTransportSettings
|
||||
//! - ✅ GetCurrentTransportActions
|
||||
//! - ✅ Stop, Play, Pause
|
||||
//!
|
||||
//! Et certaines actions optionnelles :
|
||||
//! - ✅ SetNextAVTransportURI
|
||||
//! - ✅ Seek, Next, Previous
|
||||
//!
|
||||
//! ## Variables d'état
|
||||
//!
|
||||
//! Le service expose 24 variables d'état conformes à la spécification :
|
||||
//!
|
||||
//! ### État du transport
|
||||
//! - [`TRANSPORTSTATE`] : État actuel (PLAYING, STOPPED, PAUSED_PLAYBACK, etc.)
|
||||
//! - [`TRANSPORTSTATUS`] : Status du transport (OK, ERROR_OCCURRED)
|
||||
//! - [`TRANSPORTPLAYSPEED`] : Vitesse de lecture
|
||||
//!
|
||||
//! ### Information sur les pistes
|
||||
//! - [`CURRENTTRACK`] : Numéro de la piste actuelle
|
||||
//! - [`NUMBEROFTRACKS`] : Nombre total de pistes
|
||||
//! - [`CURRENTTRACKDURATION`] : Durée de la piste actuelle
|
||||
//! - [`CURRENTTRACKURI`] : URI de la piste actuelle
|
||||
//! - [`CURRENTTRACKMETADATA`] : Métadonnées de la piste
|
||||
//!
|
||||
//! ### Positionnement
|
||||
//! - [`RELATIVETIMEPOSITION`] : Position relative dans la piste
|
||||
//! - [`ABSOLUTETIMEPOSITION`] : Position absolue
|
||||
//!
|
||||
//! ### URIs et métadonnées
|
||||
//! - [`AVTRANSPORTURI`] : URI de la ressource en cours
|
||||
//! - [`AVTRANSPORTURIMETADATA`] : Métadonnées associées
|
||||
//! - [`AVTRANSPORTNEXTURI`] : URI de la ressource suivante
|
||||
//! - [`AVTRANSPORTNEXTURIMETADATA`] : Métadonnées de la ressource suivante
|
||||
//!
|
||||
//! ### Modes et capacités
|
||||
//! - [`CURRENTPLAYMODE`] : Mode de lecture (NORMAL, SHUFFLE, REPEAT_ONE, etc.)
|
||||
//! - [`PLAYBACKSTORAGEMEDIUM`] : Support de lecture (NETWORK, HDD, CD-DA, etc.)
|
||||
//! - [`POSSIBLEPLAYBACKSTORAGEMEDIA`] : Supports de lecture possibles
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! use pmoupnp::mediarenderer::avtransport::AVTTRANSPORT;
|
||||
//! use pmoupnp::UpnpTyped;
|
||||
//!
|
||||
//! // Accéder au service
|
||||
//! let service = &*AVTTRANSPORT;
|
||||
//! println!("Service: {}", service.name());
|
||||
//! println!("Type: {}", service.service_type());
|
||||
//!
|
||||
//! // Lister les actions disponibles
|
||||
//! for action in service.actions() {
|
||||
//! println!(" Action: {}", action.get_name());
|
||||
//! }
|
||||
//!
|
||||
//! // Lister les variables d'état
|
||||
//! for variable in service.variables() {
|
||||
//! println!(" Variable: {}", variable.get_name());
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! ## Références
|
||||
//!
|
||||
//! - [UPnP AVTransport:1 Service Template](https://www.upnp.org/specs/av/UPnP-av-AVTransport-v1-Service.pdf)
|
||||
//! - [UPnP AV Architecture](https://upnp.org/specs/av/)
|
||||
|
||||
use crate::define_service;
|
||||
|
||||
pub mod variables;
|
||||
pub mod actions;
|
||||
|
||||
use actions::{
|
||||
GETCURRENTTRANSPORTACTIONS, GETDEVICECAPABILITIES, GETMEDIAINFO,
|
||||
GETPOSITIONINFO, GETTRANSPORTINFO, GETTRANSPORTSETTINGS, NEXT, PAUSE,
|
||||
PLAY, PREVIOUS, SEEK, SETNEXTAVTRANSPORTURI, SETAVTRANSPORTURI, STOP
|
||||
};
|
||||
use variables::{
|
||||
ABSOLUTETIMEPOSITION, AVTRANSPORTNEXTURI, AVTRANSPORTNEXTURIMETADATA,
|
||||
AVTRANSPORTURI, AVTRANSPORTURIMETADATA, A_ARG_TYPE_INSTANCE_ID,
|
||||
A_ARG_TYPE_PLAY_SPEED, A_ARG_TYPE_SEEKMODE, CURRENTMEDIADURATION,
|
||||
CURRENTPLAYMODE, CURRENTTRACK, CURRENTTRACKDURATION, CURRENTTRACKMETADATA,
|
||||
CURRENTTRACKURI, NUMBEROFTRACKS, PLAYBACKSTORAGEMEDIUM,
|
||||
POSSIBLEPLAYBACKSTORAGEMEDIA, RELATIVETIMEPOSITION, SEEKMODE,
|
||||
TRANSPORTPLAYSPEED, TRANSPORTSTATE, TRANSPORTSTATUS
|
||||
};
|
||||
|
||||
// Service AVTransport:1 conforme à la spécification UPnP AV pour MediaRenderer audio
|
||||
// Voir la documentation du module pour plus de détails
|
||||
define_service! {
|
||||
pub static AVTTRANSPORT = "AVTransport" {
|
||||
variables: [
|
||||
ABSOLUTETIMEPOSITION,
|
||||
A_ARG_TYPE_INSTANCE_ID,
|
||||
A_ARG_TYPE_PLAY_SPEED,
|
||||
A_ARG_TYPE_SEEKMODE,
|
||||
AVTRANSPORTNEXTURI,
|
||||
AVTRANSPORTNEXTURIMETADATA,
|
||||
AVTRANSPORTURI,
|
||||
AVTRANSPORTURIMETADATA,
|
||||
CURRENTMEDIADURATION,
|
||||
CURRENTPLAYMODE,
|
||||
CURRENTTRACK,
|
||||
CURRENTTRACKDURATION,
|
||||
CURRENTTRACKMETADATA,
|
||||
CURRENTTRACKURI,
|
||||
NUMBEROFTRACKS,
|
||||
PLAYBACKSTORAGEMEDIUM,
|
||||
POSSIBLEPLAYBACKSTORAGEMEDIA,
|
||||
RELATIVETIMEPOSITION,
|
||||
SEEKMODE,
|
||||
TRANSPORTPLAYSPEED,
|
||||
TRANSPORTSTATE,
|
||||
TRANSPORTSTATUS,
|
||||
],
|
||||
actions: [
|
||||
GETCURRENTTRANSPORTACTIONS,
|
||||
GETDEVICECAPABILITIES,
|
||||
GETMEDIAINFO,
|
||||
GETPOSITIONINFO,
|
||||
GETTRANSPORTINFO,
|
||||
GETTRANSPORTSETTINGS,
|
||||
NEXT,
|
||||
PAUSE,
|
||||
PLAY,
|
||||
PREVIOUS,
|
||||
SEEK,
|
||||
SETNEXTAVTRANSPORTURI,
|
||||
SETAVTRANSPORTURI,
|
||||
STOP,
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_INSTANCE_ID: UI4 = "A_ARG_TYPE_InstanceID"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_PLAY_SPEED: String = "A_ARG_TYPE_PlaySpeed"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_SEEKMODE: String = "A_ARG_TYPE_SeekMode" {
|
||||
allowed: ["TRACK_NR", "REL_TIME", "ABS_TIME"],
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static AVTRANSPORTURI: String = "AVTransportURI"
|
||||
}
|
||||
|
||||
define_variable! {
|
||||
pub static AVTRANSPORTNEXTURI: String = "AVTransportNextURI"
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::{StateVariable, StateVariableError};
|
||||
use crate::variable_types::StateVarType;
|
||||
use bevy_reflect::Reflect;
|
||||
use once_cell::sync::Lazy;
|
||||
use pmodidl::{DIDLLite, MediaMetadataParser};
|
||||
|
||||
|
||||
fn avtransporturimetadataparser(value: &str) -> Result<Box<dyn Reflect>, StateVariableError> {
|
||||
// Parse DIDL-Lite
|
||||
let didl = DIDLLite::parse(value)
|
||||
.map_err(|e| StateVariableError::ParseError(format!("Failed to parse DIDL-Lite: {}", e)))?;
|
||||
|
||||
// Retourne le résultat sous forme de Box<dyn Reflect>
|
||||
Ok(Box::new(didl) as Box<dyn Reflect>)
|
||||
}
|
||||
|
||||
pub static AVTRANSPORTURIMETADATA: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let mut sv = StateVariable::new(StateVarType::String, "AVTransportURIMetaData".to_string());
|
||||
|
||||
sv.set_value_parser(Arc::new(avtransporturimetadataparser)).expect("Failed to set parser");
|
||||
Arc::new(sv)
|
||||
});
|
||||
|
||||
pub static AVTRANSPORTNEXTURIMETADATA: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let mut sv = StateVariable::new(StateVarType::String, "AVTransportNextURIMetaData".to_string());
|
||||
|
||||
sv.set_value_parser(Arc::new(avtransporturimetadataparser)).expect("Failed to set parser");
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTMEDIADURATION: String = "CurrentMediaDuration"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTPLAYMODE: String = "CurrentPlayMode" {
|
||||
allowed: ["NORMAL", "SHUFFLE", "REPEAT_ONE", "REPEAT_ALL", "RANDOM", "DIRECT_1", "INTRO"],
|
||||
default: "NORMAL",
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTTRACKMETADATA: String = "CurrentTrackMetaData"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTTRACKURI: String = "CurrentTrackURI"
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
mod a_arg_type_instanceid;
|
||||
mod a_arg_type_playspeed;
|
||||
mod a_arg_type_seekmode;
|
||||
mod avtransporturi;
|
||||
mod avtransporturimetadata;
|
||||
mod currentmediaduration;
|
||||
mod currentplaymode;
|
||||
mod currenttrackmetadata;
|
||||
mod currenttrackuri;
|
||||
mod playbackstoragemedium;
|
||||
mod possibleplaybackstoragemedia;
|
||||
mod possiblerecordstoragemedia;
|
||||
mod recordstoragemedium;
|
||||
mod seekmode;
|
||||
mod track;
|
||||
mod trackduration;
|
||||
mod transportplayspeed;
|
||||
mod transportstate;
|
||||
mod transportstatus;
|
||||
|
||||
pub use a_arg_type_instanceid::A_ARG_TYPE_INSTANCE_ID;
|
||||
pub use a_arg_type_playspeed::A_ARG_TYPE_PLAY_SPEED;
|
||||
pub use a_arg_type_seekmode::A_ARG_TYPE_SEEKMODE;
|
||||
pub use avtransporturi::AVTRANSPORTURI;
|
||||
pub use avtransporturi::AVTRANSPORTNEXTURI;
|
||||
pub use avtransporturimetadata::AVTRANSPORTURIMETADATA;
|
||||
pub use avtransporturimetadata::AVTRANSPORTNEXTURIMETADATA;
|
||||
pub use currentmediaduration::CURRENTMEDIADURATION;
|
||||
pub use currentplaymode::CURRENTPLAYMODE;
|
||||
pub use currenttrackmetadata::CURRENTTRACKMETADATA;
|
||||
pub use currenttrackuri::CURRENTTRACKURI;
|
||||
pub use playbackstoragemedium::PLAYBACKSTORAGEMEDIUM;
|
||||
pub use possibleplaybackstoragemedia::POSSIBLEPLAYBACKSTORAGEMEDIA;
|
||||
pub use possiblerecordstoragemedia::POSSIBLERECORDSTORAGEMEDIA;
|
||||
pub use recordstoragemedium::RECORDSTORAGEMEDIUM;
|
||||
pub use seekmode::SEEKMODE;
|
||||
pub use track::CURRENTTRACK;
|
||||
pub use track::NUMBEROFTRACKS;
|
||||
pub use trackduration::ABSOLUTETIMEPOSITION;
|
||||
pub use trackduration::CURRENTTRACKDURATION;
|
||||
pub use trackduration::RELATIVETIMEPOSITION;
|
||||
pub use transportplayspeed::TRANSPORTPLAYSPEED;
|
||||
pub use transportstate::TRANSPORTSTATE;
|
||||
pub use transportstatus::TRANSPORTSTATUS;
|
||||
|
||||
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
// Valeurs pour un MediaRenderer audio uniquement (suppression des formats vidéo)
|
||||
define_variable! {
|
||||
pub static PLAYBACKSTORAGEMEDIUM: String = "PlaybackStorageMedium" {
|
||||
allowed: [
|
||||
"UNKNOWN", "CD-ROM", "CD-DA", "CD-R", "CD-RW", "SACD",
|
||||
"MD-AUDIO", "DVD-AUDIO", "DAT", "HDD", "NETWORK",
|
||||
"NONE", "NOT_IMPLEMENTED"
|
||||
],
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static POSSIBLEPLAYBACKSTORAGEMEDIA: String = "PossiblePlaybackStorageMedia"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::StateVarType;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static POSSIBLERECORDSTORAGEMEDIA: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let sv = StateVariable::new(StateVarType::String, "PossibleRecordStorageMedia".to_string());
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -1,10 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::StateVarType;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static RECORDSTORAGEMEDIUM: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let sv = StateVariable::new(StateVarType::String, "RecordStorageMedium".to_string());
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -1,6 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static SEEKMODE: String = "SeekMode"
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTTRACK: String = "CurrentTrack" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
|
||||
define_variable! {
|
||||
pub static NUMBEROFTRACKS: String = "NumberOfTracks" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTTRACKDURATION: String = "CurrentTrackDuration" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
|
||||
define_variable! {
|
||||
pub static ABSOLUTETIMEPOSITION: String = "AbsoluteTimePosition" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
|
||||
define_variable! {
|
||||
pub static RELATIVETIMEPOSITION: String = "RelativeTimePosition" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static TRANSPORTPLAYSPEED: String = "TransportPlaySpeed" {
|
||||
allowed: ["1"],
|
||||
default: "1",
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
// États pour un MediaRenderer audio uniquement (suppression des états d'enregistrement)
|
||||
define_variable! {
|
||||
pub static TRANSPORTSTATE: String = "TransportState" {
|
||||
allowed: ["STOPPED", "PLAYING", "TRANSITIONING", "PAUSED_PLAYBACK", "NO_MEDIA_PRESENT"],
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static TRANSPORTSTATUS: String = "TransportStatus" {
|
||||
allowed: ["OK", "ERROR_OCCURRED"],
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::mediarenderer::connectionmanager::variables::CURRENTCONNECTIONIDS;
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETCURRENTCONNECTIONIDS = "GetCurrentConnectionIDs" {
|
||||
out "ConnectionIDs" => CURRENTCONNECTIONIDS,
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
use crate::mediarenderer::connectionmanager::variables::{
|
||||
A_ARG_TYPE_CONNECTIONID, A_ARG_TYPE_RCSID, A_ARG_TYPE_AVTRANSPORTID,
|
||||
A_ARG_TYPE_PROTOCOLINFO, A_ARG_TYPE_DIRECTION, A_ARG_TYPE_CONNECTIONSTATUS
|
||||
};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETCURRENTCONNECTIONINFO = "GetCurrentConnectionInfo" {
|
||||
in "ConnectionID" => A_ARG_TYPE_CONNECTIONID,
|
||||
out "RcsID" => A_ARG_TYPE_RCSID,
|
||||
out "AVTransportID" => A_ARG_TYPE_AVTRANSPORTID,
|
||||
out "ProtocolInfo" => A_ARG_TYPE_PROTOCOLINFO,
|
||||
out "PeerConnectionManager" => A_ARG_TYPE_PROTOCOLINFO,
|
||||
out "PeerConnectionID" => A_ARG_TYPE_CONNECTIONID,
|
||||
out "Direction" => A_ARG_TYPE_DIRECTION,
|
||||
out "Status" => A_ARG_TYPE_CONNECTIONSTATUS,
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
use crate::mediarenderer::connectionmanager::variables::{SOURCEPROTOCOLINFO, SINKPROTOCOLINFO};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETPROTOCOLINFO = "GetProtocolInfo" {
|
||||
out "Source" => SOURCEPROTOCOLINFO,
|
||||
out "Sink" => SINKPROTOCOLINFO,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
mod getprotocolinfo;
|
||||
mod getcurrentconnectionids;
|
||||
mod getcurrentconnectioninfo;
|
||||
|
||||
pub use getprotocolinfo::GETPROTOCOLINFO;
|
||||
pub use getcurrentconnectionids::GETCURRENTCONNECTIONIDS;
|
||||
pub use getcurrentconnectioninfo::GETCURRENTCONNECTIONINFO;
|
||||
@@ -1,89 +0,0 @@
|
||||
//! # ConnectionManager Service - Service de gestion des connexions UPnP
|
||||
//!
|
||||
//! Ce module implémente le service ConnectionManager:1 selon la spécification UPnP AV.
|
||||
//! Le service ConnectionManager gère les connexions entre MediaServer et MediaRenderer,
|
||||
//! et expose les protocoles et formats supportés.
|
||||
//!
|
||||
//! ## Fonctionnalités
|
||||
//!
|
||||
//! Le service ConnectionManager permet :
|
||||
//! - **Énumération des protocoles** : GetProtocolInfo
|
||||
//! - **Gestion des connexions** : GetCurrentConnectionIDs, GetCurrentConnectionInfo
|
||||
//! - Support des formats audio (MP3, FLAC, WAV, etc.)
|
||||
//!
|
||||
//! ## Conformité UPnP
|
||||
//!
|
||||
//! Cette implémentation suit la spécification **UPnP ConnectionManager:1 Service Template**.
|
||||
//! Toutes les actions obligatoires (Required) sont implémentées :
|
||||
//!
|
||||
//! - ✅ GetProtocolInfo
|
||||
//! - ✅ GetCurrentConnectionIDs
|
||||
//! - ✅ GetCurrentConnectionInfo
|
||||
//!
|
||||
//! ## Variables d'état
|
||||
//!
|
||||
//! Le service expose les variables d'état conformes à la spécification :
|
||||
//!
|
||||
//! ### Informations de protocole
|
||||
//! - [`SOURCEPROTOCOLINFO`] : Protocoles source (vide pour un renderer)
|
||||
//! - [`SINKPROTOCOLINFO`] : Protocoles sink supportés (http-get:*:audio/mpeg:*, etc.)
|
||||
//! - [`CURRENTCONNECTIONIDS`] : IDs des connexions actives
|
||||
//!
|
||||
//! ### Arguments
|
||||
//! - [`A_ARG_TYPE_CONNECTIONID`] : ID de connexion
|
||||
//! - [`A_ARG_TYPE_CONNECTIONSTATUS`] : Statut de connexion
|
||||
//! - [`A_ARG_TYPE_DIRECTION`] : Direction (Input/Output)
|
||||
//! - [`A_ARG_TYPE_PROTOCOLINFO`] : Information de protocole
|
||||
//! - [`A_ARG_TYPE_RCSID`] : ID RenderingControl
|
||||
//! - [`A_ARG_TYPE_AVTRANSPORTID`] : ID AVTransport
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! use pmoupnp::mediarenderer::connectionmanager::CONNECTIONMANAGER;
|
||||
//!
|
||||
//! // Accéder au service
|
||||
//! let service = &*CONNECTIONMANAGER;
|
||||
//! println!("Service: {}", service.name());
|
||||
//! println!("Type: {}", service.service_type());
|
||||
//! ```
|
||||
//!
|
||||
//! ## Références
|
||||
//!
|
||||
//! - [UPnP ConnectionManager:1 Service Template](https://upnp.org/specs/av/UPnP-av-ConnectionManager-v1-Service.pdf)
|
||||
//! - [UPnP AV Architecture](https://upnp.org/specs/av/)
|
||||
|
||||
use crate::define_service;
|
||||
|
||||
pub mod variables;
|
||||
pub mod actions;
|
||||
|
||||
use actions::{GETCURRENTCONNECTIONIDS, GETCURRENTCONNECTIONINFO, GETPROTOCOLINFO};
|
||||
use variables::{
|
||||
A_ARG_TYPE_AVTRANSPORTID, A_ARG_TYPE_CONNECTIONID, A_ARG_TYPE_CONNECTIONSTATUS,
|
||||
A_ARG_TYPE_DIRECTION, A_ARG_TYPE_PROTOCOLINFO, A_ARG_TYPE_RCSID,
|
||||
CURRENTCONNECTIONIDS, SINKPROTOCOLINFO, SOURCEPROTOCOLINFO
|
||||
};
|
||||
|
||||
// Service ConnectionManager:1 conforme à la spécification UPnP AV pour MediaRenderer audio
|
||||
// Voir la documentation du module pour plus de détails
|
||||
define_service! {
|
||||
pub static CONNECTIONMANAGER = "ConnectionManager" {
|
||||
variables: [
|
||||
A_ARG_TYPE_AVTRANSPORTID,
|
||||
A_ARG_TYPE_CONNECTIONID,
|
||||
A_ARG_TYPE_CONNECTIONSTATUS,
|
||||
A_ARG_TYPE_DIRECTION,
|
||||
A_ARG_TYPE_PROTOCOLINFO,
|
||||
A_ARG_TYPE_RCSID,
|
||||
CURRENTCONNECTIONIDS,
|
||||
SINKPROTOCOLINFO,
|
||||
SOURCEPROTOCOLINFO,
|
||||
],
|
||||
actions: [
|
||||
GETCURRENTCONNECTIONIDS,
|
||||
GETCURRENTCONNECTIONINFO,
|
||||
GETPROTOCOLINFO,
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_AVTRANSPORTID: I4 = "A_ARG_TYPE_AVTransportID"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_CONNECTIONID: I4 = "A_ARG_TYPE_ConnectionID"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_CONNECTIONSTATUS: String = "A_ARG_TYPE_ConnectionStatus" {
|
||||
allowed: ["OK", "ContentFormatMismatch", "InsufficientBandwidth", "UnreliableChannel", "Unknown"],
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_DIRECTION: String = "A_ARG_TYPE_Direction" {
|
||||
allowed: ["Input", "Output"],
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_PROTOCOLINFO: String = "A_ARG_TYPE_ProtocolInfo"
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_RCSID: I4 = "A_ARG_TYPE_RcsID"
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static CURRENTCONNECTIONIDS: String = "CurrentConnectionIDs" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
mod sourceprotocolinfo;
|
||||
mod sinkprotocolinfo;
|
||||
mod currentconnectionids;
|
||||
mod a_arg_type_connectionid;
|
||||
mod a_arg_type_connectionstatus;
|
||||
mod a_arg_type_direction;
|
||||
mod a_arg_type_protocolinfo;
|
||||
mod a_arg_type_rcsid;
|
||||
mod a_arg_type_avtransportid;
|
||||
|
||||
pub use sourceprotocolinfo::SOURCEPROTOCOLINFO;
|
||||
pub use sinkprotocolinfo::SINKPROTOCOLINFO;
|
||||
pub use currentconnectionids::CURRENTCONNECTIONIDS;
|
||||
pub use a_arg_type_connectionid::A_ARG_TYPE_CONNECTIONID;
|
||||
pub use a_arg_type_connectionstatus::A_ARG_TYPE_CONNECTIONSTATUS;
|
||||
pub use a_arg_type_direction::A_ARG_TYPE_DIRECTION;
|
||||
pub use a_arg_type_protocolinfo::A_ARG_TYPE_PROTOCOLINFO;
|
||||
pub use a_arg_type_rcsid::A_ARG_TYPE_RCSID;
|
||||
pub use a_arg_type_avtransportid::A_ARG_TYPE_AVTRANSPORTID;
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
// Pour un MediaRenderer audio, liste les protocoles/formats audio supportés
|
||||
define_variable! {
|
||||
pub static SINKPROTOCOLINFO: String = "SinkProtocolInfo" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static SOURCEPROTOCOLINFO: String = "SourceProtocolInfo" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
//! Définition du device MediaRenderer.
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::{
|
||||
devices::Device,
|
||||
mediarenderer::{
|
||||
avtransport::AVTTRANSPORT,
|
||||
renderingcontrol::RENDERINGCONTROL,
|
||||
connectionmanager::CONNECTIONMANAGER,
|
||||
},
|
||||
};
|
||||
|
||||
/// Device MediaRenderer UPnP.
|
||||
///
|
||||
/// MediaRenderer audio-only conforme UPnP AV Architecture 1.0.
|
||||
///
|
||||
/// # Services inclus
|
||||
///
|
||||
/// - **AVTransport:1** : Contrôle de la lecture
|
||||
/// - **RenderingControl:1** : Contrôle du volume et du mute
|
||||
/// - **ConnectionManager:1** : Gestion des connexions
|
||||
///
|
||||
/// # Spécifications
|
||||
///
|
||||
/// - Device Type : `urn:schemas-upnp-org:device:MediaRenderer:1`
|
||||
/// - Version : 1
|
||||
/// - Manufacturer : PMOMusic
|
||||
/// - Model : PMOMusic Audio Renderer
|
||||
///
|
||||
/// # Exemple
|
||||
///
|
||||
/// ```ignore
|
||||
/// use pmoupnp::mediarenderer::MEDIA_RENDERER;
|
||||
/// use pmoupnp::UpnpModel;
|
||||
///
|
||||
/// // Créer une instance du renderer
|
||||
/// let renderer_instance = MEDIA_RENDERER.create_instance();
|
||||
///
|
||||
/// // Accéder aux services
|
||||
/// if let Some(avtransport) = renderer_instance.get_service("AVTransport") {
|
||||
/// // Contrôler la lecture...
|
||||
/// }
|
||||
/// ```
|
||||
pub static MEDIA_RENDERER: Lazy<Arc<Device>> = Lazy::new(|| {
|
||||
let mut device = Device::new(
|
||||
"MediaRenderer".to_string(),
|
||||
"MediaRenderer".to_string(),
|
||||
"PMOMusic Audio Renderer".to_string(),
|
||||
);
|
||||
|
||||
device.set_manufacturer("PMOMusic".to_string());
|
||||
device.set_model_name("PMOMusic Audio Renderer".to_string());
|
||||
device.set_model_description("UPnP AV MediaRenderer for audio streaming".to_string());
|
||||
device.set_udn_prefix("pmomusic".to_string());
|
||||
|
||||
// Ajouter les trois services obligatoires
|
||||
device.add_service(Arc::clone(&AVTTRANSPORT))
|
||||
.expect("Failed to add AVTransport service");
|
||||
|
||||
device.add_service(Arc::clone(&RENDERINGCONTROL))
|
||||
.expect("Failed to add RenderingControl service");
|
||||
|
||||
device.add_service(Arc::clone(&CONNECTIONMANAGER))
|
||||
.expect("Failed to add ConnectionManager service");
|
||||
|
||||
Arc::new(device)
|
||||
});
|
||||
@@ -1,35 +0,0 @@
|
||||
//! Module MediaRenderer UPnP.
|
||||
//!
|
||||
//! Ce module implémente un MediaRenderer UPnP audio-only conforme à la spécification
|
||||
//! UPnP AV Architecture. Un MediaRenderer permet de recevoir et lire du contenu audio
|
||||
//! depuis un serveur UPnP (MediaServer).
|
||||
//!
|
||||
//! # Architecture
|
||||
//!
|
||||
//! Le MediaRenderer est composé de trois services obligatoires :
|
||||
//!
|
||||
//! - **AVTransport** : Contrôle de la lecture (play, pause, stop, seek, etc.)
|
||||
//! - **RenderingControl** : Contrôle du volume et du mute
|
||||
//! - **ConnectionManager** : Gestion des connexions et des protocoles supportés
|
||||
//!
|
||||
//! # Device UPnP
|
||||
//!
|
||||
//! - Type : `urn:schemas-upnp-org:device:MediaRenderer:1`
|
||||
//! - Services : AVTransport:1, RenderingControl:1, ConnectionManager:1
|
||||
//!
|
||||
//! # Utilisation
|
||||
//!
|
||||
//! ```ignore
|
||||
//! use pmoupnp::mediarenderer::MEDIA_RENDERER;
|
||||
//!
|
||||
//! // Le device est déjà configuré avec tous ses services
|
||||
//! let renderer = MEDIA_RENDERER.clone();
|
||||
//! let instance = renderer.create_instance();
|
||||
//! ```
|
||||
|
||||
pub mod avtransport;
|
||||
pub mod connectionmanager;
|
||||
pub mod renderingcontrol;
|
||||
pub mod device;
|
||||
|
||||
pub use device::MEDIA_RENDERER;
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::renderingcontrol::variables::{A_ARG_TYPE_INSTANCE_ID, A_ARG_TYPE_CHANNEL, MUTE};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETMUTE = "GetMute" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "Channel" => A_ARG_TYPE_CHANNEL,
|
||||
out "CurrentMute" => MUTE,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::renderingcontrol::variables::{A_ARG_TYPE_INSTANCE_ID, A_ARG_TYPE_CHANNEL, VOLUME};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static GETVOLUME = "GetVolume" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "Channel" => A_ARG_TYPE_CHANNEL,
|
||||
out "CurrentVolume" => VOLUME,
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
mod getvolume;
|
||||
mod setvolume;
|
||||
mod getmute;
|
||||
mod setmute;
|
||||
|
||||
pub use getvolume::GETVOLUME;
|
||||
pub use setvolume::SETVOLUME;
|
||||
pub use getmute::GETMUTE;
|
||||
pub use setmute::SETMUTE;
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::renderingcontrol::variables::{A_ARG_TYPE_INSTANCE_ID, A_ARG_TYPE_CHANNEL, MUTE};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static SETMUTE = "SetMute" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "Channel" => A_ARG_TYPE_CHANNEL,
|
||||
in "DesiredMute" => MUTE,
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
use crate::mediarenderer::renderingcontrol::variables::{A_ARG_TYPE_INSTANCE_ID, A_ARG_TYPE_CHANNEL, VOLUME};
|
||||
use crate::define_action;
|
||||
|
||||
define_action! {
|
||||
pub static SETVOLUME = "SetVolume" {
|
||||
in "InstanceID" => A_ARG_TYPE_INSTANCE_ID,
|
||||
in "Channel" => A_ARG_TYPE_CHANNEL,
|
||||
in "DesiredVolume" => VOLUME,
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
//! # RenderingControl Service - Service de contrôle du rendu audio UPnP
|
||||
//!
|
||||
//! Ce module implémente le service RenderingControl:1 selon la spécification UPnP AV.
|
||||
//! Le service RenderingControl permet de contrôler les paramètres de rendu audio
|
||||
//! (volume, mute, etc.) sur un MediaRenderer.
|
||||
//!
|
||||
//! ## Fonctionnalités
|
||||
//!
|
||||
//! Le service RenderingControl permet :
|
||||
//! - **Contrôle du volume** : GetVolume, SetVolume
|
||||
//! - **Contrôle du mute** : GetMute, SetMute
|
||||
//! - Support multi-canal (Master, LF, RF)
|
||||
//!
|
||||
//! ## Conformité UPnP
|
||||
//!
|
||||
//! Cette implémentation suit la spécification **UPnP RenderingControl:1 Service Template**.
|
||||
//! Toutes les actions obligatoires (Required) sont implémentées :
|
||||
//!
|
||||
//! - ✅ GetVolume
|
||||
//! - ✅ SetVolume
|
||||
//! - ✅ GetMute
|
||||
//! - ✅ SetMute
|
||||
//!
|
||||
//! ## Variables d'état
|
||||
//!
|
||||
//! Le service expose les variables d'état conformes à la spécification :
|
||||
//!
|
||||
//! ### Contrôle audio
|
||||
//! - [`VOLUME`] : Niveau de volume (0-100)
|
||||
//! - [`MUTE`] : État mute (true/false)
|
||||
//!
|
||||
//! ### Arguments
|
||||
//! - [`A_ARG_TYPE_INSTANCE_ID`] : ID d'instance
|
||||
//! - [`A_ARG_TYPE_CHANNEL`] : Canal audio (Master, LF, RF)
|
||||
//!
|
||||
//! ## Examples
|
||||
//!
|
||||
//! ```rust
|
||||
//! use pmoupnp::mediarenderer::renderingcontrol::RENDERINGCONTROL;
|
||||
//!
|
||||
//! // Accéder au service
|
||||
//! let service = &*RENDERINGCONTROL;
|
||||
//! println!("Service: {}", service.name());
|
||||
//! println!("Type: {}", service.service_type());
|
||||
//! ```
|
||||
//!
|
||||
//! ## Références
|
||||
//!
|
||||
//! - [UPnP RenderingControl:1 Service Template](https://upnp.org/specs/av/UPnP-av-RenderingControl-v1-Service.pdf)
|
||||
//! - [UPnP AV Architecture](https://upnp.org/specs/av/)
|
||||
|
||||
use crate::define_service;
|
||||
|
||||
pub mod variables;
|
||||
pub mod actions;
|
||||
|
||||
use actions::{GETMUTE, GETVOLUME, SETMUTE, SETVOLUME};
|
||||
use variables::{A_ARG_TYPE_CHANNEL, A_ARG_TYPE_INSTANCE_ID, MUTE, VOLUME};
|
||||
|
||||
// Service RenderingControl:1 conforme à la spécification UPnP AV pour MediaRenderer audio
|
||||
// Voir la documentation du module pour plus de détails
|
||||
define_service! {
|
||||
pub static RENDERINGCONTROL = "RenderingControl" {
|
||||
variables: [
|
||||
A_ARG_TYPE_CHANNEL,
|
||||
A_ARG_TYPE_INSTANCE_ID,
|
||||
MUTE,
|
||||
VOLUME,
|
||||
],
|
||||
actions: [
|
||||
GETMUTE,
|
||||
GETVOLUME,
|
||||
SETMUTE,
|
||||
SETVOLUME,
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_CHANNEL: String = "A_ARG_TYPE_Channel" {
|
||||
allowed: ["Master", "LF", "RF"],
|
||||
default: "Master",
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static A_ARG_TYPE_INSTANCE_ID: UI4 = "A_ARG_TYPE_InstanceID"
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
mod a_arg_type_instanceid;
|
||||
mod a_arg_type_channel;
|
||||
mod volume;
|
||||
mod mute;
|
||||
|
||||
pub use a_arg_type_instanceid::A_ARG_TYPE_INSTANCE_ID;
|
||||
pub use a_arg_type_channel::A_ARG_TYPE_CHANNEL;
|
||||
pub use volume::VOLUME;
|
||||
pub use mute::MUTE;
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static MUTE: Boolean = "Mute" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
use crate::define_variable;
|
||||
|
||||
define_variable! {
|
||||
pub static VOLUME: UI2 = "Volume" {
|
||||
evented: true,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user