Rocco Labellarte
 · Never Give Up, Never Surrender

Chewie Custom Video Player

This document provides an overview of a custom video player widget built using Chewie and video_player packages. This custom video player is designed to be used within a FlutterFlow project.

Introduction

Having worked through a number of examples shared within the community, I found that, over time, these examples have become unusable, either because they were incomplete, or that packages and solutions become superseded.

My requirement was quite simple. I wanted the ability to display a full-screen video with audio in portrait mode, which autoplays when the page is loaded, taking the file from Firebase storage. I also wanted the ability to pause and restart the image when tapping on the screen. After a bit of playing around with the scarce documentation online, I finally got the solution working, which I am happy to share with the wider FF community.

Overview

This custom video player widget uses chewie, a wrapper around video_player, to provide a more user-friendly video player interface. The widget allows playing videos from network URLs, with features such as play/pause on tap, volume control, and aspect ratio adjustments.

Dependencies

Make sure you have the following dependencies in Flutterflow:

chewie: 1.7.5

video_player: (Use the one in Flutterflow)

Code

// Automatic FlutterFlow imports
import '/flutter_flow/flutter_flow_theme.dart';
import '/flutter_flow/flutter_flow_util.dart';
import '/custom_code/widgets/index.dart'; // Imports other custom widgets
import '/flutter_flow/custom_functions.dart'; // Imports custom functions
import 'package:flutter/material.dart';
// Begin custom widget code
// DO NOT REMOVE OR MODIFY THE CODE ABOVE!
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';
// Define a custom widget named CustomVidPlayer
class CustomVidPlayer extends StatefulWidget {
  CustomVidPlayer({
    this.width,
    this.height,
    required this.videoPath,
  });
  final double? width;
  final double? height;
  final String videoPath;
  @override
  _CustomVidPlayerState createState() => _CustomVidPlayerState();
}
class _CustomVidPlayerState extends State<CustomVidPlayer> {
  late VideoPlayerController _videoPlayerController;
  late ChewieController _chewieController;
  late Future<void> _initializeVideoPlayerFuture;
  double videoContainerRatio = 0.5;
  @override
  void initState() {
    super.initState();
    _videoPlayerController =
        VideoPlayerController.networkUrl(Uri.parse(widget.videoPath));
    _initializeVideoPlayerFuture = _videoPlayerController.initialize();
    _videoPlayerController.setVolume(1.0);
  }
  @override
  void dispose() {
    _videoPlayerController.dispose();
    _chewieController.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initializeVideoPlayerFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          _chewieController = ChewieController(
            videoPlayerController: _videoPlayerController,
            aspectRatio: _videoPlayerController.value.aspectRatio,
            autoInitialize: true,
            looping: false,
            showControls: false,
            autoPlay: true,
          );
          return Container(
            child: Transform.scale(
              scale: getScale(),
              child: AspectRatio(
                aspectRatio: _videoPlayerController.value.aspectRatio,
                child: Stack(
                  children: [
                    // Display the video using Chewie
                    Chewie(
                      controller: _chewieController,
                    ),
                    GestureDetector(
                      onTap: toggleVideoPlayback, // play / pause video on tap
                      behavior: HitTestBehavior.opaque,
                    ),
                  ],
                ),
              ),
            ),
          );
        } else {
          return Center(
            child: CircularProgressIndicator(),
          );
        }
      },
    );
  }
  double getScale() {
    double videoRatio = _videoPlayerController.value.aspectRatio;
    if (videoRatio < videoContainerRatio) {
      ///for tall videos, we just return the inverse of the controller aspect ratio
      return videoContainerRatio / videoRatio;
    } else {
      ///for wide videos, divide the video AR by the fixed container AR
      ///so that the video does not over scale
      return videoRatio / videoContainerRatio;
    }
  }
  void toggleVideoPlayback() {
    if (_videoPlayerController.value.isPlaying) {
      _chewieController.pause();
      print("Paused");
    } else {
      _chewieController.play();
      print("Playing");
    }
  }
}

Parameters

What’s Going On?

Imports and Initialization:

  • The required packages and dependencies are imported.

  • VideoPlayerController from video_player package and ChewieController from chewie package are used.

CustomVidPlayer Widget:

  • This widget takes width, height, and videoPath as parameters.

  • width and height define the size of the video player.

  • videoPath is the URL of the video to be played.

State Management:

  • _CustomVidPlayerState manages the state of the video player.

  • The initState method initializes the video player with the provided video URL and sets the volume.

Video Player Initialization:

  • _initializeVideoPlayerFuture is used to handle the asynchronous initialization of the video player.

Dispose Method:

  • The dispose method disposes of the video player controller and chewie controller to free up resources.

Build Method:

  • The build method uses a FutureBuilder to ensure the video is loaded before displaying it.

  • A ChewieController is created to manage the video player settings such as aspect ratio, auto play, and looping.

  • The Container widget uses Transform.scale to maintain the aspect ratio and scale of the video.

Helper Methods:

  • getScale method adjusts the scale of the video based on its aspect ratio.

  • toggleVideoPlayback method toggles the video playback between play and pause on tap.

Notes

  • The Chewie package provides a simplified wrap around the video_player interface with custom controls.

  • Ensure to use compatible versions of chewie and video_player to avoid conflicts with other dependencies, such as provider.

This documentation should help developers understand and use the custom video player widget in their FlutterFlow projects.

Happy Coding.

Article originally published here: Flutterflow Custom Video Player. Video Player Widget (Chewie) | by Rocco Labellarte | May, 2024 | Medium

8
2 replies