【问题标题】:How to get the actual aspect ratio of the video?如何获得视频的实际宽高比?
【发布时间】:2020-02-26 09:22:31
【问题描述】:

我不希望我的视频看起来被拉长。我正在使用Chewieflutter 包作为我的视频播放器。

我尝试使用_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)),
                              ),
                            );
                          },
                        ),
                      )

【问题讨论】:

  • 从我刚刚阅读的文档来看,它可能只是_controller.value.aspectRatio 而不是_controller.value.size.aspectRatio,所以尝试否定size 数据成员。
  • 这很奇怪。我试过_controller.value.aspectRatio。从我的画廊中选择一个视频后,它仍然被拉伸,然后点击全屏图标。然后再次点击它以关闭全屏。现在它显示了实际的纵横比。
  • 你能展示一下你相机的截图吗?
  • 我们必须等到它被初始化。
  • _controller.value.aspectRatio 总是返回 1.0 作为纵横比。

标签: flutter dart flutter-layout flutter-test


【解决方案1】:

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();
  }
}

This is the github url

【讨论】:

  • 总是返回 1.0 作为纵横比。
【解决方案2】:

如果您只是使用常规的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上写了一篇文章。

【讨论】:

    【解决方案3】:

    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),
    

    【讨论】:

    • 在 BetterPlayer 中很有用
    【解决方案4】:

    您必须等到视频播放器控制器初始化。仅在_playerController.initialize() 完成后(在then 块中)将纵横比值分配给ChewieController

    @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());
            }
          },
        );
    

    【讨论】:

      【解决方案5】:

      首先,尝试将_controller.value.size.aspectRatio 更改为_controller.value.aspectRatio

      然后,确保您使用_controller.initialize() 初始化控制器。

      如果它仍然给出错误,则添加一个空检查。

      _controller != null
          ? // Do your code
          : Text("Controller is null")
      

      这应该可以解决您的问题。

      【讨论】:

        【解决方案6】:

        我只使用原始 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;
          }
        

        【讨论】:

          猜你喜欢
          • 2011-06-27
          • 2012-11-23
          • 2020-10-19
          • 1970-01-01
          • 2015-04-27
          • 2020-09-06
          • 2012-12-02
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多