A media element is a stateful client, not a decorative box around a file. It selects a source, fetches enough data to identify tracks, decodes frames, buffers ahead, and reports readiness and failure through separate states. A page should offer explicit controls and a nonmedia path to the same essential information. Preload is a hint rather than a download guarantee, and audible autoplay cannot be a prerequisite for understanding the page. Source choice must account for actual encoded tracks as well as container names. A successful HTTP response can still carry bytes the browser cannot decode.
Media Player Source and Load State
Working case
A field reviewer opens case 47 on a metered connection. Its inspection clip is 83 MiB, but the reviewer only needs to read the finding. The page renders the report and a poster first, asks for no full clip download during initial navigation, and shows a play control. A browser that cannot decode the preferred encode can choose a compatible alternative; if both sources fail, the reviewer can open a transcript and an authorized download. A failed play promise or a stalled stream receives an actionable message instead of a blank black rectangle. Switching from case 47 to case 63 releases the old player and its listeners.
Implementation boundary
function playerMessage(state) {
if (state.error) return 'Playback unavailable; open the transcript';
if (state.waiting) return 'Waiting for more video data';
return state.ended ? 'Clip finished' : 'Ready to play';
}
console.log(playerMessage({ error: true, waiting: false, ended: false }));
// Output: Playback unavailable; open the transcriptKeep native controls unless a custom interface can reproduce keyboard, captions, speed, volume, focus, and error behavior. Order source candidates by product policy, but verify the target browser can actually play them in a device test. Use a stable poster with dimensions so loading does not shift surrounding controls. Do not require autoplay. On an explicit play action, handle a rejected play attempt, loading state, waiting state, ended state, and error state as distinct outcomes. Make an essential transcript available without requiring media playback. Use a preload policy based on the page task, not an unconditional eager fetch. Remove event listeners and stop old playback when a route changes; a stale player should not continue speaking over the next case. If the clip is private, every source and fallback request still needs authorization.
Cost and boundaries
For a clip of B bytes, transferring the whole asset is O(B) network and cache use, even if the user watches only a few seconds. Metadata loading can still request some media bytes, so measure actual transfer rather than assuming a hint forces a fixed amount. Decode consumes CPU, memory, and battery that vary with resolution, codec, and device. A poster adds its own request but can keep the initial page useful while the clip is idle. Limit parallel media players and stop hidden playback where product behavior permits. Measure initial page bytes, play-start delay, stall time, decode failure, transcript use, and bytes delivered per minute actually watched.
Failure trace
Block the first source format and verify the alternative works. Return a valid container with an unsupported video track and require a visible error path. Reject the play attempt and preserve an accessible manual control. Throttle the network after playback starts and show waiting without claiming the clip ended. Open the page on a metered device and confirm the first paint does not fetch the entire 83 MiB clip. Change routes while audio is playing and verify it stops. Disable script and confirm the report and transcript remain available. Inspect keyboard and screen-reader access to native controls, source error text, and the transcript path.
Verification
- The first page load does not fetch an entire unused clip.
- Decode and play failures have visible fallback paths.
- Old media stops on route change.
Practice drill
Build a case page with a poster, two encoded source candidates, a transcript, and an authorized fallback download for case 47. Load it with playback untouched and record transferred media bytes. Then press play, record time to first frame, force the first source to fail, and inspect the second. Move to case 63 during audio playback and count active media elements and event listeners. Simulate a rejected play promise. Report the user-facing state and whether the essential finding remained available throughout.
Decision note
Media playback enriches a report; the report remains understandable when a source, decode, or play request fails.
Common Mistakes
- Making audible autoplay the only entry to content.
- Assuming a file extension proves codec support.
- Replacing native controls without restoring their behavior.
Related lessons
On-Demand Media Playback and Delivery; Media Byte Ranges, Seeking, and Version Identity; Adaptive Media Buffer and Fallback Policy; Private Media Session, Cache, and Timed Text; Accessible Content and Media; Page loading: keep content available while CSS and scripts arrive.
Connected practice
Build Project: private inspection clip playback and review Web Development: media playback decisions quiz.
