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

2023-12-23

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

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

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/ 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);
    }
}

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

这是音乐传送回调:

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 将本机缓冲区复制到托管字节数组中。
  4. 将此托管字节数组传递给 BufferedWaveProvider 上的 AddSamples。
  5. 在 GetAudioBufferStats 回调中,使用 bufferedWaveProvider.BufferedBytes / 2 作为“样本”,并将“stutters”保留为 0。

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

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

祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 NAudio 在 C# 中播放 ohLibSpotify pcm 数据流 的相关文章

随机推荐

  • 以用户的区域设置格式和时间偏移显示日期/时间

    我希望服务器始终在 HTML 中提供 UTC 日期 并让客户端站点上的 JavaScript 将其转换为用户的本地时区 如果我可以以用户的区域设置日期格式输出 那就太好了 似乎从 UTC 日期开始最简单的方法是创建一个新的Date对象并使用
  • 在 Woocommerce 3 中添加新产品类型

    在 Woocommerce 中 我创建了自定义产品类型live stream 但是 当我在此自定义类型中创建新产品并发布它时 该产品仍然是 简单产品 并且没有获得live stream为其设置自定义类型 我做错了什么 如何使定制产品类型发挥
  • Django 中的 OneToOne 和子类化模型有什么区别

    例如 class Subdomain Site fields here and class Subdomain models Model site models OneToOne Site fields here 型号带有OneToOne拥
  • 通过在 Maven 中运行项目的 java 类来生成源

    我正在将一个较大的 Ant 构建转换为 Maven 作为 Ant 构建的一部分 我们有几个步骤通过调用项目的类之一来创建 Java 类 简化为 javac SomeGenerator java java SomeGenerator gene
  • 硒和 iframe

    我有一个 iframe 当我单击页面上的选项卡时会加载该 iframe 当我使用 Firebug 查看 IE8 上的 iframe 时 我看到的是 iframe id tabContextFrame class contextFrame c
  • Docker如何传递相对路径作为参数

    我想运行这个命令 docker run docker mup deploy config deploy mup js where docker mup是图像的名称 并且deploy config deploy mup js是参数 我的问题
  • 使用 Active Directory 或成员数据库进行 MVC 4 身份验证

    我正在构建一个可以通过两种方式访问 的网络应用程序 与我在同一组织工作的每个人都可以使用我们的活动目录来访问该应用程序 来自外部的每个人都应该通过单独的会员数据库加入该应用程序 每个人都应该在会员数据库中拥有一个包含其角色的帐户 因此广告连
  • 登录自定义路由被身份验证拒绝

    Router scope club slug function routes routes gt connect login controller gt Users action gt login 所以当我尝试访问时http example
  • 为什么我无法正确打印第 47 个斐波那契数?

    我使用的是 64 位操作系统 因此我也无法正确打印第 46 个斐波那契数 该数小于 40 亿 include
  • 什么是反向路由?

    确实 它到处都被提及 但甚至没有维基百科页面准确命名 这只是 URL 重定向的一个奇特名称吗 它还有其他名称或定义吗 反向路由是生成指向路由的 URL 的过程 给定路由的符号引用 可以是路由 视图 控制器的名称或对控制器的引用 具体取决于框
  • 如何在Tcl中安装软件包?

    我正在尝试安装critlib在我的机器上 http equi4 com critlib http equi4 com critlib 这样我就可以在 Tcl 中动态创建 zip 文件 问题是我不知道如何安装 Tcl 软件包 您是否有放置文件
  • 在 IIS7 静态内容集成模式中使用角色进行 ASP.NET 身份验证

    我正在试验IIS7中静态内容的集成身份验证模式 我按照本文中的说明进行操作 https web archive org web 20210612113955 https aspnet 4guysfromrolla com articles
  • BeautifulSoup 选择具有特定类的某些元素中的所有 href

    我正在尝试从中删除图像网站 我尝试使用 Scrapy 使用 Docker 和 scrapy slenium Scrapy 似乎不适用于 windows10 home 所以我现在尝试使用 Selenium Beautifulsoup 我正在将
  • 模板类中的 C++ 非模板方法

    是否可以在 cpp 文件的模板类 结构 中编写非模板方法的实现 我读到模板方法应该写在 h上 但我的方法不是模板方法 尽管它属于模板类 这是我的 h 中的代码 include
  • BottomNavigationView 在片段事务上滞后

    问题 我正在使用BottomNavigationView来自我的一项活动的 Android 设计支持库 以及每个导航项的片段 每次我在栏上选择一个项目时 我都会执行一个片段事务 如下面的代码片段 为了简洁起见 删除了代码的某些部分 priv
  • Callkit - 如果从后台开始通话则没有音频

    从 iOS 13 3 1 开始出现这种情况 在我的应用程序中 我使用 Callkit WebRTC 建立 VOIP 连接 我总是能够毫无问题地建立连接 但是 从 13 3 1 开始 如果应用程序不在前台 我将无法启动 Callkit 调用
  • 来自特定网卡的 UDP 多播

    我正在寻找一些网络专家来帮助我解决问题 我有很多计算机运行我的软件 该软件使用 UDP 多播 如果计算机仅连接到一个网络 网络 A 则此方法可以正常工作 我的计算机 也运行上述软件 将在端口 XXXX 上侦听多播 这台计算机有两个网卡 当我
  • 如何缓存 Spring Data JPA 投影

    我正在使用 Spring Data JPA 存储库运行 Spring Boot 1 5 1 我已经在我的用户存储库中添加了一个方法 该方法使用 JPA 投影 UserProfile 效果很好 我现在希望在我的服务层中缓存该方法的结果 该层应
  • 从 Apache Spark 中的架构获取数据类型列表

    我在 Spark Python 中有以下代码 用于从 DataFrame 的架构中获取名称列表 该代码工作正常 但如何获取数据类型列表 columnNames df schema names 例如 类似 columnTypes df sch
  • 使用 NAudio 在 C# 中播放 ohLibSpotify pcm 数据流

    我正在尝试播放从 ohLibSpotify c 库提供的原始 pcm 数据 https github com openhome ohLibSpotify https github com openhome ohLibSpotify 我在以下