A Flutter video player built on top of video_player with resume watching, progress tracking, completion detection, and fullscreen support.
Designed for learning platforms, coaching apps, fitness apps, and any application that needs to track user video progress.
- Resume watching automatically
- Track video progress
- Completion detection
- Fullscreen support
- Analytics integration
- Custom controls
- Custom storage providers
- Network, Asset, and File video support
Building a video-based learning experience usually requires more than simply playing a video.
Many applications need to:
- Save and restore the user's last watched position
- Track watch progress
- Detect when a video is completed
- Trigger analytics events
- Handle fullscreen orientation changes
- Integrate with custom databases and APIs
video_progress_player provides these capabilities out of the box while remaining flexible and backend-agnostic.
The package focuses on reducing the amount of boilerplate required to build learning, coaching, training, and fitness applications that rely on video content.
This package is a good fit for:
- Learning Management Systems (LMS)
- Online Courses
- Coaching Platforms
- Fitness Applications
- Employee Training Systems
- Certification Programs
- Video-Based Onboarding Flows
- Simple setup with sensible defaults
- Resume watching across app sessions
- Built-in progress tracking
- Configurable completion detection
- Analytics integration points
- Custom storage support
- Custom controls support
- Fullscreen and orientation management
- Works with Network, Asset, and File videos
| Platform | Supported |
|---|---|
| Android | Yes |
| iOS | Yes |
| iPadOS | Yes |
| Web | Based on video_player support |
| macOS | Based on video_player support |
| Windows | Based on video_player support |
| Linux | Based on video_player support |
Add the package to your pubspec.yaml:
dependencies:
video_progress_player: ^0.0.1Then run:
flutter pub getSince this package streams video over the internet and manages device orientation, you must configure native permissions for Android and iOS.
Open android/app/src/main/AndroidManifest.xml and add the Internet permission above the <application> tag:
<uses-permission android:name="android.permission.INTERNET"/>(Optional: If you are streaming HTTP instead of HTTPS, also add android:usesCleartextTraffic="true" to the <application> tag).
No additional configuration is required for HTTPS video URLs.
If you need to stream non-secure HTTP content, configure App Transport Security (ATS) in your Info.plist according to Apple's guidelines.
The simplest way to use the package:
import 'package:video_progress_player/video_progress_player.dart';
VideoProgressPlayer.network(
url: 'https://example.com/video.mp4',
)Provide a resumeKey to automatically save and restore the user's last watched position.
Note
The resumeKey should be a unique identifier from your database for the specific video being played (e.g., a Video ID like 'course_42_lesson_1' or 'movie_uuid_8f73b2'). Do not hardcode a generic string like 'lesson_1' for all videos, or progress will be overwritten!
VideoProgressPlayer.network(
url: 'https://example.com/video.mp4',
resumeKey: 'lesson_1',
)Listen to progress updates:
VideoProgressPlayer.network(
url: 'https://example.com/video.mp4',
onProgressChanged: (progress) {
print(progress.percentage);
},
)VideoProgress(
watched: Duration,
total: Duration,
percentage: double,
)Receive a callback when a video reaches the completion threshold.
VideoProgressPlayer.network(
url: 'https://example.com/video.mp4',
onCompleted: () {
print('Video completed');
},
)VideoProgressPlayer.network(
url: 'https://example.com/video.mp4',
completionStrategy: PercentageCompletionStrategy(95),
)Control playback programmatically.
final controller = VideoProgressController();
VideoProgressPlayer.network(
url: videoUrl,
controller: controller,
);controller.play();
controller.pause();
controller.seekTo(
const Duration(minutes: 5),
);
controller.setPlaybackSpeed(1.5);
controller.enterFullscreen();
controller.exitFullscreen();Create a custom analytics provider:
class MyAnalyticsProvider implements AnalyticsProvider {
@override
void onPlay() {}
@override
void onPause() {}
@override
void onSeek(Duration from, Duration to) {}
@override
void onResume(Duration position) {}
@override
void onComplete() {}
@override
void onFullscreen(bool isFullscreen) {}
}Use it:
VideoProgressPlayer.network(
url: videoUrl,
analyticsProvider: MyAnalyticsProvider(),
)Store progress in your own backend:
class FirebaseStorageProvider
implements ProgressStorageProvider {
@override
Future<void> saveProgress(
String key,
VideoProgress progress,
) async {
// Save progress
}
@override
Future<VideoProgress?> loadProgress(
String key,
) async {
// Load progress
return null;
}
}Use it:
VideoProgressPlayer.network(
url: videoUrl,
resumeKey: 'lesson_1',
storageProvider: FirebaseStorageProvider(),
)Replace the default controls with your own UI.
VideoProgressPlayer(
videoSource: NetworkVideoSource(
url: videoUrl,
),
controlsBuilder: (
context,
controller,
videoController,
) {
return MyCustomControls();
},
)NetworkVideoSource(
url: videoUrl,
)AssetVideoSource(
assetPath: 'assets/video.mp4',
)FileVideoSource(
file: videoFile,
)Built-in fullscreen support includes:
- Android fullscreen mode
- iPhone fullscreen mode
- iPad support
- Orientation restoration
- Immersive mode
Listen for fullscreen changes:
VideoProgressPlayer.network(
url: videoUrl,
onFullscreenChanged: (isFullscreen) {},
)If your app is strictly portrait-only, but you want to allow landscape only when the video is in fullscreen, you must enable all orientations in your OS settings:
- iOS: Check
Landscape LeftandLandscape Rightin XCode (Info.plist). - Android: Do not restrict orientation in
AndroidManifest.xml.
Then, force your app into portrait at the top level in your main.dart:
void main() {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setPreferredOrientations([
DeviceOrientation.portraitUp,
]);
runApp(MyApp());
}This allows video_progress_player to temporarily override the portrait lock when the user taps the fullscreen button!
A complete example application is available in the example/ folder.
It demonstrates:
- Basic playback
- Resume watching
- Progress tracking
- Completion detection
- Custom analytics integration
- Custom storage providers
- Fullscreen handling
Future releases may include:
- YouTube support
- Vimeo support
- Additional completion strategies
- Offline video support
Issues and pull requests are welcome.
Apache License 2.0