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:

code
flutter create my_video_app

This 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:

code
dependencies:
flutter:
sdk: flutter
video_player: ^2.8.1

Run this to fetch the package:

code
flutter pub get

Platform Permissions

For network videos, configure permissions in platform files:

  • Android (android/app/src/main/AndroidManifest.xml):
code
<uses-permission android:name="android.permission.INTERNET"/>
  • iOS (ios/Runner/Info.plist):
code
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>

This enables streaming from the internet and avoids connection issues.

Video CDN

Implementing the Video Player Widget

In your lib/main.dart, import the video_player package:

code
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

Create a stateful widget that initializes and controls the video player:

code
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:

code
flutter:
assets:
- assets/videos/my_video.mp4

Change the controller initialization to:

code
_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:

code
flutter run

Test 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:

code
_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.