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

Flutter如何播放无MP3后缀HTTP URL的直播音频流(如网络电台)

Hey there! I’ve worked on exactly this kind of live audio streaming scenario in Flutter before, so let me break down a reliable implementation for you. The key here is using a package that handles live streams natively, even when the URL doesn’t have a .mp3 or other audio file extension.

Flutter Live Audio Stream Implementation (No MP3 Suffix URL)

1. Pick the Right Audio Package

I’d recommend just_audio for this task—it’s built to handle both on-demand audio and live streams seamlessly, and it doesn’t care if your URL lacks a file extension. It also gives you great control over playback states, buffering, and error handling. Alternatively, audioplayers works too, but just_audio is more robust for streaming use cases.

2. Add Dependencies

First, update your pubspec.yaml to include the package:

dependencies:
  just_audio: ^0.9.34 # Use the latest version available
  rxdart: ^0.27.7 # Optional, but helpful for stream-based state listening

Run flutter pub get to install the dependencies.

3. Full Playback Widget Code

Here’s a complete, reusable widget that handles loading the live stream, play/pause controls, and error handling:

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

class LiveRadioPlayer extends StatefulWidget {
  final String streamUrl;
  const LiveRadioPlayer({super.key, required this.streamUrl});

  @override
  State<LiveRadioPlayer> createState() => _LiveRadioPlayerState();
}

class _LiveRadioPlayerState extends State<LiveRadioPlayer> {
  late final AudioPlayer _audioPlayer;
  bool _isPlaying = false;
  String? _errorMsg;

  @override
  void initState() {
    super.initState();
    _audioPlayer = AudioPlayer();
    _setupStream();
  }

  void _setupStream() async {
    try {
      // Load the live stream URL directly—no file extension required
      await _audioPlayer.setUrl(widget.streamUrl);

      // Listen for playback state changes to update UI
      _audioPlayer.playerStateStream.listen((playerState) {
        setState(() {
          _isPlaying = playerState.playing;
        });
      });

      // Catch any playback errors
      _audioPlayer.playbackEventStream.listen((event) {
        if (event.error != null) {
          setState(() {
            _errorMsg = event.error?.message;
          });
        }
      });
    } catch (e) {
      setState(() {
        _errorMsg = "Failed to load stream: $e";
      });
    }
  }

  Future<void> _togglePlayback() async {
    if (_isPlaying) {
      await _audioPlayer.pause();
    } else {
      await _audioPlayer.play();
    }
  }

  @override
  void dispose() {
    // Always dispose the player to avoid memory leaks
    _audioPlayer.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        // Show error message if something goes wrong
        if (_errorMsg != null)
          Padding(
            padding: const EdgeInsets.only(bottom: 16),
            child: Text(
              _errorMsg!,
              style: const TextStyle(color: Colors.red, fontSize: 14),
              textAlign: TextAlign.center,
            ),
          ),
        // Play/Pause button
        ElevatedButton(
          onPressed: _togglePlayback,
          style: ElevatedButton.styleFrom(
            padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 12),
          ),
          child: Text(_isPlaying ? 'Pause Stream' : 'Play Stream'),
        ),
      ],
    );
  }
}

// To use this widget:
// LiveRadioPlayer(streamUrl: "https://your-live-stream-url.com/stream")

4. Platform-Specific Configurations

Android

Add these permissions to android/app/src/main/AndroidManifest.xml:

<!-- Required for internet access -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Optional: Keep audio playing when app is in background -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

If your stream uses HTTP (not HTTPS), add this to the <application> tag to allow cleartext traffic:

android:usesCleartextTraffic="true"

iOS

Update ios/Runner/Info.plist to enable internet access and optional background playback:

<!-- Allow HTTP/HTTPS access -->
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsArbitraryLoads</key>
  <true/>
</dict>

<!-- Optional: Allow audio playback in background -->
<key>UIBackgroundModes</key>
<array>
  <string>audio</string>
</array>

5. Pro Tips

  • Buffering Feedback: You can listen to _audioPlayer.bufferedPositionStream to show a buffering indicator for users.
  • Codec Compatibility: Most live streams use MP3 or AAC, which just_audio supports out of the box. If you hit compatibility issues, try switching to the audioplayers package.
  • Error Handling: Extend the error logic to handle cases like network drops—you could add a retry button if the stream fails.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:30