Publish file/device quality updates to sync app state

This commit is contained in:
joren
2026-03-31 22:32:44 +02:00
parent bacb40af58
commit 7b882a727a
3 changed files with 147 additions and 19 deletions

View File

@@ -392,6 +392,30 @@ fn msg_max_audio_quality_changed(quality: u64) -> Vec<u8> {
build_qconnect_message(28, &payload)
}
fn msg_file_audio_quality_changed(
sampling_rate_hz: u64,
bit_depth: u64,
channels: u64,
audio_quality: u64,
) -> Vec<u8> {
let mut payload = encode_field_varint(1, sampling_rate_hz);
payload.extend(encode_field_varint(2, bit_depth));
payload.extend(encode_field_varint(3, channels));
payload.extend(encode_field_varint(4, audio_quality));
build_qconnect_message(26, &payload)
}
fn msg_device_audio_quality_changed(
sampling_rate_hz: u64,
bit_depth: u64,
channels: u64,
) -> Vec<u8> {
let mut payload = encode_field_varint(1, sampling_rate_hz);
payload.extend(encode_field_varint(2, bit_depth));
payload.extend(encode_field_varint(3, channels));
build_qconnect_message(27, &payload)
}
/// RNDR_SRVR_VOLUME_MUTED (29): renderer confirms mute state.
fn msg_volume_muted(muted: bool) -> Vec<u8> {
let payload = encode_field_varint(1, if muted { 1 } else { 0 });
@@ -1045,25 +1069,43 @@ async fn run_connection(
current_duration_ms = duration_ms;
match api.get_track_stream(auth_token, &track_id_str, format_id).await {
Ok(stream) => {
let player_stream = match stream {
TrackStream::DirectUrl { url } => {
let (player_stream, stream_sr, stream_bits, stream_ch) = match stream {
TrackStream::DirectUrl {
url,
sampling_rate_hz,
bit_depth,
channels,
} => {
info!("[STATE] Got direct stream URL (duration={}ms)", duration_ms);
StreamSource::DirectUrl(url)
(
StreamSource::DirectUrl(url),
sampling_rate_hz,
bit_depth,
channels,
)
}
TrackStream::Segmented {
url_template,
n_segments,
encryption_key_hex,
sampling_rate_hz,
bit_depth,
channels,
} => {
info!(
"[STATE] Got segmented stream (segments={}, duration={}ms)",
n_segments, duration_ms
);
StreamSource::Segmented {
url_template,
n_segments,
encryption_key_hex,
}
(
StreamSource::Segmented {
url_template,
n_segments,
encryption_key_hex,
},
sampling_rate_hz,
bit_depth,
channels,
)
}
};
player.send(PlayerCommand::Play {
@@ -1073,6 +1115,24 @@ async fn run_connection(
duration_ms,
start_position_ms: requested_pos.unwrap_or(0),
});
if let (Some(sr), Some(bits)) = (stream_sr, stream_bits) {
let ch = stream_ch.unwrap_or(2).max(1);
let file_msg = msg_file_audio_quality_changed(
sr as u64,
bits as u64,
ch as u64,
max_audio_quality as u64,
);
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &file_msg).into())).await?;
msg_id += 1;
let dev_msg = msg_device_audio_quality_changed(
sr as u64,
bits as u64,
ch as u64,
);
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &dev_msg).into())).await?;
msg_id += 1;
}
current_buffer_state = 2; // OK
}
Err(e) => {
@@ -1271,17 +1331,39 @@ async fn run_connection(
current_duration_ms = duration_ms;
match api.get_track_stream(auth_token, &track_id_str, format_id).await {
Ok(stream) => {
let player_stream = match stream {
TrackStream::DirectUrl { url } => StreamSource::DirectUrl(url),
let (player_stream, stream_sr, stream_bits, stream_ch) = match stream {
TrackStream::DirectUrl {
url,
sampling_rate_hz,
bit_depth,
channels,
} => {
(
StreamSource::DirectUrl(url),
sampling_rate_hz,
bit_depth,
channels,
)
}
TrackStream::Segmented {
url_template,
n_segments,
encryption_key_hex,
} => StreamSource::Segmented {
url_template,
n_segments,
encryption_key_hex,
},
sampling_rate_hz,
bit_depth,
channels,
} => {
(
StreamSource::Segmented {
url_template,
n_segments,
encryption_key_hex,
},
sampling_rate_hz,
bit_depth,
channels,
)
}
};
player.send(PlayerCommand::Play {
stream: player_stream,
@@ -1290,6 +1372,24 @@ async fn run_connection(
duration_ms,
start_position_ms: 0,
});
if let (Some(sr), Some(bits)) = (stream_sr, stream_bits) {
let ch = stream_ch.unwrap_or(2).max(1);
let file_msg = msg_file_audio_quality_changed(
sr as u64,
bits as u64,
ch as u64,
*quality as u64,
);
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &file_msg).into())).await?;
msg_id += 1;
let dev_msg = msg_device_audio_quality_changed(
sr as u64,
bits as u64,
ch as u64,
);
ws_tx.send(Message::Binary(build_payload_frame(msg_id, &dev_msg).into())).await?;
msg_id += 1;
}
current_buffer_state = 2; // OK(2)
info!("Restarted at format_id={}", format_id);
}