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

Flutter web端video_player组件销毁后仍播放音频的问题如何解决?

Flutter Web端video_player销毁后音频残留问题修复方案

问题根因

  • ChewieController在build方法内重复创建,旧实例未被销毁,残留Web端底层HTML5 Video元素引用
  • 仅销毁VideoPlayerController,未主动释放ChewieController资源
  • 未判断控制器初始化状态就调用暂停、销毁方法,Web端异步初始化未完成时操作不生效
  • 原代码存在参数引用错误,Chewie初始化时的autoPlay未正确取widget.autoPlay值

修复后代码

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:video_player/video_player.dart';
import 'package:chewie/chewie.dart';

class VideoAsset extends StatefulWidget {
  final Uri url;
  final bool autoPlay;

  const VideoAsset({Key? key, required this.url, this.autoPlay = false}) : super(key: key);

  @override
  _VideoAssetState createState() => _VideoAssetState();
}

class _VideoAssetState extends State<VideoAsset> {
  late VideoPlayerController videoPlayerController;
  ChewieController? chewieController;

  @override
  void initState() {
    super.initState();
    videoPlayerController = VideoPlayerController.network(widget.url.toString());
    _initControllers();
  }

  Future<void> _initControllers() async {
    await videoPlayerController.initialize();
    if (mounted) {
      setState(() {
        chewieController = ChewieController(
          videoPlayerController: videoPlayerController,
          autoPlay: widget.autoPlay,
          looping: false,
          allowFullScreen: false,
          aspectRatio: 16 / 9,
          placeholder: Container(),
        );
      });
    }
  }

  @override
  void dispose() {
    // 先销毁Chewie控制器
    if (chewieController != null) {
      chewieController!.pause();
      chewieController!.dispose();
    }
    // 再处理视频控制器
    if (videoPlayerController.value.isInitialized) {
      videoPlayerController.pause();
      // Web端额外适配逻辑
      if (kIsWeb) {
        videoPlayerController.setVolume(0);
        videoPlayerController.seekTo(Duration.zero);
      }
    }
    videoPlayerController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 16 / 9,
      child: chewieController != null 
          ? Chewie(controller: chewieController!)
          : const Center(child: CircularProgressIndicator()),
    );
  }
}

额外优化说明

  • 移除了build方法内的FutureBuilder,避免每次页面重build触发重复初始化逻辑
  • 增加mounted判断,避免异步初始化完成前页面已销毁导致的异常
  • Web端销毁前强制设置音量为0、重置播放进度,彻底阻断残留音频输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 12:39:04