Better Player Reborn: From 0.0.84 to 1.x
A lot has happened since version 0.0.84. Actually, a lot. If you blinked, you might have missed us rewriting the internals of Better Player while the package kept running in your app. Let's take a quick tour of what has landed.
Starting Fresh(ish)
Back at 0.0.84, Better Player was a well-loved but aging package: running ExoPlayer 2, Objective-C on iOS, and a classic channel-based plugin architecture. It worked, sure, but the ecosystem moved on.
We moved with it. No dramatic rewrite from scratch, but a steady, version-by-version modernization across the stack. Native code, architecture, platforms, tooling: all of it got overhauled.
The Big Ones
ExoPlayer to AndroidX Media3
Version 0.1.0 brought the biggest Android change in the package's history: we replaced ExoPlayer 2 with AndroidX Media3. This is Google's modern playback engine: better codec support, improved performance, active development, and a brighter future. It was a breaking change, but the kind you do once and never look back.
Objective-C to Swift + Swift Package Manager
iOS users, we didn't forget you. In 0.8.0 we completed the full migration of the iOS native layer from Objective-C to Swift, and moved the package to Swift Package Manager (SPM). The old Obj-C code served well for years, but Swift brings cleaner interop, modern tooling, and a codebase that is enjoyable to work in. SPM also means no more CocoaPods headaches when integrating the plugin.
FFI + JNI: Modern Native Bridges
With version 1.2.0 we migrated to a modern JNI/Swift FFI architecture for native bridges, replacing legacy platform channels. This means faster, more reliable communication between Dart and native code, with fewer mysterious crashes. The boundary between Dart and native is explicit, typed, and direct.
Web Support
In 1.7.0, Better Player gained WASM and Web compatibility, and 1.6.0 introduced full web platform documentation and a feature matrix with Shaka Player integration. There is also a detailed setup guide covering what works across browsers. If your users are on the web, we have you covered.
Architectural Overhaul
We did not stop at swapping engines. The architecture got real attention:
- Federated plugin model (
1.0.0): Android and iOS implementations are separate packages (better_player_android,better_player_ios). This keeps platform code decoupled and simplifies maintenance. - Cleaner controller API:
VideoPlayerControllerwas replaced withPlayerEngineController. Internal state is refactored into immutable data classes (PlayerViewState,PlayerPlaybackState,PlayerSubtitleState,PlayerTrackState) instead of scattered mutable variables. - Extensible logging (
1.3.0): A dedicatedPlayerLoggerwith native-to-Dart log streaming, automatic caller/tag derivation, and structured internal logs. No moreprint()archaeology when something fails in production. - Widevine L1/L3 security levels (
1.8.0): Configurable DRM security levels for Android and Web. L1 for hardware-backed secure playback, L3 for software fallback. - Localization improvements (
1.x): Persian and Portuguese translations landed, the overflow menu gained localization support with newPlayerTranslationsfields, and a localization bridge integrates with your app's existing locale setup.
Production Reliability
Testing makes or breaks a media plugin. Every commit triggers:
- Unit and widget tests: covering controllers, state management, subtitle parsing, HLS/DASH utilities, and UI components with mock injection for network code.
- Maestro E2E tests on iOS and Android: testing real device flows, tapping through the player UI, verifying controls, fullscreen, and subtitles.
- Playwright E2E tests on web: automating the browser experience end to end.
Every single commit gets checked on Android, iOS, and web before it lands.
Fixes and Polish
- Accessibility: Semantic labels and interactive semantics across all controls.
- Migration guides: Smooth transitions from
video_player,chewie, andmedia_kit. - Streaming fixes: Subtitle segment timing, audio track detection, live stream sliding windows, ABR video sizing on Android TV, and aspect ratio edge cases.
- Picture-in-Picture: Hardened PiP lifecycles on Android and iOS.
- VOD duration fix: Resolved zero-duration reporting for edge-case VOD streams on Android.
What 0.x to 1.x Means
It means: new engine, Swift on iOS, FFI/JNI native bridges, web support, a federated plugin structure, a cleaner public API, full E2E test coverage, and migration tooling: shipped incrementally with changelogs for every milestone.
Check out Better Player on pub.dev and the full changelog for details.
Have questions or feedback? Open an issue on GitHub or reach out: we read everything.
