如何使用just_audio ^0.9.24在Flutter中切换流媒体歌曲音质?
用just_audio实现流媒体音质切换(Flutter)
核心思路
每个音质等级对应独立的流媒体URL,切换时记录当前播放进度,重新加载对应音质的音频源后跳转回原进度,实现无缝切换。
实现步骤与代码示例
1. 定义音质配置与状态变量
在State类中初始化AudioPlayer实例,同时维护音质选项、对应URL映射及当前选中状态:
import 'package:flutter/material.dart'; import 'package:just_audio/just_audio.dart'; class AudioQualityPage extends StatefulWidget { const AudioQualityPage({Key? key}) : super(key: key); @override State<AudioQualityPage> createState() => _AudioQualityPageState(); } class _AudioQualityPageState extends State<AudioQualityPage> { final _audioPlayer = AudioPlayer(); // 映射音质等级与对应流媒体地址 final Map<String, String> _qualityMap = { "96 Kbps": "https://your-domain.com/song_96kbps.mp3", "160 Kbps": "https://your-domain.com/song_160kbps.mp3", "320 Kbps": "https://your-domain.com/song_320kbps.mp3", }; String _currentQuality = "160 Kbps"; // 默认选中音质 @override void dispose() { _audioPlayer.dispose(); super.dispose(); } }
2. 实现音质切换逻辑
编写切换方法,核心是记录当前进度、加载新音质源、恢复播放状态:
Future<void> _switchToQuality(String targetQuality) async { if (targetQuality == _currentQuality) return; // 记录当前播放进度 final currentPos = await _audioPlayer.position; // 暂停当前播放 await _audioPlayer.pause(); try { // 加载目标音质的音频源 await _audioPlayer.setAudioSource( AudioSource.uri(Uri.parse(_qualityMap[targetQuality]!)), ); // 跳转到之前的播放进度 if (currentPos != Duration.zero) { await _audioPlayer.seek(currentPos); } // 如果之前处于播放状态,自动恢复播放 if (_audioPlayer.playing) { await _audioPlayer.play(); } // 更新当前选中音质 setState(() { _currentQuality = targetQuality; }); } catch (e) { debugPrint("音质切换失败: $e"); } }
3. 构建交互UI
添加下拉菜单或按钮组触发切换,搭配基础播放控制:
@override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("流媒体音质切换")), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // 音质选择下拉菜单 DropdownButton<String>( value: _currentQuality, items: _qualityMap.keys.map((quality) { return DropdownMenuItem( value: quality, child: Text(quality), ); }).toList(), onChanged: (value) { if (value != null) _switchToQuality(value); }, ), const SizedBox(height: 30), // 播放控制按钮 Row( mainAxisAlignment: MainAxisAlignment.center, children: [ IconButton( icon: const Icon(Icons.play_arrow), onPressed: () => _audioPlayer.play(), iconSize: 40, ), IconButton( icon: const Icon(Icons.pause), onPressed: () => _audioPlayer.pause(), iconSize: 40, ), ], ), ], ), ), ); }
关键注意事项
- 确保各音质对应的流媒体URL有效,且服务器支持断点续传(主流流媒体服务均支持),避免切换后重新从头加载。
- 切换过程中可添加加载提示(如
CircularProgressIndicator),优化用户感知。 - 若使用HLS/Dash格式流媒体,只需将
AudioSource.uri替换为HlsAudioSource/DashAudioSource,切换逻辑保持一致。
内容的提问来源于stack exchange,提问作者Sriram M
相关产品推荐
相关产品推荐

