video_player не плавный на устройствах нижнего уровня - PullRequest
0 голосов
/ 18 апреля 2020

Я использую video_player в моем приложении флаттера на iOS для воспроизведения и воспроизведения видео из локального файла после его загрузки. Я следовал руководству " Воспроизведение и приостановка видео " из поваренной книги флаттера.

Чтобы воспроизвести видео один раз после завершения загрузки, я использую addPostFrameCallback из WidgetsBinding. Затем пользователь может воспроизвести видео, нажав на него.

WidgetsBinding.instance.addPostFrameCallback((_) => afterBuild());

Это работает хорошо в большинстве случаев, но на старых устройствах, таких как iPad air 1-го поколения, иногда рендеринг видео происходит не плавно и падает некоторые кадры или немного звука при запуске, создавая впечатление прерывистого звука или видео.

Обратите внимание, что я играю очень короткие видео (от ~ 1 до ~ 3 секунд), я не знаю, может ли это повлиять на производительность video_player (который может потребоваться немного для запуска видео и воспроизводить его плавно?)

Ниже приведен мой текущий код.

Уже давно я занимаюсь этим вопросом и не знаю, как устранить неполадки. Я уже пытался немного задержать первый звонок для воспроизведения видео (что дало игроку немного больше времени), но это не решило проблему. Иногда видео по-прежнему не воспроизводится гладко.

Есть идеи, что еще попробовать?

Вот мой код:

class MyVideoPlayer extends StatefulWidget {
  final File videoFile;

  MyVideoPlayer({Key key, this.videoFile}) : super(key: key);

  @override
  _MyVideoPlayerState createState() => _MyVideoPlayerState();
}

class _MyVideoPlayerState extends State<MyVideoPlayer> {
  VideoPlayerController _controller;
  Future<void> _initializeVideoPlayerFuture;

  @override
  void initState() {
    _controller = VideoPlayerController.file(widget.videoFile);

    WidgetsBinding.instance.addPostFrameCallback((_) => afterBuild());

    _controller.addListener(() async {
      if (_controller.value.duration != null &&
          _controller.value.position >= _controller.value.duration) {
        await _controller.seekTo(Duration(seconds: 0));
        await _controller.pause();
      }
    });

    _initializeVideoPlayerFuture = _controller.initialize();
    super.initState();
  }

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

  _videoPressed() async {
    if (!_controller.value.isPlaying) {
     _controller.play();
    }
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: _initializeVideoPlayerFuture,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          return AspectRatio(
            aspectRatio: _controller.value.aspectRatio,
            child: GestureDetector(
              onTap: () {
                _videoPressed();
              },
              child: VideoPlayer(_controller),
            ),
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }

  void afterBuild() {
    _videoPressed();
  }
}

...