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.
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:
//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'));
cloudinary
object alongside the publicId
parameter. For example: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:
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:
final CldVideoController _controller = CldVideoController(publicId: 'dog.m3u8', transformation: Transformation().videoEdit(VideoEdit.trim().startOffset("3.0")));
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:
final CldVideoController _controller = CldVideoController(publicId: 'dog.m3u8', transformation: Transformation().transcode(Transcode.streamingProfile(StreamingProfile.auto())).videoEdit(VideoEdit.trim().startOffset("3.0")));