Files

27 lines
8.0 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta name="generator" content="rustdoc"><meta name="description" content="Telling a finished stream apart from a truncated one."><title>jellytau_lib::player::stream_end - Rust</title><script>if(window.location.protocol!=="file:")document.head.insertAdjacentHTML("beforeend","SourceSerif4-Regular-6b053e98.ttf.woff2,FiraSans-Italic-81dc35de.woff2,FiraSans-Regular-0fe48ade.woff2,FiraSans-MediumItalic-ccf7e434.woff2,FiraSans-Medium-e1aa3f0a.woff2,SourceCodePro-Regular-8badfe75.ttf.woff2,SourceCodePro-Semibold-aa29a496.ttf.woff2".split(",").map(f=>`<link rel="preload" as="font" type="font/woff2"href="../../../static.files/${f}">`).join(""))</script><link rel="stylesheet" href="../../../static.files/normalize-9960930a.css"><link rel="stylesheet" href="../../../static.files/rustdoc-17e0aaed.css"><meta name="rustdoc-vars" data-root-path="../../../" data-static-root-path="../../../static.files/" data-current-crate="jellytau_lib" data-themes="" data-resource-suffix="" data-rustdoc-version="1.97.1 (8bab26f4f 2026-07-14)" data-channel="1.97.1" data-search-js="search-fd9372ac.js" data-stringdex-js="stringdex-2da4960a.js" data-settings-js="settings-170eb4bf.js" ><script src="../../../static.files/storage-41dd4d93.js"></script><script defer src="../sidebar-items.js"></script><script defer src="../../../static.files/main-fcd733ba.js"></script><noscript><link rel="stylesheet" href="../../../static.files/noscript-f7c3ffd8.css"></noscript><link rel="alternate icon" type="image/png" href="../../../static.files/favicon-32x32-eab170b8.png"><link rel="icon" type="image/svg+xml" href="../../../static.files/favicon-044be391.svg"></head><body class="rustdoc mod"><a class="skip-main-content" href="#main-content">Skip to main content</a><!--[if lte IE 11]><div class="warning">This old browser is unsupported and will most likely display funky things.</div><![endif]--><rustdoc-topbar><h2><a href="#">Module stream_end</a></h2></rustdoc-topbar><nav class="sidebar"><div class="sidebar-crate"><h2><a href="../../../jellytau_lib/index.html">jellytau_<wbr>lib</a><span class="version">0.11.2</span></h2></div><div class="sidebar-elems"><section id="rustdoc-toc"><h2 class="location"><a href="#">Module stream_<wbr>end</a></h2><h3><a href="#structs">Module Items</a></h3><ul class="block"><li><a href="#structs" title="Structs">Structs</a></li><li><a href="#constants" title="Constants">Constants</a></li><li><a href="#functions" title="Functions">Functions</a></li></ul></section><div id="rustdoc-modnav"><h2><a href="../index.html">In jellytau_<wbr>lib::<wbr>player</a></h2></div></div></nav><div class="sidebar-resizer" title="Drag to resize sidebar"></div><main><div class="width-limiter"><section id="main-content" class="content" tabindex="-1"><div class="main-heading"><div class="rustdoc-breadcrumbs"><a href="../../index.html">jellytau_lib</a>::<wbr><a href="../index.html">player</a></div><h1>Module <span>stream_<wbr>end</span>&nbsp;<button id="copy-path" title="Copy item path to clipboard">Copy item path</button></h1><rustdoc-toolbar></rustdoc-toolbar><span class="sub-heading"><a class="src" href="../../../src/jellytau_lib/player/stream_end.rs.html#1-524">Source</a> </span></div><details class="toggle top-doc" open><summary class="hideme"><span>Expand description</span></summary><div class="docblock"><p>Telling a <em>finished</em> stream apart from a <em>truncated</em> one.</p>
<p>TRACES: UR-040 | DR-129 | UT-117</p>
<p>Background audio-only playback of a video item streams a <strong>progressive mp3
transcode over plain HTTP</strong> (see
<code>OnlineRepository::build_audio_only_stream_url_for_video</code>). That response has
no reliable length — a live transcode is chunked — so when the connection
drops mid-episode the data source simply sees end-of-input. ExoPlayer cannot
distinguish that from the real end of the media and reports
<code>Player.STATE_ENDED</code>, which the app then treats as “the episode finished”.</p>
<p>The user-visible damage is not the missed advance itself. Playback parks in
ExoPlayers <code>STATE_ENDED</code>, and the next play intent from the lockscreen,
notification or a Bluetooth reconnect goes through media3s
<code>Util.handlePlayButtonAction</code>, which seeks an ENDED player to its default
position before playing — so <strong>the episode starts over from 0:00</strong>. On a
flaky connection that reads as “it randomly restarts the episode”.</p>
<p>The player itself has no way to know; the <em>duration</em> does. Jellyfin gives us
the items real runtime, so an end reported well short of it is a truncation,
not a finish — and the right response is to re-open the stream where it died,
which is the “buffer and resume” the user expects.</p>
</div></details><h2 id="structs" class="section-header">Structs<a href="#structs" class="anchor">§</a></h2><dl class="item-table"><dt><a class="struct" href="struct.ObservedTime.html" title="struct jellytau_lib::player::stream_end::ObservedTime">Observed<wbr>Time</a></dt><dd>The last playback time actually observed while media was loaded.</dd><dt><a class="struct" href="struct.ResumeTracker.html" title="struct jellytau_lib::player::stream_end::ResumeTracker">Resume<wbr>Tracker</a></dt><dd>Budget for consecutive resume attempts that make no progress.</dd></dl><h2 id="constants" class="section-header">Constants<a href="#constants" class="anchor">§</a></h2><dl class="item-table"><dt><a class="constant" href="constant.MAX_STALLED_RESUME_ATTEMPTS.html" title="constant jellytau_lib::player::stream_end::MAX_STALLED_RESUME_ATTEMPTS">MAX_<wbr>STALLED_<wbr>RESUME_<wbr>ATTEMPTS</a></dt><dd>Consecutive resume attempts allowed at the same position before giving up.</dd><dt><a class="constant" href="constant.RESUME_PROGRESS_EPSILON_SECS.html" title="constant jellytau_lib::player::stream_end::RESUME_PROGRESS_EPSILON_SECS">RESUME_<wbr>PROGRESS_<wbr>EPSILON_<wbr>SECS</a><span title="Restricted Visibility">&nbsp;🔒</span> </dt><dd>Position change that counts as “this is a different playback context” —
either the resume made progress, or a different item is loaded.</dd><dt><a class="constant" href="constant.TRUNCATED_STREAM_TOLERANCE_SECS.html" title="constant jellytau_lib::player::stream_end::TRUNCATED_STREAM_TOLERANCE_SECS">TRUNCATED_<wbr>STREAM_<wbr>TOLERANCE_<wbr>SECS</a></dt><dd>How far short of the items runtime a stream may end and still count as a
natural finish.</dd></dl><h2 id="functions" class="section-header">Functions<a href="#functions" class="anchor">§</a></h2><dl class="item-table"><dt><a class="fn" href="fn.is_audio_only_video.html" title="fn jellytau_lib::player::stream_end::is_audio_only_video">is_<wbr>audio_<wbr>only_<wbr>video</a></dt><dd>A video item played through the native <em>audio</em> path — i.e. the background
audio-only handoff, the only place a length-less progressive transcode is
used. Jellyfins item-type taxonomy stays in Rust (CLAUDE.md).</dd><dt><a class="fn" href="fn.is_truncated_end.html" title="fn jellytau_lib::player::stream_end::is_truncated_end">is_<wbr>truncated_<wbr>end</a></dt><dd>Did this end-of-stream happen far enough short of the items runtime to be a
truncation rather than a finish?</dd><dt><a class="fn" href="fn.player_retry_restarts_stream.html" title="fn jellytau_lib::player::stream_end::player_retry_restarts_stream">player_<wbr>retry_<wbr>restarts_<wbr>stream</a></dt><dd>Would the <em>players own</em> load-error retry restart this stream from its
beginning? If so the retry must be switched off and recovery left to
<a href="../struct.PlayerController.html#method.recoverable_error_resume" title="method jellytau_lib::player::PlayerController::recoverable_error_resume"><code>crate::player::PlayerController::recoverable_error_resume</code></a>.</dd><dt><a class="fn" href="fn.with_start_time.html" title="fn jellytau_lib::player::stream_end::with_start_time">with_<wbr>start_<wbr>time</a></dt><dd>Rewrite an audio-only stream URL to start at <code>position_seconds</code>.</dd></dl></section></div></main></body></html>