Using Video and Image Assets Inside a Flutter App

Using Video and Image Assets Inside a Flutter App

This article is simply about how to display images and play videos on your flutter app using network or local assets. In simple words an asset is a file that is bundled and deployed with your app, and is accessible at runtime. An asset can be an image, a video, a font etc. So let's get started.

As you can see in the above video. There are two containers, one with a network image and another with a video asset. So let's first install the video player module using pub. For this go to your pubspec.yaml file and type these lines.

dependencies:
  flutter:
    sdk: flutter
  
  video_player:

Then make an assets directory in your root folder and under the flutter assets section in pubspec.yaml file provide with the path of your image or video which you are planning to embed.

assets:
  
  - assets/VIDEO_NAME.EXTENSION

After updating your pubspec file. Run the command pub get in your terminal. Also if you are using Android Studio you can simply click on the pub get link on top of the file.

Now let's come to our main.dart file inside our lib folder. First we'll have to import the packages.

import 'dart:async';

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

dart:async provide us with async methods that are used when you have to wait for a few task to process. In that case you can complete your other tasks and come back to the previous one after processing.

material.dart provides us with Flutter widgets implementing Material Design.

video_player/video_player.dart is a package that will help us in playing our videos on the app.

void main() => runApp(VideoPlayerApp());

class VideoPlayerApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Video Player Demo',
      home: VideoPlayerScreen(),
    );
  }
}

As you can see we have created a StatelessWidget and passed it to our runApp method. Our VideoPlayerApp will create a MaterialApp for us. The debugShowCheckedModeBanner is set to false. It simply removes the debug banner from your app. We have given the app a title and passed VideoPlayerScreen() to the home property. Let's look at our VideoPlayerScreen next.

class VideoPlayerScreen extends StatefulWidget {
  VideoPlayerScreen({Key key}) : super(key: key);

  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    // Create and store the VideoPlayerController. The VideoPlayerController
    // offers several different constructors to play videos from assets, files,
    // or the internet.
    _controller = VideoPlayerController.asset('assets/vidOne.mp4');

    // Initialize the controller and store the Future for later use.
    _initializeVideoPlayerFuture = _controller.initialize();

    // Use the controller to loop the video.
    _controller.setLooping(true);

    super.initState();
  }

  @override
  void dispose() {
    // Ensure disposing of the VideoPlayerController to free up resources.
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // here are we'll make our widget tree
  }           

In the above code we have initialized the VideoPlayerController by doing the following:

  • Created a StatefulWidget with a companion State class
  • Added a variable to the State class to store the VideoPlayerController
  • Added a variable to the State class to store the Future returned from VideoPlayerController.initialize
  • Created and initialized the controller in the initState method
  • Disposed of the controller in the dispose method

Now, display the video. The video_player plugin provides the VideoPlayer widget to display the video initialized by the VideoPlayerController. By default, the VideoPlayer widget takes up as much space as possible. This often isn’t ideal for videos because they are meant to be displayed in a specific aspect ratio, such as 16x9 or 4x3.

Therefore, wrap the VideoPlayer widget in an AspectRatio widget to ensure that the video has the correct proportions.

Furthermore, you must display the VideoPlayer widget after the _initializeVideoPlayerFuture() completes. Use FutureBuilder to display a loading spinner until the controller finishes initializing. Note: initializing the controller does not begin playback.

// Use a FutureBuilder to display a loading spinner while waiting for the
// VideoPlayerController to finish initializing.
FutureBuilder(
  future: _initializeVideoPlayerFuture,
  builder: (context, snapshot) {
    if (snapshot.connectionState == ConnectionState.done) {
      // If the VideoPlayerController has finished initialization, use
      // the data it provides to limit the aspect ratio of the VideoPlayer.
      return AspectRatio(
        aspectRatio: _controller.value.aspectRatio,
        // Use the VideoPlayer widget to display the video.
        child: VideoPlayer(_controller),
      );
    } else {
      // If the VideoPlayerController is still initializing, show a
      // loading spinner.
      return Center(child: CircularProgressIndicator());
    }
  },
)

To play and pause the video we'll use a FloatingActionButton. By default, the video starts in a paused state. To begin playback, call the play() method provided by the VideoPlayerController. To pause playback, call the pause() method.

Let's add a FloatingActionButton to our app that displays a play or pause icon depending on the situation. When the user taps the button, play the video if it’s currently paused, or pause the video if it’s playing.

FloatingActionButton(
  onPressed: () {
    // Wrap the play or pause in a call to `setState`. This ensures the
    // correct icon is shown
    setState(() {
      // If the video is playing, pause it.
      if (_controller.value.isPlaying) {
        _controller.pause();
      } else {
        // If the video is paused, play it.
        _controller.play();
      }
    });
  },
  // Display the correct icon depending on the state of the player.
  child: Icon(
    _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
  ),
)

