RemoteCastPlayer silently ignores MediaChannelResult status for setPlayWhenReady, setPlaybackParameters, setRepeatMode and setVolume
@tanay187 is already working on this.
Since Aug 14, 2026.
- Dominant language
- Java
- Stars
- 3k
- Forks
- 955
- Avg merge
- 12d 14h
- Merged PRs (30d)
- 2
Description
Version
Media3 1.11.0
More version details
androidx.media3:media3-cast:1.11.0 with play-services-cast-framework:22.3.1. Findings below come from reading the shipped bytecode of media3-cast-1.11.0.aar with javap -c -p.
Devices that reproduce the issue
Not device-specific. The symptom needs a receiver that rejects a request; mine was a Chromecast Audio on the Default Media Receiver (CC1AD845) with a second sender attached to the same session, which made the receiver answer Invalid Request.
Devices that do not reproduce the issue
n/a
Reproducible in the demo app?
Not tested
Reproduction steps
- Cast to a receiver that will reject a request. The reliable way is to join a Default Media Receiver session that another sender is also mutating, so the receiver's sequence numbers stop matching.
- Call
setPlaybackParameters(orsetPlayWhenReady,setRepeatMode,setVolume) on theCastPlayer. - Watch logcat and watch the app.
The Cast SDK reports the rejection:
W/MediaControlChannel: received unexpected error: Invalid Request.
W/MediaControlChannel: Possibility of local queue out of sync with receiver queue.
Refetching sequence number. Current Local Sequence Number = 6
Media3 does not, and the app has no callback through which it could learn.
Expected result
An app can tell that a request it issued was rejected by the receiver, so it can retry, reconcile, or tell the user. Media3 already does this for two other request families, which is why the gap reads as an oversight rather than a deliberate contract:
RemoteCastPlayer$SeekResultCallbackreadsStatus.getStatusCode()and logsSeek failed. Error code.RemoteCastPlayer$StatusListenerlogsSession start failedandSession resume failed.
Actual result
The ResultCallback<MediaChannelResult> instances used for the state setters never look at the result. RemoteCastPlayer$1.onResult is representative — it null-checks the client, clears the pending-result bookkeeping and flushes listener events, and that is all:
public void onResult(RemoteMediaClient$MediaChannelResult);
0: getfield this$0
4: invokestatic RemoteCastPlayer.access$1100 // remoteMediaClient
7: ifnull 28
10: ...
15: invokestatic RemoteCastPlayer.access$1200 // clear pending callback
22: invokestatic RemoteCastPlayer.access$1300 // listeners
25: invokevirtual ListenerSet.flushEvents
28: return
RemoteCastPlayer$2 through $5 have the same shape. None of the five references Status, getStatusCode, or isSuccess; by contrast SeekResultCallback does.
Tracing where those five are constructed, they cover:
| Callback site | Public API |
|---|---|
RemoteCastPlayer$1–$5 |
setPlayWhenReady(boolean), setPlaybackParameters(PlaybackParameters), setRepeatMode(int), setVolume(float), plus updateTracksAndNotifyIfChanged |
So a rejected play/pause, playback-speed, repeat-mode or volume change is indistinguishable from a successful one. The player's masked state reverts on the next receiver status, but nothing tells the app why, and nothing is logged.
The practical consequence for me: playback speed set locally did not take effect on the receiver, and there was no way to find out from the library whether the setPlaybackParameters request had been rejected or never mattered. I ended up re-applying the speed after STATE_READY as a workaround, without being able to confirm which of the two it was.
I have not traced the queue-mutation path (queueInsertItems, queueReorderItems, queueRemoveItems, load) to the same level of certainty, so I am not claiming anything about it here — though those also attach a ResultCallback through StateHolder and were what first sent me looking.
Logging a failure the way SeekResultCallback already does would be enough to make this diagnosable. Surfacing it to the app would be better.
Media
Not content-dependent.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.