Flutter開発実践 - video_playerで複数の動画を再生する MediaCodecVideoRendererエラー問題

Flutter開発実践 - video_playerで複数の動画を再生する MediaCodecVideoRendererエラー問題

開発プロセス中に、video_player を使用して複数のビデオを再生すると、MediaCodecVideoRenderer エラーが発生します

1. video_player を使用してビデオを再生します

video_player を使用して遅延ビデオを再生します。https:
//blog.csdn.net/gloryFlow/article/details/132124837を確認してください。

ここでは、複数のビデオ MediaCodecVideoRenderer エラーの問題を解決するための記録を示します。

2. app/build.gradle に依存関係を追加します。

app/build.gradle に依存関係を追加します

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

ビデオを再生するためのウィジェットを実装します。再生テスト中、再生できるビデオは 1 つだけです。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();
  }
}

3. 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)] 未処理の例外: PlatformException(VideoError、ビデオ プレーヤーにエラー x0 がありました。q: MediaCodecVideoRenderer エラー、index=0、format=Format(1、null、null、video/avc、 avc1.64001E、-1、null、[1080、1920、30.0]、[-1、-1])、format_supported=YES、null、null)

3. まとめ

Flutter開発実践 - video_playerで複数の動画を再生する MediaCodecVideoRendererエラー問題。

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

学習記録、日々改善を続けてください。

おすすめ

転載: blog.csdn.net/gloryFlow/article/details/132676760