解码器init无法在Flutter上与Chewie一起播放视频列表



我正在开发一个Flutter应用程序,以顺序显示从互联网下载的视频。我正在使用Chewie组件来显示视频。

这是加载Chewie Widget的UI逻辑:

class SliderScreen extends StatefulWidget {
static String id = 'SliderScreen';
@override
_SliderScreenState createState() => _SliderScreenState();
}
class _SliderScreenState extends State<SliderScreen> {
SliderViewModel vModel;
@override
void initState() {
super.initState();
}
@override
void dispose() {
if (null != vModel) vModel.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return BaseView<SliderViewModel>(
onModelReady: (model) {
model.downloadController = locator<DownloadController>();
model.downloadController.init(callback: model.onFirstFileDownloaded);
vModel = model;
vModel.getSlots(isFirstCall: true);
},
builder: (context, model, child) => null != model.medias && model.medias.length > 0
? FutureBuilder(
future: model.initializeVideoPlayerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
vModel.chewieController.play();
return AspectRatio(
aspectRatio: 16 / 9,
// Use the VideoPlayer widget to display the video.
child: Center(
child: null != vModel.chewieController ? Chewie(controller: vModel.chewieController) : Center(child: CircularProgressIndicator()),
));
} else {
return SizedBox(
height: 300,
child: Center(child: CircularProgressIndicator()),
);
}
})
: SizedBox());
}
}

viewModel是下载和播放媒体的地方。

class SliderViewModel extends BaseViewModel {
static String id = 'SliderViewModel';
static int kFiveMinutes = 5 * 60;
Slot currentSlot;
Slot nextSlot;
DownloadController downloadController;
Timer nextSlotTimer;
List<TaskInfo> medias = [];
VideoPlayerController videoController;
ChewieController chewieController;
bool _disposed = false;
var _isPlaying = false;
var _isEndPlaying = false;
var _canPlay = true;
String token;
int currentIndex = 0;
Future<void> initializeVideoPlayerFuture;
void getSlots({bool isFirstCall = false}) async {
//get videos to show.....
}
void addToDownload({Slot slot, bool resetMedias = false}) async {
if (resetMedias) {
medias.clear();
downloadController.clearTasks();
await downloadController.cancelDownload();
}
await downloadController.addMediasToDownload(ads: slot.ads, slotStart: slot.slot.sta);
downloadController.startDownloadMedias();
}
Future<void> _startPlay() async {
print("play ---------> ${medias[currentIndex].path}");
initializeVideoPlayerFuture = null;
Future.delayed(const Duration(milliseconds: 200), () {
_clearPrevious().then((_) {
_initializePlay();
});
});
}
Future<void> _initializePlay() async {
print('*****************      preparing ${medias[currentIndex].path}');
videoController = VideoPlayerController.file(File(medias[currentIndex].path));
videoController.addListener(_controllerListener);
chewieController = ChewieController(
videoPlayerController: videoController,
aspectRatio: 16 / 9,
fullScreenByDefault: true,
showControls: true,
autoPlay: true,
// Prepare the video to be played and display the first frame
autoInitialize: true,
looping: false,
// Errors can occur for example when trying to play a video
// from a non-existent URL
errorBuilder: (context, errorMessage) {
return Center(
child: Text(
errorMessage,
style: TextStyle(color: Colors.white),
),
);
},
);
//chewieController.addListener(_controllerListener);
initializeVideoPlayerFuture = videoController.initialize();
setState(ViewState.Idle);
}
Future<bool> _clearPrevious() async {
await videoController?.pause();
videoController?.removeListener(_controllerListener);
await videoController?.dispose();
return true;
}
void onFirstFileDownloaded(TaskInfo task) {
if (null != task) {
print('current slot: ${currentSlot.slot.sta} - task slot: ${task.slotStart} - ${task.name} FINISH!!!');
if (currentSlot.slot.sta == task.slotStart) {
medias.add(task);
if (!_isPlaying) {
if (_canPlay) {
loadNextMedia();
_canPlay = false;
}
}
}
} else
print('all files downloaded!!!');
}
Future<void> _controllerListener() async {
if (videoController == null || _disposed) {
return;
}
if (!videoController.value.initialized) {
return;
}
final position = await videoController.position;
final duration = videoController.value.duration;
final isPlaying = position.inMilliseconds < duration.inMilliseconds;
final isEndPlaying = position.inMilliseconds > 0 && position.inSeconds == duration.inSeconds;
if (_isPlaying != isPlaying || _isEndPlaying != isEndPlaying) {
_isPlaying = isPlaying;
_isEndPlaying = isEndPlaying;
print(" -----> isPlaying=$isPlaying");
if (!_isPlaying) {
//mark media as viewed
print('send viewed ${medias[currentIndex].ad.id}');
apiServices.sendViewed(
token: token,
adId: medias[currentIndex].ad.id.toString(),
userId: await AppSingleton().storage.read(key: kUserId),
slotId: currentSlot.slot.tsi.toString(),
def: medias[currentIndex].ad.def.toString());
final isComplete = medias.length - 1 == currentIndex;
if (isComplete) {
print("played all!!");
if (currentSlot.slot.loop == 0 || currentSlot.slot.loop == 1 && medias[currentIndex].ad.def == 0) medias.removeAt(currentIndex);
currentIndex = 0;
if (currentSlot.slot.loop == 1) loadNextMedia();
setState(ViewState.Idle);
} else {
_canPlay = true;
print('finish play ${medias[currentIndex].name} - slot: ${medias[currentIndex].slotStart}');
if (currentSlot.slot.loop == 0 || (currentSlot.slot.loop == 1 && medias[currentIndex].ad.def == 0))
medias.removeAt(currentIndex);
else
currentIndex++;
if (medias.length > currentIndex)
loadNextMedia();
else
setState(ViewState.Idle);
}
}
}
}
void loadNextMedia() {
_startPlay();
}
@override
void dispose() {
_disposed = true;
videoController.dispose();
chewieController.dispose();
initializeVideoPlayerFuture = null;
super.dispose();
}
}

