+ Media: {output.media?.session?.title} -
+ {output.media?.session?.artist}
+
Battery charge: {output.battery?.chargePercent}
diff --git a/packages/client-api/src/providers/media/create-media-provider.ts b/packages/client-api/src/providers/media/create-media-provider.ts
index 7ae68159..0398bbad 100644
--- a/packages/client-api/src/providers/media/create-media-provider.ts
+++ b/packages/client-api/src/providers/media/create-media-provider.ts
@@ -9,7 +9,6 @@ import type {
const mediaProviderConfigSchema = z.object({
type: z.literal('media'),
- refreshInterval: z.coerce.number().default(5 * 1000),
});
export function createMediaProvider(
diff --git a/packages/client-api/src/providers/media/media-provider-types.ts b/packages/client-api/src/providers/media/media-provider-types.ts
index 77ecd6a2..b6bb1695 100644
--- a/packages/client-api/src/providers/media/media-provider-types.ts
+++ b/packages/client-api/src/providers/media/media-provider-types.ts
@@ -5,10 +5,14 @@ export interface MediaProviderConfig {
}
export interface MediaOutput {
+ session: MediaSession | null;
+}
+
+export interface MediaSession {
title: string;
- artist: string;
- albumTitle: string;
- albumArtist: string;
+ artist: string | null;
+ albumTitle: string | null;
+ albumArtist: string | null;
trackNumber: number;
startTime: number;
endTime: number;
diff --git a/packages/desktop/src/providers/media/media_provider.rs b/packages/desktop/src/providers/media/media_provider.rs
index 4719a5c7..e3f80974 100644
--- a/packages/desktop/src/providers/media/media_provider.rs
+++ b/packages/desktop/src/providers/media/media_provider.rs
@@ -5,14 +5,14 @@ use std::{
use async_trait::async_trait;
use serde::{Deserialize, Serialize};
-use tokio::sync::mpsc::Sender;
-use tracing::debug;
+use tokio::{sync::mpsc::Sender, task};
+use tracing::{debug, error};
use windows::{
Foundation::{EventRegistrationToken, TypedEventHandler},
Media::Control::{
- GlobalSystemMediaTransportControlsSession as MediaSession,
- GlobalSystemMediaTransportControlsSessionManager as MediaManager,
- GlobalSystemMediaTransportControlsSessionPlaybackStatus as MediaPlaybackStatus,
+ GlobalSystemMediaTransportControlsSession as GsmtcSession,
+ GlobalSystemMediaTransportControlsSessionManager as GsmtcManager,
+ GlobalSystemMediaTransportControlsSessionPlaybackStatus as GsmtcPlaybackStatus,
},
};
@@ -25,10 +25,16 @@ pub struct MediaProviderConfig {}
#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct MediaOutput {
+ pub session: Option
,
+}
+
+#[derive(Debug, Clone, PartialEq, Serialize)]
+#[serde(rename_all = "camelCase")]
+pub struct MediaSession {
pub title: String,
- pub artist: String,
- pub album_title: String,
- pub album_artist: String,
+ pub artist: Option,
+ pub album_title: Option,
+ pub album_artist: Option,
pub track_number: u32,
pub start_time: u64,
pub end_time: u64,
@@ -45,36 +51,58 @@ struct EventTokens {
pub struct MediaProvider {
_config: MediaProviderConfig,
- current_session: Arc>>,
- event_tokens: Arc>>,
}
impl MediaProvider {
pub fn new(config: MediaProviderConfig) -> MediaProvider {
- MediaProvider {
- _config: config,
- current_session: Arc::new(Mutex::new(None)),
- event_tokens: Arc::new(Mutex::new(None)),
- }
+ MediaProvider { _config: config }
}
fn emit_media_info(
- session: &MediaSession,
+ session: Option<&GsmtcSession>,
emit_result_tx: Sender,
) {
- if let Ok(media_output) = Self::media_output(session) {
- let _ = emit_result_tx
- .try_send(Ok(ProviderOutput::Media(media_output)).into());
- }
+ let _ = match Self::media_output(session) {
+ Ok(media_output) => emit_result_tx
+ .blocking_send(Ok(ProviderOutput::Media(media_output)).into()),
+ Err(err) => {
+ error!("Error retrieving media output: {:?}", err);
+ emit_result_tx.blocking_send(Err(err).into())
+ }
+ };
}
- fn media_output(session: &MediaSession) -> anyhow::Result {
+ fn media_output(
+ session: Option<&GsmtcSession>,
+ ) -> anyhow::Result {
+ Ok(MediaOutput {
+ session: match session {
+ Some(session) => Self::media_session(session)?,
+ None => None,
+ },
+ })
+ }
+
+ fn media_session(
+ session: &GsmtcSession,
+ ) -> anyhow::Result