Publish file/device quality updates to sync app state
This commit is contained in:
130
src/qconnect.rs
130
src/qconnect.rs
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user