Flutter – Handling Videos: A Comprehensive Guide with Examples

Introduction

Flutter is a popular open-source UI software development kit (SDK) created by Google, designed for building natively compiled applications for mobile, web, and desktop platforms from a single codebase. With Flutter, developers can create visually appealing and feature-rich applications, including those that handle video content seamlessly. In this blog post, we will explore various methods to handle videos in Flutter, along with practical examples to demonstrate their implementation.

Adding Dependencies

To get started with video handling in Flutter, we need to include relevant dependencies in the project. The two primary packages for video management are "video_player" and "chewie."

dependencies:
  flutter:
    sdk: flutter
  video_player: ^2.2.0
  chewie: ^2.0.0

To add these dependencies, modify the "pubspec.yaml" file and run flutter pub get to fetch them.

Giving Permissions:

To stream videos from the internet the app will be needing correct set of configuration. Depending upon the OS of the device we can set the permissions as shown below.

Android:

For Android devices, the permission to stream videos from the internet can be added by going into the Androidmanifest.xml file at 

<project root>/android/app/src/main/AndroidManifest.xml. And add the below lines write after the <application> definition :

<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
    Definition of the Flutter Application....
    </application>

    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

iOS:

For iOS devices, the permissions can be given by adding the following to the Info.plist file which is located at <project root>/ios/Runner/Info.plist as shown:

<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

Playing Local Videos

To play local videos, place your video files in the "assets" folder and specify them in the "pubspec.yaml" file:

flutter:
  assets:
    - assets/sample_video.mp4

Next, import the required packages in the Dart file:

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

Now, create a StatefulWidget to handle the video player:

class LocalVideoPlayer extends StatefulWidget {
  @override
  _LocalVideoPlayerState createState() => _LocalVideoPlayerState();
}


class _LocalVideoPlayerState extends State<LocalVideoPlayer> {
  VideoPlayerController _controller;


  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.asset('assets/sample_video.mp4')
      ..initialize().then((_) {
        setState(() {});
      });
  }


  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Local Video Player'),
      ),
      body: _controller.value.isInitialized
          ? AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              child: VideoPlayer(_controller),
            )
          : Center(
              child: CircularProgressIndicator(),
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _controller.value.isPlaying
                ? _controller.pause()
                : _controller.play();
          });
        },
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}

The code above creates a simple Flutter app that plays a local video when you open it.

Streaming Videos from the Internet

To stream videos from the Internet, change the VideoPlayerController's source:

VideoPlayerController.network('assets/sample_video.mp4')

Using Chewie for Better Video Playback Controls

The "chewie" package provides better video playback controls than the default ones. First, add the dependency:

dependencies:
  chewie: ^2.0.0

Next, import the "chewie" package along with "video_player":

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

Now, modify the StatefulWidget to use Chewie:

class ChewieVideoPlayer extends StatefulWidget {
  @override
  _ChewieVideoPlayerState createState() => _ChewieVideoPlayerState();
}


class _ChewieVideoPlayerState extends State<ChewieVideoPlayer> {
  late VideoPlayerController _controller;
  late ChewieController _chewieController;


  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'))
      ..initialize().then((_) {
        setState(() {});
      });
    _chewieController = ChewieController(
      videoPlayerController: _controller,
      autoPlay: true,
      looping: true,
    );
  }


  @override
  void dispose() {
    _controller.dispose();
    _chewieController.dispose();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Chewie Video Player'),
      ),
      body: Center(
        child: Chewie(
          controller: _chewieController,
        ),
      ),
    );
  }
} 

Complete Source Code

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


void main() {
  runApp(const MyApp());
}


class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'FlutterforGeeks',
      debugShowCheckedModeBanner: false,
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.green.shade900),
        useMaterial3: true,
      ),
      home: const MyHomePage(title: 'FlutterforGeeks'),
    );
  }
}


class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});


  final String title;


  @override
  State<MyHomePage> createState() => _MyHomePageState();
}


class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.primary,
        title: Text(
          widget.title,
          style: const TextStyle(color: Colors.white),
        ),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(
                      builder: (context) => LocalVideoPlayer()));
                },
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                    'Video Player',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
                  ),
                )),
            const SizedBox(
              height: 30,
            ),
            ElevatedButton(
                onPressed: () {
                  Navigator.of(context).push(MaterialPageRoute(
                      builder: (context) => ChewieVideoPlayer()));
                },
                child: const Padding(
                  padding: EdgeInsets.all(8.0),
                  child: Text(
                    'Chewie Video Player',
                    style: TextStyle(fontWeight: FontWeight.bold, fontSize: 20),
                  ),
                ))
          ],
        ),
      ),
      // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}


class LocalVideoPlayer extends StatefulWidget {
  @override
  _LocalVideoPlayerState createState() => _LocalVideoPlayerState();
}


class _LocalVideoPlayerState extends State<LocalVideoPlayer> {
  late VideoPlayerController _controller;


  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'))
      ..initialize().then((_) {
        setState(() {});
      });
  }


  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Local Video Player'),
      ),
      body: _controller.value.isInitialized
          ? AspectRatio(
              aspectRatio: _controller.value.aspectRatio,
              child: VideoPlayer(_controller),
            )
          : const Center(
              child: CircularProgressIndicator(),
            ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            _controller.value.isPlaying
                ? _controller.pause()
                : _controller.play();
          });
        },
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ),
    );
  }
}


class ChewieVideoPlayer extends StatefulWidget {
  @override
  _ChewieVideoPlayerState createState() => _ChewieVideoPlayerState();
}


class _ChewieVideoPlayerState extends State<ChewieVideoPlayer> {
  late VideoPlayerController _controller;
  late ChewieController _chewieController;


  @override
  void initState() {
    super.initState();
    _controller = VideoPlayerController.networkUrl(Uri.parse(
        'https://storage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4'))
      ..initialize().then((_) {
        setState(() {});
      });
    _chewieController = ChewieController(
      videoPlayerController: _controller,
      autoPlay: true,
      looping: true,
    );
  }


  @override
  void dispose() {
    _controller.dispose();
    _chewieController.dispose();
    super.dispose();
  }


  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Chewie Video Player'),
      ),
      body: Center(
        child: Chewie(
          controller: _chewieController,
        ),
      ),
    );
  }
}

GitHub Repository - Find the complete code for each example in this tutorial on GitHub.

Video Demo


Conclusion

In this blog post, we explored various methods to handle videos in Flutter. We started by playing local videos using the "video_player" package and then learned how to stream videos from the internet. Additionally, we enhanced the video playback experience by integrating the "chewie" package. You can now implement these techniques in your Flutter projects to create stunning video-based applications with ease. Happy coding!

Description of the image

Related Posts