Flutter audioplayers 1.1.0播放位置异常重置问题求助
解决audioplayers 1.1.0网络音频播放时位置回调重置为0的问题
问题现象
使用audioplayers: 1.1.0播放网络音频时,播放功能正常,但player.onPositionChanged回调会在特定时长后突然返回0,导致进度滑块同步重启。日志显示位置值在正常递增后突然跳回0,再继续递增:
0:00:00.000000 0:00:00.002000 ... 0:00:04.882000 0:00:00.236000 // 此处突然重置为0 0:00:00.438000 ...
解决方案
方案1:升级audioplayers到最新稳定版
这个问题是audioplayers旧版本(1.1.0)的已知bug,后续版本已经修复了网络音频的位置计算逻辑。在pubspec.yaml中更新依赖:
dependencies: audioplayers: ^latest_version # 替换为当前最新稳定版,如4.0.0+
方案2:临时过滤异常位置值(仅应急使用)
如果暂时无法升级,可以在回调中手动过滤掉不合理的位置值,避免滑块重置。修改onPositionChanged的监听逻辑:
player.onPositionChanged.listen((newPosition) { // 过滤掉比当前记录位置小1秒以上的异常值(排除播放初始状态) if (newPosition.inSeconds >= position.inSeconds - 1 || position.inSeconds == 0) { setState(() { position = newPosition; }); } });
通过判断新位置与当前记录位置的差值,排除异常的重置值,避免UI错误更新。
修复后完整代码示例
以下是适配新版依赖(或加入过滤逻辑)后的完整代码:
import 'package:flutter/material.dart'; import 'package:audioplayers/audioplayers.dart'; import 'dart:async'; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Audio Player'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { final player = AudioPlayer(); bool isPlaying = false; Duration duration = Duration.zero; Duration position = Duration.zero; String formatTime(int seconds) { return '${(Duration(seconds: seconds))}'.split('.')[0].padLeft(8, '0'); } @override void initState() { super.initState(); player.onPlayerStateChanged.listen((state) { setState(() { isPlaying = state == PlayerState.playing; }); }); player.onDurationChanged.listen((newDuration) { setState(() { duration = newDuration; }); }); // 加入异常位置过滤逻辑(未升级依赖时使用) player.onPositionChanged.listen((newPosition) { if (newPosition.inSeconds >= position.inSeconds - 1 || position.inSeconds == 0) { setState(() { position = newPosition; }); } }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Slider( min: 0, max: duration.inSeconds.toDouble(), value: position.inSeconds.toDouble(), onChanged: (value) { final seekPosition = Duration(seconds: value.toInt()); player.seek(seekPosition); if (!isPlaying) { player.resume(); } }, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ CircleAvatar( radius: 25, child: IconButton( icon: Icon( isPlaying ? Icons.pause : Icons.play_arrow, ), onPressed: () { if (isPlaying) { player.pause(); } else { player.play(UrlSource("https://www.kozco.com/tech/LRMonoPhase4.mp3")); } }, ), ), const SizedBox(width: 20), CircleAvatar( radius: 25, child: IconButton( icon: const Icon(Icons.stop), onPressed: () { player.stop(); setState(() { position = Duration.zero; isPlaying = false; }); }, ), ), ], ), Container( padding: const EdgeInsets.all(20), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(formatTime(position.inSeconds)), Text(formatTime((duration - position).inSeconds)), ], ), ), ], ), ), ); } }
注:升级到新版依赖后,player.play需使用UrlSource包装音频地址,旧版本可保持原写法。
内容的提问来源于stack exchange,提问作者Anandh Krishnan
相关产品推荐
相关产品推荐

