使用 NAudio 转换为 WAV 后使用 SoundPlayer 播放 MP3

2023-11-29

我想使用NET提供的播放从网上下载的MP3文件系统.媒体.SoundPlayer机制。由于它适用于 WAV 格式,因此需要以下支持:NAudio库 - 我需要将 MP3 转换为 WAV。

我想在内存中执行所有操作,因为我需要它快速,但我有问题。下面我展示了按预期工作的代码,但它与文件配合。相反,我需要使其仅使用内存操作来工作。

(1) 有效,但涉及磁盘操作:

public void Speak(Uri mp3FileUri)
{
    using (var client = new WebClient())
    {
        using (var networkStream = client.OpenRead(mp3FileUri))
        {
            if (networkStream != null)
            {
                var temp = Path.GetTempPath();
                var mp3File = Path.Combine(temp, "file.mp3");
                var wavFile = Path.Combine(temp, "file.wav");
                using (var fileStream = File.Create(mp3File))
                {
                    networkStream.CopyTo(fileStream);
                }
                using (var reader = new Mp3FileReader(mp3File))
                {
                    WaveFileWriter.CreateWaveFile(wavFile, reader);
                }                        
                using(var player = new SoundPlayer(wavFile))
                {
                    player.Play();
                }
            }
        }
    }
}

(2) 不起作用 - 没有抛出异常,但没有播放任何内容:

public void Speak(Uri mp3FileUri)
{
    using (var client = new WebClient())
    {
        using (var networkStream = client.OpenRead(mp3FileUri))
        {
            if (networkStream != null)
            {
                var memStream = new MemoryStream();
                networkStream.CopyTo(memStream);
                memStream.Position = 0;
                using (var reader = new Mp3FileReader(memStream))
                {
                    var outStream = new MemoryStream();
                    using (var writer = new WaveFileWriter(outStream, reader.WaveFormat))
                    {
                        var num = 0L;
                        var buffer = new byte[reader.WaveFormat.AverageBytesPerSecond * 4];
                        while (true)
                        {
                            var count = reader.Read(buffer, 0, buffer.Length);
                            if (count != 0)
                            {
                                num += count;
                                if (num <= int.MaxValue)
                                    writer.Write(buffer, 0, count);
                                else
                                    throw new InvalidOperationException("Too large file or endless stream.");
                            }
                            else
                                break;
                        }
                        writer.Flush();
                        outStream.Position = 0;
                        using(var player = new SoundPlayer(outStream))
                        {
                            player.Play(); /* why silence ? */
                        }
                    }                            
                }
            }
        }
    }
}

如何做到这一点以及第二个代码示例有什么问题?


根据 Lee Harrison 的回答,我创建了更好的替代代码。

(3)直接播放WEB上的MP3文件,无需转换为WAV,也无需使用磁盘操作:

