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
学習記録、日々改善を続けてください。