You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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');
  }
}

额外检查项

  1. 确认pubspec.yaml中已正确声明音频资源:
flutter:
  assets:
    - assets/images/splashscreen.mp4
    - assets/audio/splashsound.mp3
  1. 确保音频文件路径与代码中一致,文件格式支持当前平台(MP3格式通常全平台兼容)

内容的提问来源于stack exchange,提问作者Omega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:02:33