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

为何无法用单个源播放多首歌曲?Rodio播放问题求解

问题原因与修复方案

问题原因

直接拼接两个MP3文件的二进制数据,无法被rodio的Decoder正确识别为两首独立歌曲。MP3是带有特定头部信息的格式,每个文件的头部仅描述自身音频数据,拼接后的数据流没有统一标识告知解码器“此处为下一首歌的起始”,解码器解析完第一首歌的所有帧后,会判定流已结束,随即停止解码。

修复方案

针对本地文件示例的修复

无需拼接数据,分别解码每个文件并依次添加到sink中即可实现连续播放:

use std::{fs, io::Cursor};
fn main() {
    let (_stream, handle) = rodio::OutputStream::try_default().unwrap();
    let sink = rodio::Sink::try_new(&handle).unwrap();

    // 分别解码每首歌并添加到播放队列
    let song1 = rodio::Decoder::new(Cursor::new(fs::read("guiro-sweep.mp3").unwrap())).unwrap();
    sink.append(song1);

    let song2 = rodio::Decoder::new(Cursor::new(fs::read("on_the_moon.mp3").unwrap())).unwrap();
    sink.append(song2);

    sink.sleep_until_end();
}

sink会自动按添加顺序播放音频源,第一首播放完毕后无缝切换到第二首。

针对客户端-服务器分块传输场景的修复

服务器需先发送歌曲数据的长度标识,客户端接收时先读取长度,再获取对应长度的完整歌曲数据,单独解码后添加到sink:

use std::{io::{self, Read}, net::TcpStream};
use rodio::{Decoder, OutputStream, Sink};
use std::io::Cursor;

fn main() {
    let (_stream, handle) = OutputStream::try_default().unwrap();
    let sink = Sink::try_new(&handle).unwrap();

    let mut stream = TcpStream::connect("server_addr:port").unwrap();
    let mut len_buffer = [0; 8]; // 用8字节存储歌曲数据长度(对应u64类型)

    loop {
        // 先读取歌曲数据长度
        match stream.read_exact(&mut len_buffer) {
            Ok(_) => {
                let data_len = u64::from_be_bytes(len_buffer) as usize;
                let mut song_data = vec![0; data_len];
                // 读取完整的单首歌数据
                stream.read_exact(&mut song_data).unwrap();
                // 解码并添加到播放队列
                let decoder = Decoder::new(Cursor::new(song_data)).unwrap();
                sink.append(decoder);
            }
            Err(e) => {
                eprintln!("接收失败: {}", e);
                break;
            }
        }
    }

    sink.sleep_until_end();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 16:13:18