Add ability to get playback-time

This commit is contained in:
Alexander Heldt
2025-11-16 16:23:16 +01:00
parent 94212996d2
commit 417b5a2559
4 changed files with 69 additions and 0 deletions

View File

@@ -1,5 +1,8 @@
import gleam/json import gleam/json
import gleam/result import gleam/result
import gleam/string
import mpv/internal/control as internal_control
import mpv/key.{type Key, Char} import mpv/key.{type Key, Char}
import tcp/reason.{type Reason} import tcp/reason.{type Reason}
import tcp/tcp.{type Socket} import tcp/tcp.{type Socket}
@@ -38,6 +41,30 @@ pub fn toggle_play_pause(socket: Socket) -> Result(Nil, ControlError) {
} }
} }
// https://mpv.io/manual/master/#command-interface-playback-time
pub type PlaybackTime {
PlaybackTime(data: Float)
}
pub fn get_playback_time(socket: Socket) -> Result(PlaybackTime, ControlError) {
let command =
json.object([
#(
"command",
json.array(["get_property_string", "playback-time"], of: json.string),
),
])
case send_command(socket, command) {
Error(r) -> Error(ControlError(reason.to_string(r)))
Ok(json_string) ->
case internal_control.parse_playback_time(json_string) {
Error(e) -> Error(ControlError(string.inspect(e)))
Ok(data) -> Ok(PlaybackTime(data))
}
}
}
fn send_command(socket: Socket, command: json.Json) -> Result(String, Reason) { fn send_command(socket: Socket, command: json.Json) -> Result(String, Reason) {
result.try(tcp.send(socket, json.to_string(command) <> "\n"), fn(_) { result.try(tcp.send(socket, json.to_string(command) <> "\n"), fn(_) {
let timeout_ms = 10_000 let timeout_ms = 10_000

View File

@@ -0,0 +1,25 @@
import gleam/dynamic/decode
import gleam/float
import gleam/json
import gleam/string
pub fn parse_playback_time(
json_string: String,
) -> Result(Float, json.DecodeError) {
let decoder = {
let float_dececoder = fn(data_string) {
case float.parse(data_string) {
Error(_) -> decode.failure(0.0, "data")
Ok(float_value) -> decode.success(float_value)
}
}
use data <- decode.field(
"data",
decode.then(decode.string, float_dececoder),
)
decode.success(data)
}
json.parse(from: string.trim(json_string), using: decoder)
}

View File

@@ -1,4 +1,5 @@
import gleam/erlang/process.{type Subject} import gleam/erlang/process.{type Subject}
import gleam/float
import gleam/otp/actor import gleam/otp/actor
import gleam/result import gleam/result
import gleam/string import gleam/string
@@ -44,10 +45,17 @@ fn handle_message(
case control { case control {
control.TogglePlayPause -> { control.TogglePlayPause -> {
echo "toggling play/pause" echo "toggling play/pause"
let _ = let _ =
result.map_error(control.toggle_play_pause(state.socket), fn(err) { result.map_error(control.toggle_play_pause(state.socket), fn(err) {
echo "Could not toggle play/pause: " <> err.details echo "Could not toggle play/pause: " <> err.details
}) })
let _ =
result.map(control.get_playback_time(state.socket), fn(playback) {
echo "playback: " <> float.to_string(playback.data)
})
actor.continue(state) actor.continue(state)
} }
control.Exit -> { control.Exit -> {

View File

@@ -2,6 +2,7 @@ import gleam/list
import gleeunit import gleeunit
import mpv/control.{type Control} import mpv/control.{type Control}
import mpv/internal/control as control_internal
import mpv/key.{type Key, Char} import mpv/key.{type Key, Char}
pub fn main() -> Nil { pub fn main() -> Nil {
@@ -22,3 +23,11 @@ pub fn control_from_key_test() {
assert tc.expected == control.from_key(tc.key) assert tc.expected == control.from_key(tc.key)
}) })
} }
pub fn parse_playback_time_test() {
let json_string =
"{\"data\":\"123.456789\",\"request_id\":0,\"error\":\"success\"}\n"
let assert Ok(data) = control_internal.parse_playback_time(json_string)
assert data == 123.456789
}