Adding video playback capabilities to your Flutter app enhances user engagement by seamlessly presenting tutorials, demos, or video content within the app environment. This feature helps apps appear modern and interactive without redirecting users to external players. Flutter offers the video_player package, a powerful tool to embed video playback with fine control over UI and behavior.
Prerequisites
Before you start adding video playback to your Flutter app, make sure you have these basics in place:
- Flutter is installed with a development environment like Visual Studio Code or Android Studio.
- Basic knowledge of Dart and Flutter widgets.
- A device or emulator (Android/iOS) for testing.
- Internet connection for installing packages and streaming videos.
- Required platform permissions configured (details below).
Preparing Your Flutter Project
Create a new Flutter project if you haven't already:
flutter create my_video_appThis sets up a basic app structure. Open the project folder with your preferred editor. Confirm the Flutter SDK is properly configured by running the default app on your device or emulator.
Adding the Video Package
Add the official video playback package in pubspec.yaml under dependencies:
dependencies:
flutter:
sdk: flutter
video_player: ^2.8.1Run this to fetch the package:
flutter pub getPlatform Permissions
For network videos, configure permissions in platform files:
- Android (android/app/src/main/AndroidManifest.xml):
<uses-permission android:name="android.permission.INTERNET"/>- iOS (ios/Runner/Info.plist):
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>This enables streaming from the internet and avoids connection issues.
Implementing the Video Player Widget
In your lib/main.dart, import the video_player package:
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';Create a stateful widget that initializes and controls the video player:
class VideoScreen extends StatefulWidget {
@override
_VideoScreenState createState() => _VideoScreenState();
}
class _VideoScreenState extends State<VideoScreen> {
late VideoPlayerController _controller;
late Future<void> _initializeVideoPlayerFuture;
@override
void initState() {
super.initState();
// Use Uri.parse with networkUrl constructor for improved type safety
_controller = VideoPlayerController.networkUrl(
Uri.parse('https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'),
);
// Initialize the controller and store the Future for FutureBuilder
_initializeVideoPlayerFuture = _controller.initialize();
// Optional: Loop the video continuously
_controller.setLooping(true);
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Video Player')),
body: Center(
child: FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
);
} else if (snapshot.hasError) {
return Text('Error loading video: ${snapshot.error}');
} else {
return const CircularProgressIndicator();
}
},
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_controller.value.isPlaying ? _controller.pause() : _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
);
}
}This sets up a video player with proper initialization handling and error display. The FutureBuilder ensures the UI waits for the video to load before playing.
Using Local Videos
For local assets, place video files under an assets/videos directory and declare them in pubspec.yaml:
flutter:
assets:
- assets/videos/my_video.mp4Change the controller initialization to:
_controller = VideoPlayerController.asset('assets/videos/my_video.mp4');
_initializeVideoPlayerFuture = _controller.initialize();Test Your Video Playback
You can test the video playback by running the app using:
flutter runTest playback on multiple devices to ensure proper operation. Check your internet connection when using network videos. Verify file paths and asset declarations for local videos.
Handling Errors and Improvements
Sometimes videos fail to load. Add error handling like this in your initState:
_controller.initialize().then((_) {
setState(() {});
}).catchError((error) {
print('Video load error: $error');
});For a better user experience, add volume controls or full-screen mode using extra widgets. You can also loop videos by setting _controller.setLooping(true). These small changes make your app feel more polished.
Tips for Enhancing User Experience
- Add volume controls using _controller.setVolume(double).
- Implement full-screen by toggling screen orientation and resizing.
- Handle errors gracefully using the FutureBuilder error state.
- Loop videos for continuous playback with _controller.setLooping(true).
With this powerful setup, your app effectively integrates video playback for a smooth and native experience that keeps users engaged within your Flutter app.

