Programmable Media

Flutter video player

Last updated: Jan-29-2024

The Flutter SDK includes a Cloudinary native video player built on top of the Video Player plugin for Flutter. This makes it easy to use the various Cloudinary video capabilities and deliver your videos using the device's native player. For Android, the player uses ExoPlayer and for iOS it uses AVPlayer.

On this page:

Rate this page:

To create a player, use the CldVideoController to create a new controller instance and provide either the public ID for the video or the full Cloudinary URL:

Dart
//Public ID
final CldVideoController _controller = CldVideoController(publicId: 'dog');

//URL 
final CldVideoController _controller = CldVideoController.networkUrl(Uri.parse('https://res.cloudinary.com/demo/video/upload/sp_auto/dog.m3u8'));

Note
If you haven't set your Cloudinary credentials as an environment variable, you need to include the cloudinary object alongside the publicId parameter. For example:
Dart
Cloudinary cloudinary = CloudinaryObject.fromCloudName(cloudName: '<your_cloud_name>');
final CldVideoController _controller = CldVideoController(cloudinary: cloudinary, publicId: 'dog');

Once you have the player controller instance, you can add that to the VideoPlayer imported from the Video Player plugin.

Here's a fully working example of a simple view that renders the video player and a play/pause button:

Dart
import 'package:cloudinary_flutter/cloudinary_object.dart';
import 'package:cloudinary_flutter/video/cld_video_controller.dart';
import 'package:cloudinary_url_gen/cloudinary.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

void main() => runApp(const VideoApp());

/// Stateful widget to fetch and then display video content.
class VideoApp extends StatefulWidget {
  const VideoApp({super.key});

  
  _VideoAppState createState() => _VideoAppState();
}

class _VideoAppState extends State<VideoApp> {
  late CldVideoController _controller;
  Cloudinary cloudinary = CloudinaryObject.fromCloudName(cloudName: 'demo');


  
  void initState() {
    super.initState();

    _controller = CldVideoController(cloudinary: cloudinary, publicId: 'dog')
      ..initialize().then((_) {
        // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
        setState(() {});
      });
  }

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Video Demo',
      home: Scaffold(
        body: Center(
          child: _controller.value.isInitialized
              ? AspectRatio(
                  aspectRatio: _controller.value.aspectRatio,
                  child: VideoPlayer(_controller),
                )
              : Container(),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              _controller.value.isPlaying
                  ? _controller.pause()
                  : _controller.play();
            });
          },
          child: Icon(
            _controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
          ),
        ),
      ),
    );
  }

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

Transformations

You can include video transformations as part of your CldVideoController instance to generate a variation of the original asset. The transformations are defined when initializing the player. For example:

Dart
final CldVideoController _controller = CldVideoController(publicId: 'dog.m3u8', transformation: Transformation().videoEdit(VideoEdit.trim().startOffset("3.0")));

Note

Automatic streaming profile selection is enabled by default. This currently has a limited set of transformations that you can combine with it, therefore when using any transformations, automatic streaming profile selection will be disabled. If you want to include both, check that your transformations are supported and set the streaming profile transformation to auto when initializing your player, for example:

Dart
final CldVideoController _controller = CldVideoController(publicId: 'dog.m3u8', transformation: Transformation().transcode(Transcode.streamingProfile(StreamingProfile.auto())).videoEdit(VideoEdit.trim().startOffset("3.0")));

✔️ Feedback sent!