How would I have a video fill the screen without stretching (using Chewie or similar)?
// an arbitrary value, this can be whatever you need it to be
double videoContainerRatio = 0.5;
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;
}
}
Place an AspectRatio as high as you can in your widget tree, possibly directly above Chewie. This will determine the bounds of the video.
AspectRatio( aspectRatio: videoContainerRatio, child: Chewie(...), )
Wrap Chewie in a Stack().
Now wrap your Chewie in a new AspectRatio and set its ratio to the _videoPlayerController aspect ratio:
AspectRatio( aspectRatio: videoContainerRatio, child: Stack( children: <Widget>[ AspectRatio( aspectRatio: _videoPlayerController , child: Chewie(...), ), ] ),
Now wrap the new AspectRatio in a Transform.scale() like this:
Transform.scale( scale: getScale(), child: AspectRatio( aspectRatio: _videoPlayerController , child: Chewie(...), ), );
frax
Updated on December 20, 2022Comments
-
frax over 1 year
As the title says, is it possible to have a video fill the screen without visible stretching? If so, how would I do this with chewie?
Link to chewie: https://pub.dev/packages/chewie
The player fills the screen but the video is stretched because I've used MediaQuerys, but I don't know any other way to change the size of the player other than provide an aspectratio. I need to preserve the video's aspectratio but also have the video fit the screen.
My current code:
import 'dart:io'; import 'package:flutter/material.dart'; import 'package:chewie/chewie.dart'; import 'package:video_player/video_player.dart'; class MyVideoPlayer extends StatefulWidget { final String path; MyVideoPlayer({Key key, @required this.path}) : super(key: key); @override _MyVideoPlayerState createState() => new _MyVideoPlayerState(); } class _MyVideoPlayerState extends State<MyVideoPlayer> { VideoPlayerController _videoPlayerController; ChewieController _chewieController; Future<void> _future; TargetPlatform _platform; Future<void> initVideoPlayer() async { await _videoPlayerController.initialize(); setState(() { print(_videoPlayerController.value.aspectRatio); _chewieController = ChewieController( aspectRatio: MediaQuery.of(context).size.width/ MediaQuery.of(context).size.height, videoPlayerController: _videoPlayerController, autoPlay: false, looping: false, // showControls: false, materialProgressColors: ChewieProgressColors( playedColor: Colors.red, handleColor: Colors.blue, backgroundColor: Colors.grey, bufferedColor: Colors.lightGreen, ), // placeholder: Container( // color: Colors.grey, // ), ); }); } @override void initState() { super.initState(); // _controller = VideoPlayerController.network('https://www.sample-videos.com/video123/mp4/720/big_buck_bunny_720p_20mb.mp4'); _videoPlayerController = VideoPlayerController.file(File(widget.path)); _future = initVideoPlayer(); } @override Widget build(BuildContext context) { return MaterialApp( theme: ThemeData.light().copyWith( platform: _platform ?? Theme.of(context).platform, ), home: Scaffold( body: FutureBuilder( future: _future, builder: (context, snapshot) { return _videoPlayerController.value.initialized ? Chewie( controller: _chewieController, ) : Center(child: CircularProgressIndicator()); }), ), ); } @override void dispose() { _videoPlayerController.dispose(); _chewieController.dispose(); super.dispose(); } }
-
frax over 3 yearsThat is the correct way to do aspect ratio, however as far as that goes I could not find a solution for it to fill screen without using another plugin. (and not cropping horizontally) It is a similar issue to this: stackoverflow.com/questions/49946153/…. The plugin flick_video_player seems to account for device height and width and preserve aspect ratio.