flutter开发实战-video_player播放多个视频MediaCodecVideoRenderer error问题

flutter开发实战-video_player播放多个视频MediaCodecVideoRenderer error问题

在开发过程中,我这里使用video_player播放多个视频的时候,出现了MediaCodecVideoRenderer error

一、使用video_player播放视频

使用video_player播放耽搁视频请查看
https://blog.csdn.net/gloryFlow/article/details/132124837

这里记录一下解决多个视频MediaCodecVideoRenderer error问题。

二、在app/build.gradle下添加依赖

在app/build.gradle下添加依赖

dependencies{
    implementation 'com.google.android.exoplayer:exoplayer:2.17.1'
}

实现播放视频的Widget,在播放测试过程中,出现只能播放一个视频,可以设置VideoPlayerOptions,将VideoPlayerOptions的mixWithOthers设置为true。

Future<void> waitVideoPlay() async {
    _controller?.dispose();

    _controller = VideoPlayerController.networkUrl(
      Uri.parse(widget.videoUrl),
      videoPlayerOptions: VideoPlayerOptions(
        mixWithOthers: true,
        allowBackgroundPlayback: false,
      ),
    );

    await _controller?.initialize().then((_) {
      // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
      setState(() {});
    });

    await _controller!.setLooping(true);
    if (widget.autoPlay) {
      await _controller?.play();
    } else {
      await _controller?.pause();
    }
  }

完整VideoPlayerWidget代码如下

import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';

//  视频播放测试
class VideoPlayerWidget extends StatefulWidget {
  const VideoPlayerWidget({
    Key? key,
    required this.videoUrl,
    required this.isLooping,
    this.autoPlay = true,
    required this.width,
    required this.height,
  }) : super(key: key);

  final String videoUrl;
  final bool isLooping;
  final bool autoPlay;
  final double width;
  final double height;

  
  State<VideoPlayerWidget> createState() => _VideoPlayerWidgetState();
}

class _VideoPlayerWidgetState extends State<VideoPlayerWidget> {
  VideoPlayerController? _controller;

  
  void initState() {
    super.initState();
    waitVideoPlay();
  }

  Future<void> waitVideoPlay() async {
    _controller?.dispose();

    _controller = VideoPlayerController.networkUrl(
      Uri.parse(widget.videoUrl),
      videoPlayerOptions: VideoPlayerOptions(
        mixWithOthers: true,
        allowBackgroundPlayback: false,
      ),
    );

    await _controller?.initialize().then((_) {
      // Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
      setState(() {});
    });

    await _controller!.setLooping(true);
    if (widget.autoPlay) {
      await _controller?.play();
    } else {
      await _controller?.pause();
    }
  }

  
  Widget build(BuildContext context) {
    if (_controller != null && _controller!.value.isInitialized) {
      return Container(
        width: widget.width,
        height: widget.height,
        child: AspectRatio(
          aspectRatio: _controller!.value.aspectRatio,
          child: VideoPlayer(_controller!),
        ),
      );
    }

    return Container(
      width: widget.width,
      height: widget.height,
      color: Colors.orange,
    );
  }

  
  void dispose() {
    // TODO: implement dispose
    _controller?.dispose();
    super.dispose();
  }
}

三、video_player播放界面播放多个视频

在使用VideoPlayerWidget播放多个视频,

Widget buildVideoContainer(BuildContext context) {
    Size screenSize = MediaQuery.of(context).size;
    return Container(
      width: screenSize.width,
      height: screenSize.height,
      color: Colors.white,
      child: Wrap(
        spacing: 24.0.r, // 主轴(水平)方向间距
        runSpacing: 12.0.r, // 纵轴(垂直)方向间距
        alignment: WrapAlignment.center, //沿主轴方向居中
        children: buildVideoListWidget(context),
      ),
    );
  }

  List<Widget> buildVideoListWidget(BuildContext context) {
    List<Widget> list = [];
    for (int i = 0; i < 4; i++) {
      String videoUrl = videoList[i];
      VideoPlayerWidget widget = VideoPlayerWidget(
        key: GlobalKey(),
        videoUrl: videoUrl,
        isLooping: true,
        width: 320.r,
        height: 480.r,
        delayDuration: Duration(seconds: i),
      );
      list.add(widget);
    }

    return list;
  }

完整video_page代码如下

