Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 17 additions & 11 deletions config/scripts.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,19 +37,17 @@ local function volume()
}
end

-- 5s duration on Windows due to an issue mentioned in oled-applications/media/README.md
local SPOTIFY_DURATION = PLATFORM.Os == 'windows' and 5000 or 1000
local function spotify()
local function media(source)
return {
widgets = {
Widget.Bar {
value = SPOTIFY.Progress,
range = { min = 0, max = SPOTIFY.Duration },
value = source.Progress,
range = { min = 0, max = source.Duration },
position = { x = 0, y = 0 },
size = { width = SCREEN.Width, height = 2 },
},
Widget.Text {
text = string.format("%s - %s", SPOTIFY.Artist, SPOTIFY.Title),
text = string.format("%s - %s", source.Artist, source.Title),
scrolling = true,
position = { x = 0, y = 2 },
size = { width = SCREEN.Width, height = 20 },
Expand All @@ -71,7 +69,18 @@ local function spotify()
size = { width = SCREEN.Width, height = 2 },
},
},
duration = SPOTIFY_DURATION,
duration = 1000,
}
end

function make_media_layout(source)
return {
layout = function() return media(_ENV[source]) end,
run_on = {
string.format('%s.Artist', source),
string.format('%s.Progress', source),
string.format('%s.Title', source)
},
}
end

Expand Down Expand Up @@ -161,10 +170,7 @@ SCREEN_BUILDER
layout = volume,
run_on = { 'AUDIO.Input', 'AUDIO.Output' },
},
{
layout = spotify,
run_on = { 'SPOTIFY.Artist', 'SPOTIFY.Progress', 'SPOTIFY.Title' },
},
make_media_layout('MEDIA'),
{
layout = clock,
run_on = { 'CLOCK.Seconds' },
Expand Down
27 changes: 14 additions & 13 deletions omni-led-applications/media/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Media

Media application provides information about currently playing media, e.g. title, artist, duration etc.
Media application provides information about currently playing media, e.g., title, artist, duration, etc.

## Running

Expand All @@ -14,13 +14,13 @@ Media expects three arguments
- `a`/`address` - server address
- Optional:
- `m`/`mode` - reporting mode - `individual`, `focused` or `both`.
Default: `both`.
Described in [reporting mode](#reporting-mode).
Default: `both`.
Described in [reporting mode](#reporting-mode).
- `map` - map input application name to an event name, e.g. `--map "my_app_name=APP"`. Can be passed multiple
times. Target name must be an uppercase alphanumeric string, that can contain underscores and cannot start with a
number.
Default: `[]`.
Describen in [application name mapping](#application-name-mapping).
times. Target name must be an uppercase alphanumeric string that can contain underscores and cannot start with a
number.
Default: `[]`.
Described in [application name mapping](#application-name-mapping).

## Reporting mode

Expand All @@ -36,15 +36,15 @@ All updates will be sent with event name `MEDIA`, regardless of source applicati

### Both

Report events in both ways - individual per application and combined for currently focused application.
Report events in both ways individual per application and combined for currently focused application.

## Application name mapping

When sending events in [individual](#individual) mode, application names will be mapped to event names.
If mapping was provided as a command line parameter, then it will use the target name from that mapping.
If mapping was not provided, source application name will be converted in the following manner:
If mapping was not provided, the source application name will be converted in the following manner:

- If name starts with a digit it will be prefixed with an underscore.
- If the name starts with a digit, it will be prefixed with an underscore.
- All ascii letters will be converted to uppercase.
- All non-alphanumeric characters will be converted to underscores.

Expand All @@ -63,10 +63,10 @@ Examples:

Media sends a single type of event, and its name depends on the selected [mode](#reporting-mode).

> There is a discrepancy in event frequency between current implementations on Windows and Linux operating systems.
> On Windows the interval seems to be around 4 seconds and on Linux it's a fixed update interval of 1 second.
> Apps report the updates with varying frequencies.
> This application tracks the playback rate and duration since the last update to send updates at least once a second.

> Availability of event fields depends entirely on the media source. Be sure to check if a field is present when
> The availability of event fields depends entirely on the media source. Be sure to check if a field is present when
> handling media events.

`MEDIA` or `<MAPPED_NAME>`: table
Expand All @@ -76,3 +76,4 @@ Media sends a single type of event, and its name depends on the selected [mode](
- `Progress`: integer (value in milliseconds),
- `Duration`: integer (value in milliseconds),
- `Playing`: bool,
- `Rate`: float (Playback speed multiplier - `1.0` for regular speed)
2 changes: 2 additions & 0 deletions omni-led-applications/media/src/media/linux/media_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -110,13 +110,15 @@ impl MediaImpl {
let title = metadata.title().unwrap_or_default();
let progress = player.get_position().unwrap_or_default();
let duration = metadata.length().unwrap_or_default();
let rate = player.get_playback_rate().unwrap_or(1.0);

Ok(SessionData {
artist: artist.to_string(),
title: title.to_string(),
progress,
duration,
playing: true,
rate,
})
}
}
Expand Down
1 change: 1 addition & 0 deletions omni-led-applications/media/src/media/session_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ pub struct SessionData {
#[proto(transform = Self::duration_into_ms)]
pub duration: Duration,
pub playing: bool,
pub rate: f64,
}

impl SessionData {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,21 @@ impl GlobalSystemMedia {
Self::register_session_handlers(&session, &tx, handle.clone());
}

match manager.GetCurrentSession() {
Ok(session) => {
tx.send(Message::CurrentSessionChanged(Some(session)))
.await
.unwrap();
}
Err(err) => {
// Error code will be OK if there are no media sessions started,
// but otherwise the query succeeded
if err.code().is_err() {
panic!("{err}");
}
}
}

let sessions = Arc::new(Mutex::new(sessions));
Self::register_global_handlers(tx, handle, &manager, &sessions);
}
Expand Down
Loading