一开始运行良好,但在显示一些视频后,应用程序会抛出异常。

Playback error.
E/ExoPlayerImplInternal(12983): com.google.android.exoplayer2.ExoPlaybackException: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.qcom.video.decoder.avc, Format(1, null, null, video/avc, null, -1, null, [1280, 720, -1.0], [-1, -1])
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:479)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.reinitializeCodec(MediaCodecRenderer.java:1261)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.onInputFormatChanged(MediaCodecRenderer.java:1111)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.video.MediaCodecVideoRenderer.onInputFormatChanged(MediaCodecVideoRenderer.java:552)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:647)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:529)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:300)
E/ExoPlayerImplInternal(12983):     at android.os.Handler.dispatchMessage(Handler.java:102)
E/ExoPlayerImplInternal(12983):     at android.os.Looper.loop(Looper.java:193)
E/ExoPlayerImplInternal(12983):     at android.os.HandlerThread.run(HandlerThread.java:65)
E/ExoPlayerImplInternal(12983): Caused by: com.google.android.exoplayer2.mediacodec.MediaCodecRenderer$DecoderInitializationException: Decoder init failed: OMX.qcom.video.decoder.avc, Format(1, null, null, video/avc, null, -1, null, [1280, 720, -1.0], [-1, -1])
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodecWithFallback(MediaCodecRenderer.java:753)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.maybeInitCodec(MediaCodecRenderer.java:474)
E/ExoPlayerImplInternal(12983):     ... 9 more
E/ExoPlayerImplInternal(12983): Caused by: android.media.MediaCodec$CodecException: Failed to initialize OMX.qcom.video.decoder.avc, error 0xfffffff4
E/ExoPlayerImplInternal(12983):     at android.media.MediaCodec.native_setup(Native Method)
E/ExoPlayerImplInternal(12983):     at android.media.MediaCodec.<init>(MediaCodec.java:1811)
E/ExoPlayerImplInternal(12983):     at android.media.MediaCodec.createByCodecName(MediaCodec.java:1792)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodec(MediaCodecRenderer.java:802)
E/ExoPlayerImplInternal(12983):     at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.initCodecWithFallback(MediaCodecRenderer.java:745)
E/ExoPlayerImplInternal(12983):     ... 10 more

视频循环播放。这意味着所有视频都至少成功播放一次。在iOS尚未测试,因为无法在模拟器中再现视频。

我能够修复我的错误。这有点奇怪,但有道理。在我的应用程序中,我正在开发一个像TikTok这样的视频应用程序,许多视频正在播放和加载。目前,我的测试应用程序有33个视频,它开始显示这个错误。我只是把视频限制在10,一切都很好。由于我的应用程序主要是视频,一旦我从firestore获得视频,我就初始化了视频播放器,但没有播放。根据用户滚动,我播放视频并暂停其他视频。我认为这个应用程序的负载可能太大了。但我查看了性能图,内存使用量约为100MB。

最新更新