`maxVideoBitrate` budgets the whole stream, so a capped transcode forced
even profile-compatible audio down to low-rate AAC (measured on Plex
1.43: EAC3 5.1 640k became 360k AAC). The client profile already carries
the video cap through `add-limitation(video.bitrate)`, so drop the
redundant `maxVideoBitrate` param and send `directStreamAudio=1`: the
video stays capped per preset while audio in the codecs the profile
declares (aac/ac3/eac3/mp3) is copied through untouched. Audio the HLS
target cannot carry still transcodes as before.
A Plex transcode session always starts producing at zero: the decision
request never sent offset=, so any non-zero open - resuming a
transcoded title, or switching from Direct Play to a transcoded
quality mid-playback - opened a session whose produced window begins
at the start of the file and seeked it. mpv immediately requests a
segment the transcoder has not produced, PMS answers 404 for it and
every subsequent segment, and playback buffers forever.
Send offset=<seconds> (6dp) with the decision and start request - the
view offset on initial open, the resolved resume position on every
in-place reload - so the session begins producing at the position the
player consumes first. The playlist timeline is unchanged: an offset
session's media playlist still covers the full title from segment
zero, so the player keeps opening with start: at the resume position
and in-stream seeks work as before.
Before a native player opens an offset playlist, waitForTranscodeReady
walks the master playlist, the media playlist, and the segment
containing the offset, because PMS can publish a manifest before that
segment is fetchable and mpv treats the 404 as an HLS error. The probe
is best-effort: it never fails an open, hands off immediately on HTTP
500 (on the response and exception paths alike) so the server-limit
dialog stays prompt, stops on cancellation, skips itself when the
playlist durations never reach the offset, and stays out of the
endpoint-failover cascade. In-place reloads resolve the replacement
source only after the old stop report has gone out, so Plex cannot use
that stop to terminate the replacement transcode.
close#1840
An in-place source switch — audio, subtitle, version or quality — detaches
the host's player for the duration of the reload. `_broadcast` falls back to
a position of 0 when no player is attached, so any state published in that
window names 0:00 as the authoritative position and every guest hard-seeks
to the start of the item.
Heartbeats already suppress themselves while detached, which is why this
hides: the paths that leak the zero are the ones that answer on demand.
`onStateRequested`, `onPeerJoined` and `onReconnected` all broadcast
regardless of whether a player is attached, so a guest entering the player,
joining, or reconnecting mid-reload is the trigger.
Fall back to the last broadcast anchor instead. That field is only assigned
for untargeted broadcasts, so it holds the last position the room was
actually told, and the reload's own re-attach path already re-anchors from
it once the player comes back.