better_native_video_player 0.4.11
better_native_video_player: ^0.4.11 copied to clipboard
Native video player using AVPlayerViewController (iOS) and ExoPlayer (Android) with HLS, Picture-in-Picture, AirPlay, and fullscreen support.
Changelog #
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
0.4.11 - 2026-01-27 #
0.4.10 - 2026-01-27 #
Fixed #
- Audio focus timing: Video now requests audio focus only when playback starts, not during initialization. Avoids unnecessary audio focus grabs when the player is created but not yet playing, improving behavior when multiple audio sources are present.
0.4.9 - 2026-01-15 #
Improved #
- Initialization Logic Enhancement: Enhanced initialization logic in NativeVideoPlayerController
- Updated the initialization check to consider the presence of the method channel and platform view IDs, allowing for a more flexible initialization process
- Improved the completion handling of the initialization completer to ensure it is only completed if not already done, preventing potential issues during the initialization phase
0.4.8 - 2026-01-15 #
Improved #
- Android VideoPlayerObserver Refactoring: Refactored VideoPlayerObserver to avoid redundant loading events
- Updated comments to clarify that the "loaded" event is already sent by
onPlaybackStateChangedwhen the player reachesSTATE_READY - Eliminates duplicate event emissions for better event handling efficiency
- Improved code clarity and documentation
- Updated comments to clarify that the "loaded" event is already sent by
0.4.7 - 2026-01-14 #
Added #
- DRM (Digital Rights Management) Support: Comprehensive DRM support for protected content playback
- FairPlay Streaming support on iOS with certificate and license server configuration
- Widevine support on Android for protected content playback
- AES-128 (Standard HLS Encryption) support on both platforms
- ClearKey DRM support for testing and development
- DRM configuration via
drmConfigparameter inload(),loadUrl(), andloadFile()methods - License server URL configuration for all DRM types
- Certificate URL support for FairPlay (iOS) with automatic certificate fetching
- Custom HTTP headers for license requests (authentication tokens, etc.)
- VideoPlayerDrmHandler class for DRM setup and license requests on iOS
- Comprehensive DRM handling in VideoPlayerMethodHandler for both iOS and Android
- Picture-in-Picture (PiP) state notifications in video player UI
0.4.6 - 2025-12-29 #
Fixed #
-
Event Thread Safety: Fixed event sending to ensure thread safety on both platforms
- Android: Events now sent on main thread using
Handler(Looper.getMainLooper()) - iOS: Events now sent on main queue using
DispatchQueue.main.async - Prevents potential crashes or race conditions when events are sent from background threads
- Ensures UI updates happen on the correct thread for better stability
- Android: Events now sent on main thread using
-
Subscription Cancellation Safety: Fixed potential exceptions during controller disposal
- Added
_safeCancelSubscription()method to gracefully handleMissingPluginExceptionduring disposal - Prevents errors when native side has already disposed EventChannel StreamHandler
- Improves reliability of controller cleanup and resource management
- Added
0.4.5 - 2025-12-29 #
Added #
- Native Controls Visibility Control: Added
showNativeControlsparameter toNativeVideoPlayerControllerconstructor- Defaults to
trueto maintain backward compatibility - When set to
false, native controls are hidden - Custom overlays automatically hide native controls regardless of this setting
- Provides fine-grained control over native control visibility
- Defaults to
Improved #
- Code Quality and Formatting: Enhanced code formatting and consistency across the controller
- Improved line formatting and spacing throughout
NativeVideoPlayerController - Better code readability with consistent formatting patterns
- Removed unnecessary line breaks for cleaner code structure
- Improved line formatting and spacing throughout
Fixed #
- Event Thread Safety: Fixed event sending to ensure thread safety on both platforms
- Android: Events now sent on main thread using
Handler(Looper.getMainLooper()) - iOS: Events now sent on main queue using
DispatchQueue.main.async - Prevents potential crashes or race conditions when events are sent from background threads
- Ensures UI updates happen on the correct thread for better stability
- Android: Events now sent on main thread using
0.4.4 - 2025-12-29 #
Improved #
- Code Quality and Formatting: Enhanced code formatting and consistency across the controller
- Improved line formatting and spacing throughout
NativeVideoPlayerController - Better code readability with consistent formatting patterns
- Removed unnecessary line breaks for cleaner code structure
- Improved import organization
- Improved line formatting and spacing throughout
Fixed #
- Initialization Check: Fixed initialization check in
load()method to use_isInitializedflag instead of state check- More reliable initialization validation before loading video
- Prevents potential issues when checking controller readiness
0.4.3 - 2025-12-29 #
Fixed #
- iOS Background Playback: Fixed video playback stopping when device goes to background or screen locks
- Added
audiovisualBackgroundPlaybackPolicyconfiguration to allow playback to continue in background (iOS 15.0+) - Configured both shared players and standalone players for background playback
- Video now continues playing when device is locked or app goes to background
- Ensures seamless playback experience during background transitions
- Added
0.4.2 - 2025-11-27 #
Added #
- Automatic Inline Picture-in-Picture: New methods to enable/disable automatic PiP when app goes to background
- Added
enableAutomaticInlinePip()method to automatically start PiP when app goes to background - Added
disableAutomaticInlinePip()method to turn off automatic PiP behavior - iOS: Uses
canStartPictureInPictureAutomaticallyFromInline(requires iOS 14.2+) - Android: Integrates with the existing floating package for automatic PiP on home button press (requires Android 8+)
- Automatic PiP settings persist across view recreations for shared players
- Comprehensive platform checks and error handling with descriptive messages
- Manual PiP controls via
enterPictureInPicture()remain fully functional
- Added
Improved #
- iOS Automatic PiP State Management: Enhanced SharedPlayerManager to store automatic PiP settings
- Added
setAutomaticPiPEnabled()method to persist automatic PiP preference per controller - Settings are maintained when views are recreated with shared controllers
- Better logging for debugging automatic PiP activation
- Added
0.4.0 - 2025-11-25 #
Added #
- Subtitle/Closed Caption Support: Comprehensive subtitle functionality for HLS streams
- Added
NativeVideoPlayerSubtitleTrackmodel with language code and display name - Added
getSubtitleTracks()method to retrieve available subtitle tracks - Added
setSubtitleTrack()method to select a specific subtitle track or disable subtitles - iOS: Uses AVFoundation's
AVMediaSelectionGroupfor native subtitle track management - Android: Uses ExoPlayer's text track selection API for subtitle rendering
- Support for both VOD and Live HLS streams with embedded subtitles
- Support for WebVTT and standard HLS subtitle formats on both platforms
- Added
SubtitlePickerModalwidget with beautiful Material Design UI - Font size control (12-32px) for subtitle customization
- Language selection with localized display names
- Enable/disable subtitles toggle
- Integrated subtitle picker into custom video overlay controls
- Added comprehensive subtitle example screen demonstrating VOD and Live HLS streams
- Added
Improved #
- Example App: Enhanced with subtitle examples and better UI organization
- Added
subtitle_example_screen.dartwith multiple subtitle examples - Updated
video_list_screen_with_players.dartwith subtitle track access - Cleaned up example code for better maintainability
- Added
Documentation #
- Updated README with detailed subtitle documentation and usage examples
- Added API reference for subtitle-related methods
- Included examples for getting available tracks and selecting subtitle languages
0.3.10 - 2025-11-20 #
Improved #
- AirPlay State Manager Initialization: Enhanced initialization flow to support app startup initialization
- Added
_initRequestedflag to track initialization requests before controllers are created AirPlayStateManager.init()can now be safely called at app startup before creating any video player controllers- Automatic AirPlay detection now starts when the first controller is created if
init()was called earlier - Removed
StateErrorexception when callinginit()without available controllers - Improved developer experience by allowing flexible initialization timing
- Added proper cleanup of
_initRequestedflag indispose()method
- Added
Documentation #
- Updated
init()method documentation to clarify safe usage at app startup - Improved comments explaining automatic initialization behavior when channels become available
0.3.9 - 2025-11-20 #
Fixed #
- Android AirPlay Method Handlers: Fixed missing method handlers causing errors when calling AirPlay methods on Android
- Added
startAirPlayDetection()method handler (no-op on Android, returns success) - Added
stopAirPlayDetection()method handler (no-op on Android, returns success) - Added
disconnectAirPlay()method handler (no-op on Android, returns success) - Fixed "No video player controller available" error when calling
AirPlayStateManager.instance.init()on Android
- Added
Improved #
- AirPlay State Manager Platform Safety: Enhanced platform checking for better cross-platform compatibility
- Added platform checks to all AirPlay methods (
init(),showAirPlayPicker(),disconnectAirPlay(),dispose()) - Methods now return early without error on non-iOS platforms (Android, Web)
- AirPlay methods are now safe to call on any platform without platform-specific guards
- Improved documentation to clarify iOS-only functionality with cross-platform safety
- Added platform checks to all AirPlay methods (
0.3.8 - 2025-11-20 #
Added #
- HLS Live Stream Support: Full support for HLS live streams with indefinite duration
- iOS: Uses
seekableTimeRangesto calculate duration and position for live content - Android: Uses
Timeline.Windowto handle dynamic, non-seekable live streams - Position and duration now calculated relative to the seekable window for live streams
- Proper detection of live vs VOD content (including VOD HLS)
- Accurate time updates and progress reporting for live streams
- iOS: Uses
Improved #
-
iOS Autoplay Reliability: Enhanced autoplay functionality with proper initialization
- Added
prepareForPlayback()method that consolidates audio session, Now Playing info, and PiP setup - Autoplay now properly prepares audio session and media controls before starting playback
- Ensures playback rate is set correctly during autoplay
- Now Playing info is properly initialized before video starts
- Added
-
iOS Background Audio During Screen Lock: Major improvements to maintain playback when screen locks
- Player now actively resumes playback after screen lock transition completes
- Added 100ms delay to ensure background transition completes before resuming
- Stores playback state before lock to restore correctly
- Sets playback rate to
desiredPlaybackSpeedwhen resuming after lock - Fixes issue where iOS would pause video when device locks
-
iOS Audio Session Management: Enhanced audio session preparation for remote commands
- Audio session is now prepared before resuming playback in Now Playing handler
- Critical for proper playback after interruptions (phone calls, alarms)
- Ensures audio session is active when handling remote control commands
-
Android Autoplay Timing: Fixed autoplay to happen after player is ready
- Moved
player.play()call to execute only afterSTATE_READYis reached - Prevents autoplay attempts before player has loaded media
- Play event is now sent automatically by
VideoPlayerObserverafter successful play - More reliable autoplay behavior across different video formats
- Moved
Fixed #
-
HLS Live Stream Position: Fixed incorrect position and duration reporting for live streams
- Live streams no longer show indefinite or incorrect duration values
- Position now properly tracks within the seekable window
- Prevents position from going negative or exceeding duration
-
iOS Screen Lock Playback: Fixed video audio stopping when screen locks during playback
- Playback now continues seamlessly when device locks
- Audio maintains at correct playback speed after lock
- Resolves interruption in background audio during screen lock transitions
Technical Details #
- iOS Implementation: Enhanced time observer to detect indefinite duration and use seekable ranges
- Android Implementation: Added Timeline and Window inspection to differentiate live from VOD content
- Example App: Added CNN livestream example with autoplay enabled for testing
0.3.7 - 2025-11-19 #
Added #
- iOS Global AirPlay Device Detection: Enhanced AirPlay monitoring with global route detection
- Added
AirPlayStateManager.init()method to start global AirPlay device detection at app startup - Added
startAirPlayDetection()andstopAirPlayDetection()native methods inSharedPlayerManager - Global
AVRouteDetectormonitors AirPlay device availability across the entire app - AirPlay availability events now sent from shared manager to all controllers
- Improved device discovery with centralized detection logic
- Added
setMethodChannel()to enable event communication from shared manager
- Added
Improved #
-
iOS Audio Session Management: Major enhancements to background audio and lock screen playback
- Added
prepareAudioSession()method for centralized audio session configuration - Critical fix: Audio session now activated BEFORE calling
player.play()to ensure lock screen playback - Added
handleAppDidEnterBackground()observer to maintain audio session when screen locks - Audio session stays active during screen lock to prevent iOS from pausing video
- Better audio session error handling with detailed logging
- Consolidated audio session setup in initialization and play methods
- Added
-
iOS Audio Interruption Handling: Enhanced handling of phone calls, alarms, and other audio interruptions
- Added auto-resume functionality when system recommends resumption after interruption
- Better detection of interruption end with
shouldResumeflag handling - Improved Now Playing info restoration after audio session reactivation
- Ensures playback continues correctly after interruptions when appropriate
-
Android Error Handling: Better PiP event listener error management
- Improved error handling for MainActivity PiP events (non-critical errors)
- Fixed platform check ordering to prevent unnecessary iOS errors
- Added
cancelOnError: falseto prevent event stream from stopping on error - Better debug logging for
MissingPluginExceptioncases
-
AirPlayStateManager Lifecycle: Enhanced initialization and disposal
dispose()now stops AirPlay detection before cleaning up resourcesinit()provides clear API for starting AirPlay detection at app startup- Better error handling during disposal to prevent crashes
- Cleaner resource cleanup with proper detection stop
Fixed #
- iOS Lock Screen Audio: Fixed video audio stopping when screen locks
- Audio session now properly configured before playback starts
- Background audio maintained correctly during screen lock transitions
- Prevents iOS from automatically pausing playback when device locks
Documentation #
- Added usage examples for
AirPlayStateManager.init()in code documentation - Updated
prepareAudioSession()with detailed explanation of importance - Improved comments explaining critical audio session activation timing
0.3.6 - 2025-11-17 #
Added #
- Android PiP Enhancement: Integrated
floatingpackage (version 6.0.0) for improved Picture-in-Picture functionality on Android- Automatic PiP management with seamless transitions
- Simplified PiP implementation using the floating package
Improved #
- Android PiP Implementation: Major refactor of Android Picture-in-Picture handling
- Removed legacy PiP handling code, simplifying the codebase
- Enhanced NativeVideoPlayerController to utilize the floating package for PiP management
- Better PiP user experience with automatic handling
Changed #
- Updated dependencies with floating package for Android PiP support
- Code formatting improvements across the codebase
Documentation #
- Updated documentation to reflect new automatic PiP integration and requirements
0.3.5 - 2025-11-17 #
Changed #
- Version bump and maintenance release
- Code formatting and quality improvements
0.3.4 - 2025-11-16 #
Added #
- Global AirPlay State Management: Complete refactor to use centralized AirPlay state across all video player instances
- Added
AirPlayStateManagersingleton service for global AirPlay state management - Added
airPlayDeviceNameproperty with stream support to track connected AirPlay device name - Added
isAirplayConnectingstate to track connection progress between device selection and streaming - Added
AirPlayStateManager.instance.showAirPlayPicker()- Show AirPlay picker from anywhere in the app - Added
AirPlayStateManager.instance.disconnectAirPlay()- Disconnect from AirPlay globally - Added
controller.disconnectAirPlay()method for programmatic AirPlay disconnection - Controllers now delegate to global manager for consistent state across all instances
- Added
Improved #
-
iOS AirPlay Device Name Detection: Enhanced reliability with robust retry mechanism
- Implemented multi-attempt retry with exponential backoff (4 attempts: 0.1s, 0.3s, 0.6s, 1.0s delays)
- Added smart device name caching to prevent null values during temporary iOS audio route updates
- Comprehensive logging for audio route inspection and device detection
- Device names persist correctly even when iOS has timing issues with audio route updates
- Retry logic used in both initial state detection and audio route change events
-
iOS AirPlay State Emission: Improved state synchronization across multiple controllers
- New controllers immediately receive current global AirPlay state on subscription
- Modified stream getters to emit current state immediately to new subscribers
- All controllers stay synchronized regardless of creation order
- Fixed issue where AirPlay state was only visible on first controller
-
iOS AirPlay Connection Detection: Enhanced initial connection state handling
- Checks both player-level and system-level (audio route) AirPlay state on initialization
- Correctly detects existing AirPlay connections when new players are created
- Emits initial connection state even if AirPlay was active before player initialization
- Added audio route change observer to track AirPlay device switches
-
iOS AirPlay Connecting State Logic: Fixed inconsistent state detection
- Unified logic between initial state check and audio route change handler
- Consistently checks both
player.isExternalPlaybackActiveand system audio route - Added detailed debug logging showing playerActive, systemActive, connected, and connecting states
Fixed #
-
iOS AirPlay Connecting State: Fixed
isAirPlayConnectingincorrectly showing true when connected and playing- Audio route change handler now uses same detection logic as initial state check
isConnectingproperly calculated as: systemActive AND NOT playerActive AND isConnected- Prevents showing "connecting" UI when already connected and playing
- Fixed state calculation issues during audio route changes while connected
-
iOS Redundant State Updates: Prevented unnecessary global state updates with multiple controllers
- Added pre-checks before calling
updateConnection()andupdateAvailability() - Only updates global state if values differ from current state
- Prevents duplicate stream emissions when multiple controllers report same state
- Maintains single source of truth in
AirPlayStateManager
- Added pre-checks before calling
Technical Details #
- iOS Implementation: Added
getAirPlayDeviceName()method usingAVAudioSessionto detect device names - iOS Audio Route Handling: Added
handleAudioRouteChange()observer for device switching and state monitoring - Flutter State Model: Extended with
airPlayDeviceNameandisAirplayConnectingproperties - API Compatibility: Backward compatibility maintained for controller-level listener handlers
- Event Protocol: Updated
airPlayConnectionChangedevent to includedeviceNameparameter
Breaking Changes #
- AirPlay state is now global across all video player instances (shared via
AirPlayStateManager) - All controllers see the same AirPlay state regardless of which controller initiated the connection
- This change provides more accurate representation of system-level AirPlay connectivity
0.3.3 - 2025-11-12 #
Improved #
-
iOS Picture-in-Picture Multi-View Handling: Enhanced PiP functionality when using multiple views with shared controllers
- Added checks for active PiP across multiple views to prevent conflicts
- Improved PiP stopping actions to work correctly even when navigating between views
- Better error handling for cases where no active PiP is found
- Enhanced user experience by ensuring PiP can be stopped from any active view
-
iOS Picture-in-Picture Reliability: Major improvements to PiP start/stop mechanisms
- Implemented retry mechanism for starting PiP with detailed logging for attempts and outcomes
- Enhanced automatic PiP handling with improved player state detection
- Better PiP activation and transfer logic to improve reliability during playback
- Added comprehensive diagnostics and logging for debugging PiP transitions
-
iOS Audio Session Interruption Handling: Added robust handling for audio session interruptions
- Implemented observer for audio session interruptions (e.g., phone calls, alarms)
- Automatic reactivation of audio session after interruption ends
- Restoration of Now Playing info post-interruption
- Enhanced logging for better tracking of audio session states during playback
-
iOS Now Playing Info Persistence: Comprehensive improvements to media control reliability
- Implemented foreground notification handling to restore Now Playing info when app returns from background
- Added fallback mechanism to retrieve media info from SharedPlayerManager when local data is unavailable
- Enhanced media info retrieval in VideoPlayerObserver for accurate Now Playing info during playback
- Improved PiP restoration logic with proper cleanup during view disposal
- Media info now persists correctly when PiP is active or during restoration transitions
- Added
isPipActiveForControllermethod to check PiP status across all views for a controller
-
iOS Remote Command Management: Enhanced reliability of media control registration
- Refined remote command re-registration logic to prevent unnecessary re-registration
- Added ownership status checks before re-registering commands
- Introduced flag to track registration status for better management during ownership transfers
- Force re-registration capability with immediate and delayed verification checks
- Improved Now Playing info accuracy with better tracking of command status
-
iOS Audio Session Activation: Enhanced audio session handling for Now Playing info
- Activate audio session in VideoPlayerNowPlayingHandler to ensure info displays correctly
- Added error handling for session activation to improve reliability
- Added playback rate logging and detailed checks for audio session state
- Comprehensive diagnostics for remote command targets and Now Playing info completeness
Fixed #
-
iOS Now Playing Controls: Fixed media controls becoming unresponsive after various transitions
- Fixed Now Playing info not displaying after returning from background
- Fixed media info being lost during PiP restoration
- Fixed remote command targets not being properly re-registered during ownership transfers
- Prevents "Unknown" or blank media info from appearing in Control Center and lock screen
-
iOS HDR Performance: Removed outdated HDR correction code for improved performance optimization
0.3.2 - 2025-11-10 #
Changed #
- HDR Enabled by Default: Changed
enableHDRdefault value fromfalsetotrue- HDR content will now display with proper HDR rendering by default
- Set to
falseif you prefer SDR tone-mapping for HDR content
Improved #
-
iOS Media Info Persistence: Enhanced media info handling during Picture-in-Picture transitions
- Added media info caching in SharedPlayerManager to persist across view recreations
- Media info now survives view disposal during PiP mode
- Ensures Now Playing controls remain functional with correct title/subtitle during PiP
- Prevents media info from being cleared when transitioning between views
- Media info automatically stored when loading video and persists throughout controller lifetime
-
iOS Manual PiP vs Automatic PiP: Added tracking to prevent conflicts between manual and automatic PiP
- Added
controllersWithManualPiPtracking in SharedPlayerManager - Prevents automatic PiP from interfering when user manually enters PiP
- Automatic PiP re-enabling skipped when manual PiP is active
- Improves reliability when using both PiP modes in the same app
- Added
-
iOS PiP State Tracking: Enhanced PiP state detection and handling
- Added
isPipCurrentlyActiveflag to VideoPlayerView for reliable PiP state tracking - Better synchronization between PiP controller state and view state
- Improved cleanup logic when view is disposed while PiP is active
- More accurate detection of PiP transitions for proper event delivery
- Added
-
Code Quality: Code formatting improvements across Flutter controller
- Removed unnecessary line breaks for cleaner code structure
- Better readability with consistent formatting
- Improved maintainability of the codebase
Fixed #
- iOS Media Controls During PiP: Fixed media controls becoming unresponsive during PiP transitions
- Media info no longer cleared from SharedPlayerManager when view is disposed during PiP
- Lock screen and Control Center controls remain functional throughout PiP lifecycle
- Prevents "Unknown" or blank media info from appearing in system controls
0.3.1 - 2025-11-09 #
Fixed #
- iOS Picture-in-Picture Event Delivery: Fixed issue where PiP stop events could fail when exiting PiP with disposed views
- Added
findAllViewsForController()method to SharedPlayerManager to locate active views for a controller - Enhanced PiP stop event handling to fallback to alternative active views when primary view is disposed
- Fixed
pictureInPictureController:restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:to handle disposed views - Now attempts to find and restore UI on alternative active views with the same controller
- Completes with false when no active view exists, allowing iOS to exit PiP gracefully
- Added PiP state detection in
deinitto send pipStop events before view disposal - Ensures pipStop events are always delivered when exiting PiP, even with disposed or inactive views
- Prevents app crashes or inconsistent state when exiting PiP after navigating away from video view
- Added
0.3.0 - 2025-11-08 #
Added #
-
Video Looping Support: Comprehensive video looping functionality with smooth native playback
- Added
enableLoopingparameter toNativeVideoPlayerControllerconstructor (default: false) - Added
setLooping(bool)method for dynamic looping control during playback - Android uses ExoPlayer's
REPEAT_MODE_ONEfor seamless native looping - iOS implements looping via seek to beginning and automatic replay without gaps
- Smooth looping without visible pause or stuttering across both platforms
- Added
-
Multiple Video Format Support: Extended support beyond HLS streams
- Added support for MP4 video URLs (remote)
- Added support for local video files (file:// URIs)
- Android uses
ProgressiveMediaSourcefor non-HLS content - iOS AVPlayer natively supports multiple formats (MP4, MOV, M4V)
- Android supports additional formats (WebM, MKV)
- Added
isHlsUrl()helper function for improved format detection on both platforms - Quality selection remains available for HLS streams
-
Convenience Loading Methods: New explicit methods for improved API clarity
- Added
loadUrl({required String url, Map<String, String>? headers})for remote videos - Added
loadFile({required String path})for local files (automatically constructs file:// URIs) - Existing
load()method remains for backward compatibility - Better IDE autocomplete and discoverability
- Added
-
Asset Video Support: Local video file playback from Flutter assets
- Implemented new MethodChannel for resolving asset paths on both platforms
- Assets are automatically extracted to cache directory for playback
- Seamless integration with existing loading methods
- Added example with local asset (ElephantsDream.mp4)
Improved #
-
iOS Media Controls: Fixed critical issues with native media controls across multiple scenarios
- Fixed MPRemoteCommandCenter conflicts when using multiple videos with shared controllers
- Added
RemoteCommandManagersingleton to centralize ownership of remote commands - Remote command ownership now tracked by viewId instead of media title for reliability
- Fixed media controls becoming unresponsive when entering/exiting PiP
- Fixed lock screen controls showing incorrect media info or becoming unresponsive
- Proper cleanup of remote command targets in deinit to prevent dangling references
- Remote command handlers now verify ownership before processing events
- Fixed periodic observer conflicts causing incorrect Now Playing info updates
-
Remote Command Ownership Transfer: Automatic management between multiple views
- Only the "owner" view can register remote command handlers and update Now Playing info
- Ownership automatically transfers when entering/exiting PiP
- Prevents conflicts when multiple VideoPlayerView instances exist simultaneously
- Ensures consistent media control behavior across app lifecycle
Fixed #
-
iOS Now Playing Info Persistence: Fixed Now Playing info disappearing or showing wrong data
- Now Playing ownership no longer fails with duplicate titles or disposed views
- Media controls remain functional when switching between videos
- Lock screen and Control Center always show correct media information
-
Race Conditions: Consolidated cleanup logic to prevent race conditions
- Better synchronization between view lifecycle and remote command management
- Improved timing of ownership transfers during PiP transitions
-
HLS Detection: Improved quality switching and HLS stream detection
- More reliable detection of HLS vs progressive video formats
- Quality fetching only attempted for actual HLS streams
- Better logging for source type detection and debugging
Documentation #
- Updated README with "Supported Video Formats" section
- Added examples for HLS, MP4, and local file usage
- Updated feature list to highlight multi-format support
- Added test URLs for both HLS and MP4 formats
- Updated API Reference with new convenience methods
- Added path_provider example for local file handling
- Updated example app with mixed HLS and MP4 examples
0.2.20 - 2025-11-06 #
Improved #
-
Android Auto Picture-in-Picture: Major enhancements to automatic PiP mode when pressing home button
- Unified PiP entry logic with single
enterPictureInPictureInternal()method that handles both manual and automatic triggers - Removed
setAutoEnterEnabled(true)which was bypassing custom PiP logic andonUserLeaveHintcallback - Improved fullscreen transition before PiP entry - now enters fullscreen silently without sending intermediate events
- Added
onStop()lifecycle method in example MainActivity to catch auto PiP on devices whereonUserLeaveHintisn't reliably called - Better source rect calculation for PiP window positioning when transitioning from fullscreen
- Enhanced logging throughout PiP flow for better debugging
- Auto PiP now enabled by default in example app with proper state tracking
- Unified PiP entry logic with single
-
Android MainActivity Configuration: Cleaned up example app MainActivity
- Removed
android:taskAffinity=""from AndroidManifest which could cause activity lifecycle issues - Added
isInPipModeflag to track PiP state across lifecycle methods - Created unified
tryEnterAutoPip()method called from bothonUserLeaveHintandonStop - Improved PiP state restoration with immediate event emission after exiting PiP
- Enhanced logging with warning emojis for better visibility in logcat
- Removed
Fixed #
-
Android 12+ PiP Behavior: Fixed
setAutoEnterEnabledcausing Android to automatically enter PiP without proper custom logic- Android's auto-enter was bypassing the plugin's fullscreen transition and state management
- Now uses only
setSeamlessResizeEnabledfor smooth transitions while maintaining control over PiP entry - Ensures proper event flow and state synchronization when entering PiP
-
Auto PiP Reliability: Fixed auto PiP not working reliably on all Android devices
- Added fallback to
onStop()whenonUserLeaveHint()isn't called (device-specific behavior) - Better detection of home button press across different Android versions and manufacturers
- Prevents entering PiP when activity is finishing (back button vs home button)
- Added fallback to
0.2.19 - 2025-11-06 #
Improved #
-
Video Completion Behavior: Enhanced video completion handling to provide better user experience
- Video now automatically resets to the beginning when playback completes
- Player automatically pauses after completion instead of staying in ended state
- Applies to both iOS (AVPlayer) and Android (ExoPlayer) platforms
- Ensures consistent behavior across platforms for replay scenarios
-
Android State Restoration After Exiting PiP: Enhanced state synchronization when exiting Picture-in-Picture mode
- Added
emitCurrentState()method to re-emit all player states after PiP exit - Ensures UI components receive accurate position, duration, buffered position, and playback state
- Automatically emits current timeUpdate with buffering state
- Emits current play/pause state to synchronize UI controls
- Prevents UI from displaying stale state after returning from PiP mode on Android
- Added
0.2.18 - 2025-11-05 #
Fixed #
- State Restoration After Exiting PiP: Fixed issue where player state would not be properly restored after exiting Picture-in-Picture mode
- Added
emitCurrentState()method on both iOS and Android to re-emit all player states after PiP exit - Ensures UI components receive accurate position, duration, buffered position, and playback state
- Prevents UI from showing stale or incorrect state after returning from PiP mode
- Applies to both platforms when user exits PiP via system gesture or button
- Added
Improved #
- Code Quality (Flutter): Improved code formatting across
NativeVideoPlayerController- Better line formatting and consistency throughout the codebase
- Enhanced readability with improved code organization
- Removed unnecessary line breaks for cleaner code structure
Documentation #
- Android PiP Setup: Added comprehensive documentation for required MainActivity PiP callback
- Documented why MainActivity callback is necessary for proper PiP state restoration
- Added complete code example for MainActivity implementation
- Clarified consequences of not implementing the callback
0.2.17 - 2025-11-05 #
Improved #
- Code Quality (Android): Enhanced import organization in VideoPlayerMethodHandler
- Added explicit import for SharedPlayerManager
- Simplified fully qualified class name references
- Improved code readability and maintainability
0.2.16 - 2025-11-04 #
Improved #
-
Enhanced Initialization Handling: Improved controller initialization with better state tracking
- Added
_isInitializedand_isInitializingflags to prevent duplicate initialization - Initialize completer now waits properly for existing initialization to complete
- Early return when platform view is already created with method channel
- Added
isInitializedgetter to check initialization status programmatically
- Added
-
Immediate State Emission for New Listeners: Event listeners now receive current state immediately upon registration
- New activity listeners immediately receive current activity state (playing, paused, etc.)
- New control listeners immediately receive current position, duration, and buffer state
- Eliminates the need to wait for the next event when adding listeners after initialization
- Includes debug logging to track listener registration and state emission
-
Duration Persistence During AirPlay: Fixed duration being lost during AirPlay transitions
- Duration is now protected from being overwritten with 0 during AirPlay connection/disconnection
- Duration controller explicitly re-emits when AirPlay connects to ensure UI stays updated
- Prevents progress bars and time displays from temporarily showing 0:00 during transitions
-
Unified Event Name Handling: Added support for both 'timeUpdate' and 'timeUpdated' event names
- Native platforms can now use either naming convention
- Improves compatibility and reduces potential event parsing issues
Fixed #
- Duration Lost During Navigation: Fixed issue where duration would be temporarily lost when listeners are added after player initialization
- Controller now notifies all listeners with current state when duration becomes available
- Ensures UI components added dynamically receive accurate state information
0.2.15 - 2025-10-31 #
Added #
- Buffering State Debounce: Added 400ms debounce to buffering state changes to prevent UI flicker
- Buffering state is only emitted if it persists for more than 400ms
- Prevents brief buffering periods from causing UI flicker
- Automatically restores previous play/pause state when buffering completes
- Tracks last non-buffering state for accurate restoration
Improved #
- Code Quality: Removed all
debugPrintstatements from the package- Cleaner production code without debug output
- Better performance by avoiding unnecessary string operations
- Error handling now uses silent catch blocks or returns appropriate defaults
Fixed #
- Custom Overlay Not Working After Navigation: Fixed critical issue where custom overlays would break after using
releaseResources()_overlayBuilderis now preserved acrossreleaseResources()calls- Native controls properly hide/show based on overlay presence after reconnection
- Overlay builder persists like other state (
_state,_url) for quick resumption - Fixes issue where controls would be completely non-functional on second visit
- Only cleared on final
dispose(), not on temporaryreleaseResources()
0.2.14 - 2025-10-31 #
Added #
- Continuous Buffering State Reporting: Buffering state is now always reported in real-time
- Added
isBufferingboolean totimeUpdateevents (sent every 500ms) - Android: Tracks
player.playbackState == Player.STATE_BUFFERING - iOS: Tracks
player.timeControlStatus == .waitingToPlayAtSpecifiedRate - Flutter controller automatically transitions to
PlayerActivityState.bufferingwhen buffering starts - Ensures UI always reflects accurate buffering status, even when video is in play state
- Added
Improved #
- Qualities Persistence After Re-initialization: Video qualities now persist across view recreations
- Added
qualitiesCachestorage toSharedPlayerManageron both iOS and Android - Qualities are automatically cached when fetched and restored when view is recreated
- Eliminates the need to re-fetch qualities from network after navigation
- Ensures qualities are immediately available after calling
releaseResources()and re-initializing
- Added
Fixed #
-
Buffering Not Visible During Playback: Fixed issue where video would buffer while in play state without indicating buffering status
- Buffering state is now continuously tracked and reported every 500ms
- UI can now simultaneously show that video wants to play but is currently buffering
- Prevents confusion when video stalls during playback
-
Missing Qualities After Navigation: Fixed issue where video qualities would disappear after navigating away and back
- Qualities are now stored in
SharedPlayerManagerwhich survives view recreation getAvailableQualities()automatically restores from cache when view instance is empty- Works correctly with the release/re-init pattern used when navigating
- Qualities are now stored in
0.2.13 - 2025-10-30 #
Added #
- Overlay Lock Feature: Added ability to lock custom overlay to always be visible
- New
lockOverlay()method to keep overlay permanently visible - New
unlockOverlay()method to restore normal tap-to-hide behavior - New
isOverlayLockedgetter to check current lock state - New
isOverlayLockedStreamfor reactive lock state updates - When locked, overlay cannot be dismissed by tapping or auto-hide timer
- Useful for live streams, interactive content, or when constant access to controls is needed
- New
Fixed #
- AirPlay Connection State Updates: Fixed issue where AirPlay connection state was not properly updating the controller state
- Now properly updates
_state.isAirplayConnectedwhen receivingairPlayConnectionChangedevents - Ensures
isAirplayConnectedStreamemits correctly when connection state changes - Provides consistent state tracking between event handlers and controller state
- Now properly updates
0.2.12 - 2025-10-30 #
Added #
- Automatic Overlay Management for PiP: Custom overlays now automatically hide when entering PiP and show when exiting PiP on Android
- Prevents overlay from appearing in PiP window
- Seamless user experience when transitioning to/from PiP mode
- Only affects Android platform (iOS handles PiP differently)
Improved #
-
Enhanced Picture-in-Picture Transitions (Android): Major improvements to PiP mode behavior
- Added automatic fullscreen entry before PiP for better visual transitions
- Added
wasFullscreenBeforePiptracking to restore correct state after PiP - Implemented source rect hints for more accurate PiP window positioning
- Added seamless resize support for Android 12+ for smoother PiP transitions
- PiP window now correctly restores to inline or fullscreen mode based on state before PiP entry
- Improved visual consistency when entering and exiting PiP mode
-
Shared Player Surface Reconnection: Enhanced surface handling for shared players
- Added automatic surface reconnection after
releaseResources()is called - Ensures video playback resumes correctly when returning to a video with a shared player
- Prevents black screen issues when navigating back to previously viewed videos
- Added automatic surface reconnection after
-
PiP Availability Detection: Improved activity context handling for PiP feature detection
- Added
getActivity()helper method to properly unwrapContextWrapperinstances - More reliable PiP availability checks across different context types
- Better error handling when activity context is not immediately available
- Added
Fixed #
-
Custom Overlay in PiP Window: Fixed issue where custom overlays would appear in the PiP window on Android
- Overlay is now automatically hidden before entering PiP
- Overlay automatically reappears when exiting PiP
- Provides clean PiP experience with only native system controls
-
Fullscreen State After PiP: Fixed incorrect fullscreen state restoration after exiting PiP
- Now properly tracks fullscreen state before entering PiP
- Restores to inline mode if video was inline before PiP
- Maintains fullscreen mode if video was fullscreen before PiP
- Eliminates unexpected fullscreen state changes after PiP
0.2.11 - 2025-10-28 #
Fixed #
- Progress Bar Seek Jump: Fixed issue where progress bar would jump back briefly after seeking
- Added
_targetSeekPositionto track where we're seeking to - Modified seek handling to ignore old position events during seek operation
- Progress bar now stays at target position until native player confirms seek completion
- Position updates within 200ms of target are considered successful seeks
- Eliminates the 500ms "jump back" behavior when seeking
- Added
0.2.10 - 2025-10-28 #
Added #
-
Quality List Stream: Added
qualitiesStreamto track changes in available video qualities- Stream emits
List<NativeVideoPlayerQuality>whenever quality list changes - Useful for updating UI when qualities are loaded or changed
- Follows the same pattern as other property streams
- Example usage in
custom_video_overlay.dartdemonstrates reactive quality selector updates
- Stream emits
-
Automatic Orientation Restoration: Enhanced
FullscreenManagerwith intelligent orientation tracking- Automatically saves current orientation preferences when entering fullscreen
- Restores original orientations when exiting fullscreen (no manual setup required)
- Added
setPreferredOrientations()helper method as optional drop-in replacement forSystemChrome.setPreferredOrientations() - Added
preferredOrientationsparameter toNativeVideoPlayerControllerfor easy orientation configuration - Supports per-controller orientation preferences (e.g., portrait-only apps can specify this when creating the controller)
-
Tap-to-Hide Overlay: Enhanced custom overlay interaction
- Tapping on visible overlay now hides it (in addition to the auto-hide timer)
- Tapping on hidden overlay shows it (existing behavior)
- Interactive elements (buttons, sliders) are unaffected and work normally
- Uses
HitTestBehavior.deferToChildfor proper gesture handling
Fixed #
- Stream Disposal Race Condition: Fixed "Bad state: Cannot add new events after calling close" error
- Added
_isDisposedflag to prevent state updates after disposal - Added
isClosedchecks before adding events to all stream controllers - Improved disposal order: now cancels event subscriptions before closing stream controllers
- Added double-disposal guard to prevent errors from multiple dispose calls
- Affects:
bufferedPositionController,durationController,playerStateController,positionController,speedController,isPipEnabledController,isPipAvailableController,isAirplayAvailableController,isAirplayConnectedController,isFullscreenController,qualityChangedController, andqualitiesController
- Added
Changed #
- Custom Video Overlay: Refactored to use streams instead of control events
- Now uses
bufferedPositionStreamfor reactive buffer position updates - Now uses
qualitiesStreamfor reactive quality list updates - Reduced dependency on control event polling
- Improved code organization and separation of concerns
- Added
dart:asyncimport forStreamSubscriptionsupport
- Now uses
Documentation #
- Updated
NativeVideoPlayerControllerdocumentation withpreferredOrientationsusage examples - Updated
FullscreenManagerdocumentation explaining automatic orientation tracking - Added comprehensive explanation of auto quality feature and buffer health thresholds
0.2.9 - 2025-10-27 #
Added #
-
HDR Control: Added
enableHDRparameter toNativeVideoPlayerController- Defaults to
falseto prevent washed-out/too-white video appearance on HDR content - Set to
trueto enable HDR playback when desired - Applies to both iOS and Android platforms
- ExoPlayer automatically handles tone-mapping to SDR when HDR is disabled
- Defaults to
-
AirPlay Connection State Tracking: Enhanced AirPlay monitoring with connection state
- Added
isAirplayConnectedproperty toNativeVideoPlayerState - Added
isAirplayConnectedgetter toNativeVideoPlayerController - Added
isAirplayConnectedStreamfor real-time connection state updates - New
PlayerControlStateevents:airPlayConnectedandairPlayDisconnected - Allows UI to respond to active AirPlay streaming state
- Added
-
Convenience State Getters: Added direct property access to controller state
speed- Current playback speedisPipEnabled- Current Picture-in-Picture stateisPipAvailable- PiP device availabilityisAirplayAvailable- AirPlay device availabilityisAirplayConnected- Active AirPlay connection state
Fixed #
- Android Picture-in-Picture Media Session: Fixed media info not displaying correctly in PiP mode
- Media session now properly updates when entering PiP mode (manual, automatic, and exit)
- Ensures notification and lock screen controls show correct title, subtitle, and artwork
- Applies to all PiP entry/exit scenarios: manual start/stop and automatic transitions
Changed #
- Enhanced
NativeVideoPlayerStatemodel withisAirplayConnectedproperty - Updated event handling to process AirPlay connection state changes
- Improved Android PiP lifecycle to ensure media session consistency
0.2.8 - 2025-10-27 #
Added #
-
Individual Property Streams: Added dedicated broadcast streams for convenient property monitoring
bufferedPositionStream- Stream of buffered position changesdurationStream- Stream of duration changesplayerStateStream- Stream of player state changes (playing, paused, buffering, etc.)positionStream- Stream of playback position changesspeedStream- Stream of playback speed changesisPipEnabledStream- Stream of Picture-in-Picture state changesisPipAvailableStream- Stream of Picture-in-Picture availability changesisAirplayAvailableStream- Stream of AirPlay availability changesisFullscreenStream- Stream of fullscreen state changesqualityChangedStream- Stream of quality changes- Streams only emit when values actually change (no duplicate emissions)
- All streams are broadcast streams allowing multiple listeners
-
Toggle Picture-in-Picture: Added
togglePictureInPicture()method for easy PiP toggling- Automatically checks current PiP state and enters/exits accordingly
- Returns
boolindicating success/failure of the operation - Follows the same pattern as
toggleFullScreen()for consistency
Changed #
-
Enhanced State Model: Extended
NativeVideoPlayerStatewith new properties- Added
speedproperty to track playback speed - Added
isPipEnabledproperty to track current PiP state - Added
isPipAvailableproperty to track PiP device availability - Added
isAirplayAvailableproperty to track AirPlay device availability - Updated
copyWith(),operator==, andhashCodeto include new properties
- Added
-
Improved Event Handling: Enhanced event processing to update state properties
- Quality changes now update state and emit to quality stream
- Speed changes now update state and emit to speed stream
- PiP state changes (both platform view and MainActivity events) now update state and emit to PiP streams
- PiP availability changes now update state and emit to availability stream
- AirPlay availability changes now update state and emit to AirPlay stream
Documentation #
- Added comprehensive documentation for individual property streams in README
- Added usage examples showing how to use streams vs event listeners
- Updated API Reference section with new streams and toggle method
- Added dedicated Streams subsection in API Reference documenting all 10 available streams
- Updated Picture-in-Picture section with
togglePictureInPicture()usage examples
Note #
- The original event listeners (
addActivityListener,addControlListener) continue to work as before - Users can choose between using dedicated streams or event listeners based on their use case
- Stream controllers are properly disposed in the
dispose()method to prevent memory leaks
0.2.7 - 2025-10-23 #
Improved #
- Enhanced Player Disposal and Cleanup: Improved SharedPlayerManager on both iOS and Android platforms
- Added
stopAllViewsForController()method to properly stop playback and clear player from all views when disposing - Enhanced iOS disposal to pause player and clear current item before removing
- Enhanced Android disposal to stop playback and clear active views
- Improved logging for better debugging of player lifecycle
- Better cleanup of view references when controller is disposed
- Added
Changed #
- Code formatting improvements across the codebase to comply with Dart style guidelines
- Improved readability with better line formatting in
NativeVideoPlayerController
0.2.6 - 2025-10-23 #
Fixed #
-
Critical Controller Disposal Bug: Fixed incomplete resource cleanup in
NativeVideoPlayerController.dispose()method- Added proper cleanup of PiP event subscription (Android global listener)
- Added cleanup of AirPlay listeners (availability and connection handlers)
- Added cleanup of platform view contexts map
- Added cleanup of overlay builder and fullscreen callback references
- Fixed memory leaks by ensuring all event handlers and subscriptions are properly cancelled
-
Android Player Reinitialization Issue: Fixed critical bug where Android players could not be reinitialized after disposal
- Fixed
VideoPlayerMethodHandler.handleDispose()to properly remove player fromSharedPlayerManager - Added
controllerIdparameter toVideoPlayerMethodHandlerconstructor - Now properly releases ExoPlayer, notification handler, and clears PiP settings on disposal
- Android players can now be disposed and recreated just like iOS players
- Fixed
Changed #
- Enhanced
VideoPlayerMethodChannelwith newdispose()method that calls native platform disposal - Updated Flutter controller
dispose()to call native cleanup via method channel - Improved disposal flow to ensure both Flutter and native resources are properly cleaned up
Documentation #
- Updated
dispose()method documentation to reflect proper disposal of both Flutter and native platform resources
0.2.5 - 2025-10-23 #
Improved #
- Android Media Info Management: Refactored VideoPlayerNotificationHandler and VideoPlayerObserver for improved media information management
- Enhanced media session and notification updates to occur consistently when playback starts
- Improved user experience in both normal playback and Picture-in-Picture modes
- Cleaned up code for better readability and maintainability
- Enhanced logging for better debugging capabilities
0.2.4 - 2025-10-23 #
Fixed #
- iOS Automatic Picture-in-Picture for Shared Controllers: Fixed critical issue where automatic PiP would not work correctly when multiple views share the same controller (e.g., list view + detail view scenario)
- Fixed race condition where multiple views observing the same shared player would compete for PiP control
- Added primary view tracking to ensure only the most recently active view can trigger automatic PiP
- Fixed automatic PiP not working for videos started with native controls (non-programmatic playback)
- Improved SharedPlayerManager to properly handle PiP state transfers between views with the same controller ID
- Added
isPrimaryView()andgetPrimaryViewId()methods to prevent observer conflicts
Changed #
- Enhanced observer logic to detect when playback starts via native controls and automatically set the view as primary
- Improved logging for debugging PiP state transitions across multiple views
0.2.3 - 2025-10-21 #
Fixed #
- Fixed Dart formatting issues in
native_video_player_controller.dartandfullscreen_manager.dartto comply with pub.dev static analysis requirements
0.2.2 - 2025-10-21 #
Added #
- WASM compatibility: Package now supports Web Assembly (WASM) runtime
- Implemented conditional imports using
dart:ioonly on native platforms - Added
PlatformUtilsclass for platform detection without directdart:iodependency - Exported
PlatformUtilsfor users who need platform-agnostic code
- Implemented conditional imports using
Changed #
- Replaced direct
Platformchecks withPlatformUtilsin fullscreen manager and controller - Code formatting improvements across all files
0.2.0 - 2025-10-21 #
Added #
-
AirPlay Support (iOS): Complete AirPlay integration for streaming to Apple TV and AirPlay-enabled devices
isAirPlayAvailable()method to check for available AirPlay devicesshowAirPlayPicker()method to display native AirPlay device pickeraddAirPlayAvailabilityListener()to monitor when AirPlay devices become available/unavailableaddAirPlayConnectionListener()to track AirPlay connection state changes- Automatic detection of AirPlay-enabled devices on the network
- Support for streaming video to multiple AirPlay receivers
-
Custom Overlay Controls: Build your own video player UI on top of the native player
- New
overlayBuilderparameter inNativeVideoPlayerwidget - Full access to controller state for custom UI implementations
- Allows building custom controls while maintaining native video decoding performance
- Example implementation in
example/lib/widgets/custom_video_overlay.dartwith:- Play/pause control
- Progress slider with buffered position indicator
- Speed controls (0.25x - 2.0x)
- Quality selector for HLS streams
- Fullscreen toggle
- Volume control
- AirPlay button (iOS)
- Auto-hide functionality
- New
-
Dart-side Fullscreen Management: New
FullscreenManagerclass for Flutter-based fullscreenFullscreenVideoPlayerwidget for fullscreen video playback in a Flutter overlayenterFullscreen()andexitFullscreen()methods- System UI management (hide/show status bar and navigation bar)
- Device orientation locking options
- Fullscreen dialog helper for easy integration
- Works alongside native fullscreen for maximum flexibility
-
Buffered Position Tracking: Real-time buffered position updates
- New
bufferedPositionproperty in controller - Included in
timeUpdatedcontrol events - Enables showing how much video has been preloaded
- Perfect for showing secondary progress indicator in custom overlays
- New
Improved #
- Enhanced controller state management with better activity and control state tracking
- Improved fullscreen state synchronization between native and Dart layers
- Better event listener management with separate activity and control listeners
- Enhanced example app with new
video_with_overlay_screen.dartdemonstrating custom controls - Improved documentation with comprehensive AirPlay and custom overlay usage examples
- Better error handling and state validation throughout the player lifecycle
Documentation #
- Updated README with comprehensive sections on AirPlay and custom overlays
- Added example code for all new features
0.1.4 - 2025-10-20 #
Fixed #
- Fixed Dart SDK constraint to use proper version range (>=3.9.0 <4.0.0) instead of exact version, allowing compatibility with all Dart 3.9.x and 3.x versions
0.1.3 - 2025-10-20 #
Fixed #
- Fixed fullscreen exit handling on iOS when user dismisses by swiping down or tapping Done button
- Fixed iOS playback state preservation when exiting fullscreen (video now resumes playing if it was playing before)
- Fixed Android fullscreen button icon synchronization when fullscreen is toggled from Flutter code
- Fixed fullscreen event parsing to properly distinguish between entering and exiting fullscreen states
- Fixed shared player state synchronization by sending current playback state when new views attach
Improved #
- Standardized event naming by renaming
videoLoadedtoloadedacross all platforms for consistency - Enhanced Android fullscreen button to detect and correct icon desynchronization
- Improved shared player initial state callback mechanism to properly communicate loaded state with duration
- Better fullscreen state event notifications on Android with proper
isFullscreendata - Enhanced iOS fullscreen delegate handling with playback state restoration
0.1.2 - 2025-01-16 #
Fixed #
- Fixed iOS player state tracking by observing
timeControlStatusinstead of relying only on item observers - Fixed shared player initialization to properly handle existing players vs new players
- Fixed Android PiP event channel setup to only initialize on Android platform (prevents iOS errors)
- Fixed playback state synchronization when connecting to shared players
- Fixed unnecessary buffering/loading events for shared players during reattachment
Improved #
- Enhanced iOS player observer to distinguish between play/pause and buffering states
- Improved shared player management with better state tracking and event handling
- Enhanced Android player controls by hiding unnecessary buttons (next, previous, settings)
- Better error handling and logging throughout the player lifecycle
0.1.1 - 2025-10-20 #
Fixed #
- Fixed Android package name to match plugin name (com.huddlecommunity.better_native_video_player)
- Fixed plugin registration in Android
0.1.0 - 2025-10-20 #
Changed #
- Updated Flutter SDK constraint to 3.9.2
- Updated flutter_lints to 6.0.0
0.0.1 - 2025-01-16 #
Added #
- Initial release of native_video_player plugin
- Native video playback using AVPlayerViewController (iOS) and ExoPlayer/Media3 (Android)
- HLS streaming support with adaptive quality selection
- Picture-in-Picture (PiP) mode on both platforms
- Native fullscreen playback
- Now Playing integration (Control Center on iOS, lock screen on Android)
- Background playback with media notifications
- Comprehensive playback controls:
- Play/pause
- Seek to position
- Volume control
- Playback speed adjustment (0.5x to 2.0x)
- Quality selection for HLS streams
- Event streaming for player state changes
- Support for custom media info (title, subtitle, album, artwork)
- Configurable PiP behavior
- Native player controls toggle
- Example app demonstrating all features
- Comprehensive documentation and API reference
Platform Support #
- iOS 12.0+
- Android API 24+ (Android 7.0+)
Dependencies #
- Flutter SDK ^3.9.2
- iOS: AVFoundation framework
- Android: androidx.media3 1.5.0 (ExoPlayer, HLS, Session)