Je laisse Claude faire ses modification sur avtransport

This commit is contained in:
2025-10-05 20:34:04 +02:00
parent cf0f6ea9e0
commit 7dbacd0112
14 changed files with 277 additions and 17 deletions

View File

@@ -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,
}
}

View File

@@ -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;

View File

@@ -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,

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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;

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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)
});

View File

@@ -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)