Flutter启动页音频无法播放,报PlatformException(WebAudioError)求助
启动页音频无法播放问题排查与修复
问题描述
开发Flutter移动端项目时,启动页的开场短视频可正常播放,但音频无法播放,终端报错如下:
Error playing audio: PlatformException(WebAudioError, Player has not yet been created or has already been disposed., null, null)
原实现代码
import 'package:flutter/material.dart'; import 'package:abel/screens/home_screen.dart'; import 'package:flutter/services.dart'; import 'package:video_player/video_player.dart'; import 'package:audioplayers/audioplayers.dart'; class SplashScreen extends StatefulWidget { const SplashScreen({Key? key}) : super(key: key); @override _SplashScreenState createState() => _SplashScreenState(); } class _SplashScreenState extends State<SplashScreen> { late VideoPlayerController _videoController; late AudioPlayer _audioPlayer; @override void initState() { super.initState(); // Initialize the video player _videoController = VideoPlayerController.asset('assets/images/splashscreen.mp4') ..initialize().then((_) { setState(() {}); _videoController.play(); }); // Initialize the audio player _audioPlayer = AudioPlayer(); _playAudio(); // Navigate to HomeScreen after a delay Future.delayed(const Duration(milliseconds: 5000), () { Navigator.pushReplacement( context, MaterialPageRoute(builder: (context) => const HomeScreen()), ); }); // System UI settings SystemChrome.setEnabledSystemUIMode(SystemUiMode.manual, overlays: [ SystemUiOverlay.bottom, ]); SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle( statusBarColor: Colors.transparent, statusBarIconBrightness: Brightness.light, )); // Lock orientation to landscape SystemChrome.setPreferredOrientations([ DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight, ]); } Future<void> _playAudio() async { try { await _audioPlayer.play(AssetSource('assets/audio/splashsound.mp3')); } catch (error) { print('Error playing audio: $error'); } } @override void dispose() { _videoController.dispose(); _audioPlayer.dispose(); // Reset orientation SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, DeviceOrientation.portraitDown, ]); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( extendBody: true, extendBodyBehindAppBar: true, appBar: PreferredSize( preferredSize: const Size.fromHeight(0), child: AppBar( backgroundColor: Colors.transparent, elevation: 0, ), ), backgroundColor: const Color.fromRGBO(255, 255, 255, 1), body: LayoutBuilder( builder: (context, constraints) { return Stack( children: [ FractionallySizedBox( widthFactor: 1.0, heightFactor: 1.0, child: AspectRatio( aspectRatio: 16 / 9, child: VideoPlayer(_videoController), ), ), ], ); }, ), ); } }
问题分析
报错提示播放器未创建或已被释放,核心原因是:
- AudioPlayer实例化后立即调用
play,此时播放器可能还未完成资源加载与初始化(尤其web端存在异步初始化延迟) - 音频播放逻辑与页面跳转逻辑并行,若播放器初始化未完成就触发跳转,会导致播放器被提前释放
修复方案
方案1:等待播放器就绪后再播放
通过监听onPlayerReady事件,确保播放器初始化完成后再执行播放操作:
@override void initState() { super.initState(); // 视频初始化逻辑保持不变 _videoController = VideoPlayerController.asset('assets/images/splashscreen.mp4') ..initialize().then((_) { setState(() {}); _videoController.play(); }); // 初始化音频播放器并监听就绪状态 _audioPlayer = AudioPlayer(); // 设置音频资源 _audioPlayer.setSource(AssetSource('assets/audio/splashsound.mp3')); // 播放器就绪后开始播放 _audioPlayer.onPlayerReady.listen((_) { _audioPlayer.resume(); }); // 其他页面跳转、系统设置逻辑保持不变... }
方案2:异步初始化音频播放器
将音频初始化逻辑封装为异步函数,确保资源加载完成后再播放:
@override void initState() { super.initState(); // 视频初始化逻辑保持不变 _videoController = VideoPlayerController.asset('assets/images/splashscreen.mp4') ..initialize().then((_) { setState(() {}); _videoController.play(); }); // 异步初始化并播放音频 _initAndPlayAudio(); // 其他页面跳转、系统设置逻辑保持不变... } Future<void> _initAndPlayAudio() async { _audioPlayer = AudioPlayer(); try { // 先设置资源,确保加载完成 await _audioPlayer.setSource(AssetSource('assets/audio/splashsound.mp3')); // 再执行播放 await _audioPlayer.play(); } catch (error) { print('Error playing audio: $error'); } }
额外检查项
- 确认
pubspec.yaml中已正确声明音频资源:
flutter: assets: - assets/images/splashscreen.mp4 - assets/audio/splashsound.mp3
- 确保音频文件路径与代码中一致,文件格式支持当前平台(MP3格式通常全平台兼容)
内容的提问来源于stack exchange,提问作者Omega
相关产品推荐
相关产品推荐