class VideoPage extends StatefulWidget {
  const VideoPage({super.key});

  
  State<VideoPage> createState() => _VideoPageState();
}

class _VideoPageState extends State<VideoPage>
    with AutomaticKeepAliveClientMixin {
  List<String> videoList = [];

  
  void initState() {
    // TODO: implement initState
    initVideoList();
    super.initState();
  }

  void initVideoList() {
    videoList.add(
        "https://v-qiniu.laikeshuo.com/1648693943358lkGhcDwFQzw3Ix266OsW7WWkzhY0.mp4");

    videoList.add("https://v-qiniu.laikeshuo.com/833134651693235939767");
    videoList
        .add("https://v-qiniu.laikeshuo.com/fb52e680058440a8b220ff7d2d555632");
    videoList
        .add("https://v-qiniu.laikeshuo.com/f6967489119040319a5fdda8be3e5662");
    videoList
        .add("https://v-qiniu.laikeshuo.com/7364b2eb14d54234b205d77147106b7f");
    videoList
        .add("https://v-qiniu.laikeshuo.com/ceee6bedf4814fbcaf4178ea5fb84fc0");
    videoList
        .add("https://v-qiniu.laikeshuo.com/3f7a60531042461eb10bf29f0c31ec6b");
    videoList
        .add("https://v-qiniu.laikeshuo.com/515211835007418da0e6b26425de907c");
    videoList
        .add("https://v-qiniu.laikeshuo.com/0bd0eaf2d30e4a66a4d7a5eb9970ed2a");
    videoList
        .add("https://v-qiniu.laikeshuo.com/35b2548bcf5140bc93425dcd69054294");
    videoList
        .add("https://v-qiniu.laikeshuo.com/3f7a60531042461eb10bf29f0c31ec6b");

    // videoList
    //     .add("https://dphoto.qiniu.laikeshuo.com/bc7a2df5143a4d3a84c8a8407b22e933.mp4");
    // videoList
    //     .add("https://dalat-qiniu.laikeshuo.com/31c5040167ec43168d7ec80c9bf33104.mp4");
  }

  
  void dispose() {
    // TODO: implement dispose
    super.dispose();
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      body: ProviderWidget<VideoModel>(
        model: VideoModel(),
        onModelReady: (model) => model.initData(),
        builder: (context, model, child) {
          if (model.isBusy) {
            return Container();
          } else if (model.isError) {
            return Container();
          } else if (model.isEmpty) {
            return Container();
          }

          return buildVideoContainer(context);
        },
      ),
    );
  }

  Widget buildVideoContainer(BuildContext context) {
    Size screenSize = MediaQuery.of(context).size;
    return Container(
      width: screenSize.width,
      height: screenSize.height,
      color: Colors.white,
      child: Wrap(
        spacing: 24.0.r, // 主轴(水平)方向间距
        runSpacing: 12.0.r, // 纵轴(垂直)方向间距
        alignment: WrapAlignment.center, //沿主轴方向居中
        children: buildVideoListWidget(context),
      ),
    );
  }

  List<Widget> buildVideoListWidget(BuildContext context) {
    List<Widget> list = [];
    for (int i = 0; i < 4; i++) {
      String videoUrl = videoList[i];
      VideoPlayerWidget widget = VideoPlayerWidget(
        key: GlobalKey(),
        videoUrl: videoUrl,
        isLooping: true,
        width: 320.r,
        height: 480.r,
        delayDuration: Duration(seconds: i),
      );
      list.add(widget);
    }

    return list;
  }

  
  // TODO: implement wantKeepAlive
  bool get wantKeepAlive => true;
}

经过测试,发现播放多个视频,播放三个正常,多于三个时候,会报告如下错误。(我使用的是低配置的Android主板,设备性能差)

[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(VideoError, Video player had error x0.q: MediaCodecVideoRenderer error, index=0, format=Format(1, null, null, video/avc, avc1.64001E, -1, null, [1080, 1920, 30.0], [-1, -1]), format_supported=YES, null, null)

三、小结

flutter开发实战-video_player播放多个视频MediaCodecVideoRenderer error问题。

https://blog.csdn.net/gloryFlow/article/details/132676760

学习记录,每天不停进步。

你可能感兴趣的:(移动开发,flutter开发实战,flutter,flutter,音视频,video_player,视频播放)