Video in Flutter

I started a quick app to try to organize a group of photos, which I intend to turn into a video. The problem is that I have a bunch of videos in the batch as well that I need to review. I thought I could get the video to work inside my app, but long story short, I wasn’t able to figure it out. I don’t think video is supported on the Linux platform. Maybe if I was working on Android, it would be a different story.

Anyway, maybe some of my notes will be helpful if you are trying things similar.

I started by installing the “video_player” package:

flutter pub add video_player

Then, I found a player that would take less work building a UI:

flutter pub add chewie

I declared a couple of variables for my controllers up at the top of my class:

late VideoPlayerController _controller;
late Future<void> _initializeVideoPlayerFuture;
late Future<void> _controllersFuture;
late ChewieController _chewieController;

Then, in the initialization method, I setup the controllers. I had planned to use the file method and pull the path for the video on my drive, but I never got the sample to work.

void initState() {
  // Create an store the VideoPlayerController. The VideoPlayerController
  // offers several different constructors to play videos from assets, files,
  // or the internet.
  // _controller = VideoPlayerController.file(File(widget.videoPath));
  _controller =

  _controllersFuture = initControllers();


My initControllers() method sets up both controllers at the same time:

Future<void> initControllers() async {
  _initializeVideoPlayerFuture = _controller.initialize();
  await _initializeVideoPlayerFuture;
  _chewieController = ChewieController(videoPlayerController: _controller, autoPlay:  true, looping: true);

Here’s the build method that creates the UI. It uses a FutureBuilder to show when it is ready:

Widget build(BuildContext context) {
  return FutureBuilder(
    future: _controllersFuture,
    builder: (context, snapshot) {
      print("Built ... connectionState -- ${snapshot.connectionState}, hasData ${snapshot.hasError}");
      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),
          Chewie(controller: _chewieController,),
      } else {
        // If the VideoPlayerController is still initializing, show a
        // loading spinner.
        return Center(child: CircularProgressIndicator());

Don’t forget to dispose the controllers:

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


Linux Desktop not supported

Originally, I thought my problem was that Apple .mov files were not supported. So, I thought I could simply change to a supported format such as .mp4 or .webm. Maybe that would have been the case had I been running on Android. Anyway, here is what I went through.

I was getting this error:

PlatformException(channel-error, Unable to establish connection on channel., null, null)

A quick search shows this command can convert the video:

ffmpeg -i -vcodec h264 -acodec mp2 output.mp4

or for webm:

ffmpeg -i -c:v libvpx -crf 10 -b:v 1M -c:a libvorbis IMG_3548.webm

For the command, I need the new file name with an mp4 on it. I wrote this little procedure to swap out the last 3 characters on the file name:

String getMP4Path() {
  if(fileName.length > 0) {
    if(fileName.substring(fileName.length - 3, fileName.length).toLowerCase() == "mov") {
      return "${_backend.path}/${fileName.substring(0, fileName.length - 3)}mp4";
    } else {
      return "";
  } else {
    return "";

So, I found I could use the Process class to call ffmpeg directly from Flutter:

var result = await"ffmpeg", [
print("converted: ${result.exitCode} -- ${result.stdout}");


So, since I can’t get it to work, I just added a button to open the video with the xdg-open command. Here’s the code:

    onPressed: () {
      var result ="xdg-open", [picture.path]);
    child: Text("Open"),


Leave a Comment

Your email address will not be published. Required fields are marked *