Repository navigation
feat(media): UidVideo, UidAudio and the @dskripchenko/ui/hls adapter - #42
Merged
Merged
Conversation
…enko/ui/hls adapter - useMediaController: normalised state, commands, hotkeys, one active player per page, resume position, readable localised errors (404 told apart). - UidVideo: sources with fallback and quality menu, scrub bar with buffered ranges, chapters and sprite thumbnails, subtitles drawn by the player, speed/quality/captions menus inside the player (sheet in small players), full screen with the iOS fallback, picture-in-picture, touch gestures, auto-hiding controls. - UidAudio: compact row, mini variant, in-browser waveform (chunked, cached, size-capped, lazy) or precomputed peaks, playlist with auto-advance and Media Session. - @dskripchenko/ui/hls (lazy entry): native HLS where available, otherwise MSE with fMP4/CMAF and MPEG-TS (built-in H.264/AAC transmuxer), AES-128, live playlists, discontinuities, ABR and manual quality, retries. - Real-browser checks (scripts/media-check), docs in en/ru/de/zh, stories. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… player polish
- The HLS engine runs one stream per SourceBuffer: video (or muxed) and a
separate audio rendition (EXT-X-MEDIA TYPE=AUDIO with a URI), sharing one
timestamp offset per discontinuity so they stay in sync across seeking and
quality switches. Rendition choice: audioLanguage, DEFAULT, AUTOSELECT in
the browser language. setAudioTrack(), stats(); Safari's native
audioTracks are exposed too.
- Packed audio segments (ID3 timestamp + ADTS) go through the transmuxer.
- UidVideo: audio-track group in the settings menu; compact speed chips in
the small-player sheet. Scrub preview hides while a menu is open or the
controls are hidden.
- UidAudio: HLS sources (audio-only master or media playlist); playlist
durations prefetched from metadata ("—" until known); shimmering
placeholder while a waveform is pending; narrow layout truncates the
title/artist and puts the time under the bar.
- Fixtures (video-only renditions + en/ru audio as fMP4, TS and packed AAC,
audio-only HLS) and browser checks for all of it, incl. tone detection of
the playing rendition in Chromium and a header geometry check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Dependency-free media players on the native
<video>/<audio>elements, plus a lazily loaded HLS entry.What's inside
useMediaController: the core both players share. It keeps a normalised reactive state and offers play/pause/seek/skip, volume, mute, rate, full screen (with the iOSwebkitEnterFullscreenfallback) and picture-in-picture (standard API or Safari's presentation mode). It also has the hotkey map, allows one active player per page (with anexclusiveopt-out) and resumes from a saved position (resumeKey). Errors come as readable, localised kinds, and a 404 is reported as a network error rather than "unsupported format".UidVideo:src/sourceswith fallback; labelled sources form the quality menu.UidAudio:minivariant for table rows.decodeAudioData, peaks computed in chunks with idle yields, cached per src, decoded one file at a time and only when near the viewport, with size and duration caps. Precomputedpeaksare also accepted.@dskripchenko/ui/hls(separate entry, loaded with a dynamic import):EXT-X-MAPand byte ranges.media, docsdocs/{en,ru,de,zh}/{video,audio}.md(with a formats table and HLS notes), stories, a changeset (minor).Checks
pnpm media:fixtures && PLAYWRIGHT=… pnpm media:check(Playwright with ffmpeg-generated fixtures). All 24 checks pass in Chromium 156, Chrome 156 and WebKit 27:Sizes
dist/index.mjsgrows by +60 KB raw (+15.4 KB min+gzip). The components are tree-shakeable.dist/hls/index.mjsis 40.8 KB raw, 31.6 KB min, 11.7 KB min+gzip. It is loaded only when an HLS source appears.Not included
SAMPLE-AES/DRM, HEVC/MP3 inside MPEG-TS, alternate audio renditions (
EXT-X-MEDIA TYPE=AUDIOwith a URI), LL-HLS parts, HLS inUidAudio.🤖 Generated with Claude Code