public void Speak(Uri mp3FileUri)
{
    using (var client = new WebClient())
    {
        using (var networkStream = client.OpenRead(mp3FileUri))
        {
            if (networkStream != null)
            {
                using (var memStream = new MemoryStream())
                {
                    networkStream.CopyTo(memStream);
                    memStream.Position = 0;                            
                    using (var waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
                    {
                        var waveEvent = new ManualResetEvent(false);
                        waveOut.PlaybackStopped += (sender, e) => waveEvent.Set();
                        waveEvent.Reset();
                        using (var rdr = new Mp3FileReader(memStream))
                        using (var waveStream = WaveFormatConversionStream.CreatePcmStream(rdr))
                        using (var baStream = new BlockAlignReductionStream(waveStream))
                        {
                            waveOut.Init(baStream);
                            waveOut.Play();
                            if (waveOut.PlaybackState != PlaybackState.Stopped)
                            { 
                                waveEvent.WaitOne(); /* block thread for a while because I don't want async play back                                
                                                        (to be analogical as usage of SoundPlayer Play method) */
                            }
                        }
                    }
                }
            }
        }
    }
}

尽管如此(尽管这对我来说非常好),我仍然不知道示例(2)有什么问题。

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

使用 NAudio 转换为 WAV 后使用 SoundPlayer 播放 MP3 的相关文章

随机推荐

  • 将多个 ID 映射到 Active Directory 中的电子邮件地址并将结果输出到单个文件

    我正在尝试找到一种方法 将多个用户的 ID 映射到 Active Directory AD 中的关联电子邮件地址 然后将输出附加到 txt 文件中 最终生成包含电子邮件地址列表的单个文件 通过利用 PowerShell AD 工具的以下命令
  • 如何从 Team Foundation Server 删除测试用例

    如何从 Team Foundation Server 中删除测试用例 我已采取以下步骤 首先 我安装了 Team Foundation Server Power Tools这个网站 其次 我在 VS 命令窗口中输入以下内容 witadmin
  • “SQLSTATE[23000]:违反完整性约束”,具有有效约束

    我正在使用 Symfony 2 和 Doctrine 我有 4 个班级 国家 地区 县和地方 District 有一个 Country 外键 县有一个区外 本地有一个区域的外键 问题是 当插入一个县 使用数据装置 时 我收到错误 SQLST
  • 字典Python中重复键的值列表[重复]

    这个问题在这里已经有答案了 如果这个问题已经在这里探讨过 请提前道歉 我在这里查看了不同的答案 但找不到我需要的东西 我的目标是创建一本这样的字典 a 10 9 10 10 b 10 9 1 0 c 0 5 0 1 and so on 我拥
  • 从 jQuery-UI 选项卡获取目标 URL

    我正在开发一个大量使用 jQuery 选项卡和 Ajax 的项目 将数据加载到选项卡本身很简单 但选项卡中的数据需要通过位于选项卡 div 外部的选择框进行过滤 这就是我的问题开始的地方 假设我的选项卡对 URL tab1 html 进行
  • 使用未弃用的 64 位代码替换 CMNewProfileSearch

    我有现有的代码使用CMNewProfileSearch查找然后迭代系统上的颜色配置文件 获取它们的名称和完整路径 很遗憾 CMNewProfileSearch在 Mac OS X 10 5 中已弃用 并且在编译 64 位应用程序时也不可用
  • 如何在 Python 中使用服务帐户凭据创建 Google 表格?

    我创建Service Account Credentials here并得到 json 密钥service json 然后我尝试 from google oauth2 import service account SCOPES https
  • 最新 Chrome 85 更新后的 CORS 问题

    我是这里的新用户 因此 如果我违反了任何规则 请提前道歉 这是我面临的问题 需要建议 我有一个 Chrome 扩展 它与 Gmail 配合使用 并通过 Rails 应用程序的 Phusion Passenger 服务器使用在 nginx 上
  • 如何在 R 中的字符串中添加缺少的右括号?

    我想为具有左括号但缺少右括号的字符串添加右括号 例如 我想将 狗在公园散步 ABC 修改为 狗在公园散步 ABC 我发现了类似的问题和解决方案 但它是在Python中 如何在Python中的字符串中添加缺少的右括号 我尝试修改R中使用的代码
  • 首页“/”上出现 NotAllowedError

    我尝试设置主页 供用户登录或未登录 但我得到了NotAllowedError 这适用于本地服务器 不过 在真正的公共服务器上似乎不起作用 Does NotAllowedError是指遵守 Google App Engine 标准 不将登录信
  • (单击)如果来自函数,则在数组类型的元素上的 *ngFor 内部断开

    in plnkr我重现了一个奇怪的边缘情况 它可能取决于 pixjs 或 webgl 因为它在使用 pixjs 时发生 请注意如何单击列表中的所有元素 但是一旦开始使用 pixij 只需单击按钮 单击就会停止对数组类型的元素起作用 这odd
  • 我怎样才能减少 if else 语句[关闭]

    Closed 这个问题是基于意见的 目前不接受答案 我编写了一个函数 将 和 and 放在三个链接之间 我怎样才能减少 if else 语句 在javascript中 如果计数不为零 则我得到计数 这意味着链接必须显示 否则应该隐藏 在以下
  • System.out 对象属于 System 类还是 PrintStream 类? [关闭]

    很难说出这里问的是什么 这个问题模棱两可 含糊不清 不完整 过于宽泛或言辞激烈 无法以目前的形式合理回答 如需帮助澄清此问题以便重新打开 访问帮助中心 我是编程新手 刚刚开始学习 Java 我很好奇 System out 对象属于 Syst
  • 错误:JAVA_HOME 未正确定义执行 maven

    我安装了java并设置了路径环境 当我运行时echo JAVA HOME在终端中我得到以下输出 usr lib jvm java 7 oracle jre bin java 我也安装了apache maven并改变了environment文
  • R:按组计算 Pearson 相关性和 R 平方

    我正在尝试扩展问题的答案R 过滤数据并计算相关性 要获得一年中每个月 1 一月 的温度和湿度的相关性 我们必须对每个月执行相同的操作 12 次 cor airquality airquality Month 1 c Temp Humidit
  • Apache Spark Dataframe - 从 CSV 文件的第 n 行加载数据

    我想处理一个巨大的订单 CSV 文件 5GB 在文件开头有一些元数据行 标题列在第 4 行中表示 以 h 开头 后跟另一个元数据行 描述可选性 数据行以 d 开头 m Version v1 0 m Type xx m
  • 使用“子”函数中的局部变量

    考虑以下代码 function child echo var function parent local var 5 child 我已经在我的机器上测试了它 它似乎可以工作 但我无法找到任何明确描述局部变量的这种用法的信息 也就是说 当我在
  • 如何在 Swift 2 中调用 SOAP Web 服务?

    我想调用 Swift 2 的网络服务 但它从来没有工作过 这是我的代码 import UIKit class ViewController UIViewController UITextFieldDelegate NSURLConnecti
  • 如何知道我的电脑是否连接了耳机? HTML5 + JavaScript

    如何知道我的电脑是否连接了耳机 我的目标是使用 HTML5 JavaScript 来实现它 下一页显示了所有音频输出设备 但无法知道活动设备是否是耳机 而在 Firefox 中它不起作用 https webrtc github io sam
  • 使用 NAudio 转换为 WAV 后使用 SoundPlayer 播放 MP3

    我想使用NET提供的播放从网上下载的MP3文件系统 媒体 SoundPlayer机制 由于它适用于 WAV 格式 因此需要以下支持 NAudio库 我需要将 MP3 转换为 WAV 我想在内存中执行所有操作 因为我需要它快速 但我有问题 下