Now to add an image using a url. We can simply use the Image.network() function.

Image(image: NetworkImage('https://YOUR_URL')
                  ),

So let's look at the full code for this app.

import 'dart:async';

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

void main() => runApp(VideoPlayerApp());

class VideoPlayerApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Video Player Demo',
      home: VideoPlayerScreen(),
    );
  }
}

class VideoPlayerScreen extends StatefulWidget {
  VideoPlayerScreen({Key key}) : super(key: key);

  @override
  _VideoPlayerScreenState createState() => _VideoPlayerScreenState();
}

class _VideoPlayerScreenState extends State<VideoPlayerScreen> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    // Create and store the VideoPlayerController. The VideoPlayerController
    // offers several different constructors to play videos from assets, files,
    // or the internet.
    _controller = VideoPlayerController.asset('assets/vidOne.mp4');

    // Initialize the controller and store the Future for later use.
    _initializeVideoPlayerFuture = _controller.initialize();

    // Use the controller to loop the video.
    _controller.setLooping(true);

    super.initState();
  }

  @override
  void dispose() {
    // Ensure disposing of the VideoPlayerController to free up resources.
    _controller.dispose();

    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.black,
      appBar: AppBar(
        backgroundColor: Colors.black,
        title: Center(child: Text('Black Lives Matter')),
      ),
      // Use a FutureBuilder to display a loading spinner while waiting for the
      // VideoPlayerController to finish initializing.
      body: Column(
        children: <Widget>[
          Container(
            color: Colors.black,
            child: Card(
              child: Column(
                mainAxisSize: MainAxisSize.min,
                children: <Widget>[
                  Image(
                    image: NetworkImage('https://URL'),
                  ),
                  Container(
                    color: Colors.black,
                    child: ButtonBar(
                      alignment: MainAxisAlignment.center,
                      children: <Widget>[
                        FlatButton(
                          child: const Text('Imagine all the people living life in peace', textAlign: TextAlign.center,
                            style: TextStyle(color: Colors.white, fontStyle: FontStyle.italic,
                                fontSize: 20),),
                          onPressed: () {/* ... */},
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
          Container(
            width: double.infinity,
            height: 200,
            child: FutureBuilder(
              future: _initializeVideoPlayerFuture,
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.done) {
                  // If the VideoPlayerController has finished initialization, use
                  // the data it provides to limit the aspect ratio of the video.
                  return AspectRatio(
                    aspectRatio: _controller.value.aspectRatio,
                    // Use the VideoPlayer widget to display the video.
                    child: VideoPlayer(_controller),
                  );
                } else {
                  // If the VideoPlayerController is still initializing, show a
                  // loading spinner.
                  return Center(child: CircularProgressIndicator());
                }
              },
            ),
          ),
        ],
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          // Wrap the play or pause in a call to `setState`. This ensures the
          // correct icon is shown.
          setState(() {
            // If the video is playing, pause it.
            if (_controller.value.isPlaying) {
              _controller.pause();
            } else {
              // If the video is paused, play it.
              _controller.play();
            }
          });
        },
        // Display the correct icon depending on the state of the player.
        child: Icon(
          _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
        ),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

That's all. In case your video doesn't start try restarting your app again. Sometimes hot reload doesn't work in this case. Happy coding!

要查看或添加评论,请登录

Chaitanya Tyagi的更多文章

  • External Authorization using Istio, OPA and OpenFGA

    External Authorization using Istio, OPA and OpenFGA

    I have been looking into multiple solutions around authentication and authorization lately and today we are going to…

    3 条评论
  • Authorization using Casbin in GO

    Authorization using Casbin in GO

    What is Authorization and why do we need it? Imagine that you are the owner of a big store chain. Now to manage your…

    1 条评论
  • Pluggable Authentication Modules (PAM)

    Pluggable Authentication Modules (PAM)

    This is a very introductory article about PAM but I hope that this will kindle a bit of curiosity among the readers on…

  • Creating a Public and Private Subnet in AWS

    Creating a Public and Private Subnet in AWS

    AWS offer highly secure and available network solutions with consistently high performance and global coverage. Today…

  • Deploying Infrastructure Using Terraform

    Deploying Infrastructure Using Terraform

    Terraform enables users to define and provision a datacenter infrastructure using a high-level configuration language…

  • Automate the learning using Docker and Jenkins.

    Automate the learning using Docker and Jenkins.

    Let's automate the learning process using Docker and Jenkins! THE TASK AT HAND: Let's say you have to train a model on…

    3 条评论

社区洞察

其他会员也浏览了