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

Flutter中just_audio插件未播放时仍持续缓冲直播流问题

解决方案

问题根源在于你在initState中调用了audioPlayer.setUrl(url)——这个方法会立即触发直播流的加载与缓冲,哪怕还没执行play()操作。要实现仅点击播放才开始缓冲,只需把设置URL的逻辑移到播放按钮的点击事件中,并处理重复操作的情况。

修改步骤

  1. 移除initState里的audioPlayer.setUrl(url)调用,仅保留AudioPlayer实例初始化。
  2. 新增状态变量记录URL是否已加载,避免重复发起网络请求。
  3. 封装播放逻辑,在点击播放时先检查URL状态,未加载则先设置URL再播放,已加载则直接播放。

修改后的完整代码

import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart';

void main() => runApp(RadioTest());

class RadioTest extends StatefulWidget {
  @override
  _RadioTestState createState() => _RadioTestState();
}

class _RadioTestState extends State<RadioTest> {
  AudioPlayer audioPlayer;
  String url = "http://canada1.reliastream.com:8052/live?type=.mp3";
  bool _isUrlLoaded = false; // 标记URL是否已完成加载

  @override
  void initState() {
    super.initState();
    audioPlayer = AudioPlayer();
    print("Radio Activated");
  }

  @override
  void dispose() {
    audioPlayer.dispose();
    super.dispose();
  }

  Future<void> _playAudio() async {
    if (!_isUrlLoaded) {
      try {
        await audioPlayer.setUrl(url);
        setState(() {
          _isUrlLoaded = true;
        });
      } catch (error) {
        print(error);
        return;
      }
    }
    await audioPlayer.play();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("Radio Test"),
        ),
        body: Container(
          child: Row(
            children: <Widget>[
              Text("Hi"),
              StreamBuilder<FullAudioPlaybackState>(
                stream: audioPlayer.fullPlaybackStateStream,
                builder: (context, snapshot) {
                  final fullState = snapshot.data;
                  final state = fullState?.state;
                  final buffering = fullState?.buffering;
                  return Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      if (state == AudioPlaybackState.connecting ||
                          buffering == true)
                        Container(
                          margin: EdgeInsets.all(8.0),
                          width: 64.0,
                          height: 64.0,
                          child: CircularProgressIndicator(),
                        )
                      else if (state == AudioPlaybackState.playing)
                        IconButton(
                          icon: Icon(Icons.pause),
                          iconSize: 64.0,
                          onPressed: audioPlayer.pause,
                        )
                      else
                        IconButton(
                          icon: Icon(Icons.play_arrow),
                          iconSize: 64.0,
                          onPressed: _playAudio, // 调用自定义播放逻辑
                        ),
                      IconButton(
                        icon: Icon(Icons.stop),
                        iconSize: 64.0,
                        onPressed: state == AudioPlaybackState.stopped ||
                                state == AudioPlaybackState.none
                            ? null
                            : () async {
                                await audioPlayer.stop();
                                // 若希望停止后下次播放重新加载URL,可取消下方注释
                                // setState(() {
                                //   _isUrlLoaded = false;
                                // });
                              },
                      ),
                    ],
                  );
                },
              ),
            ],
          ),
        ),
      ),
    );
  }
}

额外说明

  • _isUrlLoaded变量用于避免重复调用setUrl,减少不必要的网络开销。
  • 若需要点击停止按钮后,下次播放重新加载直播流,只需取消stop回调中设置_isUrlLoaded = false的注释即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 02:54:35