Skip to content

Add HLS streaming support on Windows#173

Merged
kdroidFilter merged 6 commits intomasterfrom
feature/hls-windows-support
Mar 8, 2026
Merged

Add HLS streaming support on Windows#173
kdroidFilter merged 6 commits intomasterfrom
feature/hls-windows-support

Conversation

@kdroidFilter
Copy link
Owner

@kdroidFilter kdroidFilter commented Mar 8, 2026

Summary

  • Add HLS (.m3u8) streaming support on Windows using IMFMediaEngine, since IMFSourceReader does not support HLS on desktop Win32 apps
  • Dual-path architecture: HLS URLs use IMFMediaEngine with D3D11 frame extraction, all other media uses the existing IMFSourceReader path
  • Handles live streams (no duration/seeking), adaptive bitrate resolution changes, and automatic HLS detection with fallback

Test plan

  • Test HLS playback with https://demo.unified-streaming.com/k8s/features/stable/video/tears-of-steel/tears-of-steel.ism/.m3u8
  • Test live HLS stream playback
  • Verify local file and non-HLS network playback still works
  • Verify volume, playback speed, and seek controls work on HLS streams
  • Test adaptive bitrate resolution switching

…o device change

- Fix washed-out video colors by setting alpha byte to 0xFF on RGB32 frames
  (MFVideoFormat_RGB32/X8R8G8B8 leaves the padding byte undefined)
- Add thread-safe atomic access for instanceVolume and playbackSpeed
- Fix WASAPI InitWASAPI cleanup to properly release COM objects on failure (#97)
- Add audio format fallback: try native format first, fall back to 2ch/48kHz
- Add DLL version check (GetNativeVersion) to detect JNA binding mismatches
- Extract AcquireNextSample helper to eliminate ~120 lines of duplication
- Add named constants for sync thresholds (replace magic numbers)
- Fix division-by-zero guard for frame rate
- Support WAVE_FORMAT_EXTENSIBLE and 24-bit PCM in volume scaling
- Eagerly create audio device enumerator to avoid lazy-init race
- Translate all French comments to English
- Enhance GetVideoMetadata with title, bitrate, and extended MIME types
- Migrate from JNA to JNI with RegisterNatives for native bindings
- Add SetOutputSize to scale decoder output to display surface size (saves ~500MB for 4K)
- Fix playback clock desync: open media paused, start clock right before frame production
- Fix resize race: keep isResizing flag until applyOutputScaling completes
- Remove redundant SeekMedia(0) after OpenMedia
- Remove unused sharedFrameBuffer allocation
- Recalibrate wall-clock on first decoded frame in AcquireNextSample,
  fixing HTTP/network sources where decode latency caused mass frame skipping
  (audio played but video was invisible)
- Remove per-pixel alpha forcing loop in ReadVideoFrame (~8M ops/frame for 4K);
  Skia OPAQUE alpha type already handles this
- Use tryLock for audio level polling to avoid blocking media operations
- Remove unnecessary runBlocking wrapper and System.gc() calls
…ent Skia from using the alpha channel during compositing
…te handling

- Remove redundant `LaunchedEffect` and simplify player state initialization
- Add conditions to prevent unnecessary scaling during resize
- Introduce resize timeout to avoid infinite waits
- Ensure playback state is updated only when necessary
IMFSourceReader does not support HLS on desktop Win32 apps, so this adds
a dual-path architecture: HLS URLs (.m3u8) use IMFMediaEngine which has
native HLS support on Windows 10+, while all other media continues to
use the existing IMFSourceReader path.

Key changes:
- New HLSPlayer class wrapping IMFMediaEngine with D3D11 frame extraction
- Automatic HLS detection (URL pattern + fallback on source reader error)
- Live stream handling (duration 0, seeking disabled, EOF retry)
- Adaptive bitrate support (resolution re-queried per frame)
- Audio handled internally by the engine (no WASAPI needed for HLS)
@kdroidFilter kdroidFilter merged commit b03b6f0 into master Mar 8, 2026
3 of 5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant