push-qsztxxtruxvo #12
@@ -0,0 +1,8 @@
|
||||
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,3 +1,4 @@
|
||||
mod getcurrenttransportactions;
|
||||
mod getdevicecapabilities;
|
||||
mod getmediainfo;
|
||||
mod getpositioninfo;
|
||||
@@ -12,6 +13,7 @@ mod setavtransportnexturi;
|
||||
mod setavtransporturi;
|
||||
mod stop;
|
||||
|
||||
pub use getcurrenttransportactions::GETCURRENTTRANSPORTACTIONS;
|
||||
pub use getdevicecapabilities::GETDEVICECAPABILITIES;
|
||||
pub use getmediainfo::GETMEDIAINFO;
|
||||
pub use getpositioninfo::GETPOSITIONINFO;
|
||||
|
||||
@@ -1,21 +1,137 @@
|
||||
//! # 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;
|
||||
//!
|
||||
//! // 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::{
|
||||
GETDEVICECAPABILITIES, GETMEDIAINFO, GETPOSITIONINFO, GETTRANSPORTINFO,
|
||||
GETTRANSPORTSETTINGS, NEXT, PAUSE, PLAY, PREVIOUS, SEEK,
|
||||
SETNEXTAVTRANSPORTURI, SETAVTRANSPORTURI, STOP
|
||||
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, CURRENTTRACK,
|
||||
CURRENTTRACKDURATION, NUMBEROFTRACKS, RELATIVETIMEPOSITION, SEEKMODE,
|
||||
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.
|
||||
///
|
||||
/// Ce service permet de contrôler le transport de médias **audio** sur un MediaRenderer.
|
||||
///
|
||||
/// # Initialisation
|
||||
///
|
||||
/// Le service est initialisé paresseusement (lazy) au premier accès via la macro
|
||||
/// [`define_service!`]. Toutes les variables d'état et actions sont automatiquement
|
||||
/// enregistrées.
|
||||
///
|
||||
/// # Exemples
|
||||
///
|
||||
/// ```rust
|
||||
/// use pmoupnp::mediarenderer::avtransport::AVTTRANSPORT;
|
||||
///
|
||||
/// let service = &*AVTTRANSPORT;
|
||||
/// assert_eq!(service.name(), "AVTransport");
|
||||
/// assert_eq!(service.version(), 1);
|
||||
/// ```
|
||||
///
|
||||
/// # Voir aussi
|
||||
///
|
||||
/// - Module [`actions`] : Définition de toutes les actions UPnP
|
||||
/// - Module [`variables`] : Définition de toutes les variables d'état
|
||||
define_service! {
|
||||
pub static AVTTRANSPORT = "AVTransport" {
|
||||
variables: [
|
||||
@@ -27,9 +143,15 @@ define_service! {
|
||||
AVTRANSPORTNEXTURIMETADATA,
|
||||
AVTRANSPORTURI,
|
||||
AVTRANSPORTURIMETADATA,
|
||||
CURRENTMEDIADURATION,
|
||||
CURRENTPLAYMODE,
|
||||
CURRENTTRACK,
|
||||
CURRENTTRACKDURATION,
|
||||
CURRENTTRACKMETADATA,
|
||||
CURRENTTRACKURI,
|
||||
NUMBEROFTRACKS,
|
||||
PLAYBACKSTORAGEMEDIUM,
|
||||
POSSIBLEPLAYBACKSTORAGEMEDIA,
|
||||
RELATIVETIMEPOSITION,
|
||||
SEEKMODE,
|
||||
TRANSPORTPLAYSPEED,
|
||||
@@ -37,6 +159,7 @@ define_service! {
|
||||
TRANSPORTSTATUS,
|
||||
],
|
||||
actions: [
|
||||
GETCURRENTTRANSPORTACTIONS,
|
||||
GETDEVICECAPABILITIES,
|
||||
GETMEDIAINFO,
|
||||
GETPOSITIONINFO,
|
||||
|
||||
@@ -5,13 +5,13 @@ use crate::variable_types::{StateValue, StateVarType};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static A_ARG_TYPE_SEEKMODE: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let mut sv = StateVariable::new(StateVarType::UI4, "A_ARG_TYPE_SeekMode".to_string());
|
||||
let mut sv = StateVariable::new(StateVarType::String, "A_ARG_TYPE_SeekMode".to_string());
|
||||
|
||||
sv.extend_allowed_values(&[
|
||||
sv.extend_allowed_values(&[
|
||||
StateValue::String("TRACK_NR".to_string()),
|
||||
StateValue::String("REL_TIME".to_string()),
|
||||
StateValue::String("ABS_TIME".to_string()),
|
||||
]).expect("Cannot set default value");
|
||||
]).expect("Cannot set allowed values");
|
||||
|
||||
Arc::new(sv)
|
||||
});
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::StateVarType;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static CURRENTMEDIADURATION: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let sv = StateVariable::new(StateVarType::String, "CurrentMediaDuration".to_string());
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -0,0 +1,24 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::{StateValue, StateVarType};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static CURRENTPLAYMODE: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let mut sv = StateVariable::new(StateVarType::String, "CurrentPlayMode".to_string());
|
||||
|
||||
sv.extend_allowed_values(&[
|
||||
StateValue::String("NORMAL".to_string()),
|
||||
StateValue::String("SHUFFLE".to_string()),
|
||||
StateValue::String("REPEAT_ONE".to_string()),
|
||||
StateValue::String("REPEAT_ALL".to_string()),
|
||||
StateValue::String("RANDOM".to_string()),
|
||||
StateValue::String("DIRECT_1".to_string()),
|
||||
StateValue::String("INTRO".to_string()),
|
||||
]).expect("Cannot set allowed values");
|
||||
|
||||
sv.set_default(&StateValue::String("NORMAL".to_string()))
|
||||
.expect("Cannot set default value");
|
||||
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::StateVarType;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static CURRENTTRACKMETADATA: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let sv = StateVariable::new(StateVarType::String, "CurrentTrackMetaData".to_string());
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::StateVarType;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static CURRENTTRACKURI: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let sv = StateVariable::new(StateVarType::String, "CurrentTrackURI".to_string());
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -3,9 +3,17 @@ 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 seekmode;
|
||||
mod transportplayspeed;
|
||||
mod transportstate;
|
||||
mod transportstatus;
|
||||
@@ -17,12 +25,20 @@ 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::CURRENTTRACKDURATION;
|
||||
pub use trackduration::ABSOLUTETIMEPOSITION;
|
||||
pub use trackduration::CURRENTTRACKDURATION;
|
||||
pub use trackduration::RELATIVETIMEPOSITION;
|
||||
pub use seekmode::SEEKMODE;
|
||||
pub use transportplayspeed::TRANSPORTPLAYSPEED;
|
||||
pub use transportstate::TRANSPORTSTATE;
|
||||
pub use transportstatus::TRANSPORTSTATUS;
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::{StateValue, StateVarType};
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static PLAYBACKSTORAGEMEDIUM: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let mut sv = StateVariable::new(StateVarType::String, "PlaybackStorageMedium".to_string());
|
||||
|
||||
// Valeurs pour un MediaRenderer audio uniquement (suppression des formats vidéo)
|
||||
sv.extend_allowed_values(&[
|
||||
StateValue::String("UNKNOWN".to_string()),
|
||||
StateValue::String("CD-ROM".to_string()),
|
||||
StateValue::String("CD-DA".to_string()),
|
||||
StateValue::String("CD-R".to_string()),
|
||||
StateValue::String("CD-RW".to_string()),
|
||||
StateValue::String("SACD".to_string()),
|
||||
StateValue::String("MD-AUDIO".to_string()),
|
||||
StateValue::String("DVD-AUDIO".to_string()),
|
||||
StateValue::String("DAT".to_string()),
|
||||
StateValue::String("HDD".to_string()),
|
||||
StateValue::String("NETWORK".to_string()),
|
||||
StateValue::String("NONE".to_string()),
|
||||
StateValue::String("NOT_IMPLEMENTED".to_string()),
|
||||
]).expect("Cannot set allowed values");
|
||||
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::state_variables::StateVariable;
|
||||
use crate::variable_types::StateVarType;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub static POSSIBLEPLAYBACKSTORAGEMEDIA: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let sv = StateVariable::new(StateVarType::String, "PossiblePlaybackStorageMedia".to_string());
|
||||
Arc::new(sv)
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
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)
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
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)
|
||||
});
|
||||
@@ -7,16 +7,15 @@ use once_cell::sync::Lazy;
|
||||
pub static TRANSPORTSTATE: Lazy<Arc<StateVariable>> = Lazy::new(|| -> Arc<StateVariable> {
|
||||
let mut sv = StateVariable::new(StateVarType::String, "TransportState".to_string());
|
||||
|
||||
sv.extend_allowed_values(&[
|
||||
// États pour un MediaRenderer audio uniquement (suppression des états d'enregistrement)
|
||||
sv.extend_allowed_values(&[
|
||||
StateValue::String("STOPPED".to_string()),
|
||||
StateValue::String("PLAYING".to_string()),
|
||||
StateValue::String("RECORDING".to_string()),
|
||||
StateValue::String("TRANSITIONING".to_string()),
|
||||
StateValue::String("PAUSED_PLAYBACK".to_string()),
|
||||
StateValue::String("PAUSED_RECORDING".to_string()),
|
||||
StateValue::String("NO_MEDIA_PRESENT".to_string()),
|
||||
]).expect("Cannt set default value");
|
||||
|
||||
StateValue::String("NO_MEDIA_PRESENT".to_string()),
|
||||
]).expect("Cannot set allowed values");
|
||||
|
||||
sv.set_send_notification();
|
||||
|
||||
Arc::new(sv)
|
||||
|
||||
Reference in New Issue
Block a user