我不希望我的视频看起来很拉伸。我正在使用Chewie
flutter包作为我的视频播放器。
我尝试使用_controller.value.size.aspectRatio
,但返回错误
The getter 'aspectRatio' was called on null.
这是我从图库获取视频的代码:
Future uploadVideoFromGallery() async {
print("CALLED");
Map<PermissionGroup, PermissionStatus> permissions =
await PermissionHandler().requestPermissions(
[PermissionGroup.storage, PermissionGroup.camera]);
if (permissions[PermissionGroup.storage] == PermissionStatus.granted) {
var videoFile = await ImagePicker.pickVideo(source: ImageSource.gallery);
if (videoFile != null) {
getVideoThumbnail(videoFile.path);
setState(() {
isFileImage = false;
image = videoFile;
_controller = VideoPlayerController.file(image);
});
print(videoFile.path);
}
} else {
debugPrint('permission not granted');
}
}
这是我放置videoFile
的代码:
Chewie(
controller: ChewieController(
videoPlayerController: _controller,
aspectRatio: _controller.value.size.aspectRatio,
materialProgressColors: ChewieProgressColors(
playedColor: Color(colorSecondary),
handleColor: Color(colorPrimary),
bufferedColor: Color(colorPrimary),
),
placeholder: Container(
color: Colors.grey,
),
autoInitialize: true,
looping: false,
errorBuilder: (context, errorMessage) {
return Center(
child: Text(
errorMessage,
style: TextStyle(color: Color(colorText)),
),
);
},
),
)
答案 0 :(得分:6)
github上有一个与此有关的问题。
import 'package:flutter/material.dart';
import 'dart:io';
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;
Future<void> initVideoPlayer() async {
await _videoPlayerController.initialize();
setState(() {
print(_videoPlayerController.value.aspectRatio);
_chewieController = ChewieController(
videoPlayerController: _videoPlayerController,
aspectRatio: _videoPlayerController.value.aspectRatio,
autoPlay: false,
looping: false,
);
});
}
@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 new FutureBuilder(
future: _future,
builder: (context, snapshot) {
return new Center(
child: _videoPlayerController.value.initialized
? AspectRatio(
aspectRatio: _videoPlayerController.value.aspectRatio,
child: Chewie(
controller: _chewieController,
),
)
: new CircularProgressIndicator(),
);
}
);
}
@override
void dispose() {
_videoPlayerController.dispose();
_chewieController.dispose();
super.dispose();
}
}
答案 1 :(得分:3)
如果您只是使用常规的 video_player 包,则可以使用以下代码显示未拉伸的视频版本:
return FittedBox(
fit: BoxFit.cover,
child: SizedBox(
height: model.videoPlayerController.value.size?.height ?? 0,
width: model.videoPlayerController.value.size?.width ?? 0,
child: VideoPlayer(model.videoPlayerController),
),
);
我也写了一篇关于 displaying videos from a URL in Flutter 的文章。
答案 2 :(得分:0)
您必须等到视频播放器控制器初始化。仅在 ChewieController
完成后(在 _playerController.initialize()
块中)将纵横比值分配给 then
。
@override
void initState() {
super.initState();
Uri videoUrl = VideoProvider.fromUri(_post.url).getVideos().first.uri;
_playerController = VideoPlayerController.network(videoUrl.toString());
_initializeVideoPlayerFuture = _playerController.initialize().then((_) {
_chewieController = ChewieController(
videoPlayerController: _playerController,
aspectRatio: _playerController.value.aspectRatio,
allowedScreenSleep: false,
errorBuilder: (context, error) => Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(Icons.error),
Text(error),
],
)),
);
});
}
@override
Widget build(BuildContext context) {
return FutureBuilder(
future: _initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return AspectRatio(
aspectRatio: _playerController.value.aspectRatio,
child: Chewie(
controller: _chewieController,
),
);
} else {
return Center(child: CircularProgressIndicator());
}
},
);
答案 3 :(得分:0)
首先,尝试将 _controller.value.size.aspectRatio
更改为 _controller.value.aspectRatio
。
然后,确保您使用 _controller.initialize()
初始化控制器。
如果它仍然给出错误,则添加一个空检查。
_controller != null
? // Do your code
: Text("Controller is null")
这应该可以解决您的问题。
答案 4 :(得分:0)
better_player 插件解决方案。
在 initState 中:
betterPlayerController = BetterPlayerController(
betterPlayerConfiguration,
betterPlayerDataSource: betterPlayerDataSource,
);
betterPlayerController.addEventsListener((BetterPlayerEvent event) {
if (event.betterPlayerEventType == BetterPlayerEventType.initialized) {
betterPlayerController.setOverriddenAspectRatio(
betterPlayerController.videoPlayerController.value.aspectRatio);
setState(() {});
}
});
正文:
BetterPlayer(controller: betterPlayerController),
答案 5 :(得分:0)
我只使用原始 videoController 的纵横比,没有为 Chewie 的视频控制器设置它,这对我来说很好用。要获得纵横比,您需要确保首先初始化原始视频控制器,并使用它添加一个侦听器,以便在调用 setState 时,您的小部件会使用正确的纵横比视频重建。同时,您可以在未初始化之前显示循环进度项。
这是我将 Chewie 与 VideoPlayer 一起使用的方式,并且纵横比对我来说是正确的:
class _VideoWidget extends StatefulWidget {
String videoURL;
_VideoWidget({required this.videoURL});
@override
_VideoWidgetState createState() => _VideoWidgetState(videoURL: videoURL);
}
class _VideoWidgetState extends State<_VideoWidget> {
late VideoPlayerController _controller;
late Chewie _chewie;
late ChewieController _chewieController;
String videoURL;
_VideoWidgetState({required this.videoURL});
@override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
videoURL,
videoPlayerOptions: VideoPlayerOptions(mixWithOthers: true),
);
_controller.addListener(() {
setState(() {});
});
_controller.setLooping(true);
_controller.initialize();
_chewieController = ChewieController(
videoPlayerController: _controller,
autoPlay: false,
looping: false,
);
_chewie = Chewie(
controller: _chewieController,
);
_chewieController.addListener(() {
if (!_chewieController.isFullScreen)
{
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
}
});
}
@override
void dispose() {
_controller.dispose();
_chewieController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
children: <Widget>[
Container(padding: const EdgeInsets.only(top: 20.0)),
Padding(padding: EdgeInsets.only(top: 20)),
Text("Video",
style: TextStyle(fontSize: 22, fontWeight: FontWeight.bold)),
Center(
child: Container(
height: 300,
padding: const EdgeInsets.all(20),
child: _controller.value.isInitialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: Chewie(
controller: _chewieController,
),
)
: Center(
child: SizedBox(
height: 30.0,
width: 30.0,
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation(Colors.blue),
strokeWidth: 1.0))),
),
),
],
),
);
return _chewie;
}