gpt4 book ai didi

c# - 使用 NAudio 在 C# 中播放 ohLibSpotify pcm 数据流

转载 作者:行者123 更新时间:2023-11-30 14:11:06 30 4
gpt4 key购买 nike

我正在尝试播放从 ohLibSpotify c# 库 ( https://github.com/openhome/ohLibSpotify ) 传送的原始 pcm 数据。

我在以下回调中获取数据:

public void MusicDeliveryCallback(SpotifySession session, AudioFormat format, IntPtr frames, int num_frames)
{
//EXAMPLE DATA
//format.channels = 2, format.samplerate = 44100, format.sample_type = Int16NativeEndian
//frames = ?
//num_frames = 2048
}

现在我想用 NAudio ( http://naudio.codeplex.com/ ) 直接播放接收到的数据。使用以下代码片段,我可以从磁盘播放 mp3 文件。是否可以直接将从spotify接收到的数据传递给NAudio并实时播放?

using (var ms = File.OpenRead("test.pcm"))
using (var rdr = new Mp3FileReader(ms))
using (var wavStream = WaveFormatConversionStream.CreatePcmStream(rdr))
using (var baStream = new BlockAlignReductionStream(wavStream))
using (var waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
{
waveOut.Init(baStream);
waveOut.Play();
while (waveOut.PlaybackState == PlaybackState.Playing)
{
Thread.Sleep(100);
}
}

编辑:我更新了我的代码。该程序不会引发任何错误,但我也听不到音乐。我的代码有什么问题吗?

这是音乐传送回调:

public void MusicDeliveryCallback(SpotifySession session, AudioFormat format, IntPtr frames, int num_frames)
{
//format.channels = 2, format.samplerate = 44100, format.sample_type = Int16NativeEndian
//frames = ?
//num_frames = 2048

byte[] frames_copy = new byte[num_frames];
Marshal.Copy(frames, frames_copy, 0, num_frames);

bufferedWaveProvider = new BufferedWaveProvider(new WaveFormat(format.sample_rate, format.channels));
bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(40);
bufferedWaveProvider.AddSamples(frames_copy, 0, num_frames);
bufferedWaveProvider.Read(frames_copy, 0, num_frames);

if (_waveOutDeviceInitialized == false)
{
IWavePlayer waveOutDevice = new WaveOut();
waveOutDevice.Init(bufferedWaveProvider);
waveOutDevice.Play();
_waveOutDeviceInitialized = true;
}
}

这些是 SessionListener 中被覆盖的回调:

public override int MusicDelivery(SpotifySession session, AudioFormat format, IntPtr frames, int num_frames)
{
_sessionManager.MusicDeliveryCallback(session, format, frames, num_frames);
return base.MusicDelivery(session, format, frames, num_frames);
}

public override void GetAudioBufferStats(SpotifySession session, out AudioBufferStats stats)
{
stats.samples = 2048 / 2; //???
stats.stutter = 0; //???
}

最佳答案

我认为你可以这样做:

  1. 创建一个 BufferedWaveProvider。
  2. 将其传递给 waveOut.Init。
  3. 在您的 MusicDeliveryCallback 中,使用 Marshal.Copy 将 native 缓冲区复制到托管字节数组中。
  4. 将此托管字节数组传递给 BufferedWaveProvider 上的 AddSamples。
  5. 在您的 GetAudioBufferStats 回调中,将 bufferedWaveProvider.BufferedBytes/2 用于“samples”并将“stutters”保留为 0。

认为这会奏效。它涉及一些不必要的复制并且不能准确地跟踪口吃,但这是一个很好的起点。我认为实现 IWaveProvider 并自行管理缓冲可能是更好(更高效和可靠)的解决方案。

我编写了 ohLibSpotify 包装库,但我不再为同一家公司工作,所以我不再参与其开发。您也许可以从这个论坛上的某人那里获得更多帮助:http://forum.openhome.org/forumdisplay.php?fid=6就音乐传输而言,ohLibSpotify 旨在尽可能减少开销。它根本不复制音乐数据,它只是将 libspotify 库本身提供的相同 native 指针传递给您,以便您可以自己将其复制到最终目的地并避免不必要的层复制。不过,对于简单的使用来说,它确实有点笨拙。

祝你好运!

关于c# - 使用 NAudio 在 C# 中播放 ohLibSpotify pcm 数据流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21307520/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com