【问题标题】:How to play a MP3 file using NAudio如何使用 NAudio 播放 MP3 文件
【发布时间】:2011-01-30 02:43:00
【问题描述】:
WaveStream waveStream = new Mp3FileReader(mp3FileToPlay);
var waveOut = new WaveOut();
waveOut.Init(waveStream); 
waveOut.Play();

这会引发异常:

WaveBadFormat 调用 waveOutOpen

编码类型为“MpegLayer3”作为NAudio。

如何使用 NAudio 播放 mp3 文件?

【问题讨论】:

    标签: c# mp3 naudio


    【解决方案1】:

    对于 NAudio 1.6 及以上版本的用户,请不要使用原始接受答案中的代码。您不需要添加WaveFormatConversionStreamBlockAlignReductionStream,并且应避免将WaveOut 与函数回调一起使用(如果您不在WinForms 或WPF 应用程序中,则最好使用WaveOutEvent)。此外,除非您想阻止播放,否则您通常不会在音频完成之前睡觉。只需订阅WaveOutPlaybackStopped 活动即可。

    以下代码可以很好地在 NAudio 中播放 MP3:

    var reader = new Mp3FileReader("test.mp3");
    var waveOut = new WaveOut(); // or WaveOutEvent()
    waveOut.Init(reader); 
    waveOut.Play();
    

    【讨论】:

    • 嗨,马克,谢谢你的回答。我想知道,根据你的回答,“test.mp3”文件应该放在哪里?
    • 哇。如此高投票的答案与 OP 编写的确切代码 - 或者到底有什么区别?我一个都找不到。
    • WaveOut 是一次性的,但从未在您的代码中处理过。如果您处理它,音频将停止播放。如果你不处理它,它可能只会在垃圾收集器收集它之前播放。
    • @ThomasWeller 你是对的,问题和答案具有相同的代码。不同的是日期。当最初的问题被问到时,Mp3FileReader 没有从其 Read 方法发出 PCM,因此代码不起作用。最初接受的答案现在不是解决问题的推荐方法。
    • @MarkHeath - 我最近偶然发现了 NAudio,因为我最终决定 wmp 对我的播放列表的不断损坏需要一个个人 mp3 播放器项目。在不到一天的时间里,通过您的库,我能够轻松地创建一个尊重播放列表的 wmp 克隆。考虑到您实际上是 NAudio 的作者,我发现您在此呼唤您的回答颇具讽刺意味。您的库已很好地集成到 Windows 10 上的 .NET 4.7+ 中,只需几个小时即可完全实现。从您最初的回复 6 年后,代码仍然按照编写的方式执行。谢谢。
    【解决方案2】:

    试试这样:

    class Program
    {
        static void Main()
        {
            using (var ms = File.OpenRead("test.mp3"))
            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);
                }
            }
        }
    }
    

    编辑此代码现已过期(与 NAudio 1.3 相关)。不推荐在较新版本的 NAudio 上使用。请参阅替代答案。

    【讨论】:

    • 这不起作用。 "调用 acmStreamPrepareHeader 的无效参数"
    • 我刚刚下载了最新版本的 NAudio (codeplex.com/naudio) 并在我的电脑上用 mp3 测试了这段代码。它对我有用。
    • 你有64位的环境吗?我已经使用 x64 重新编译了解决方案,发布模式并将 .net 平台从 .NET 2.0 更改为 3.5 ...也许正因为如此我得到了错误?
    • 是的,我在 Win7 64 位上运行,我必须在项目属性中以 x86 为目标才能使其工作。针对Any CPUNAudio.dll 抛出了BadImageFormatException
    • NAudio 中的 x64 支持有望很快到来。查看最近签到 - naudio.codeplex.com/SourceControl/list/changesets
    【解决方案3】:

    我喜欢使用 NAudio 播放任何 MP3 文件的方式是这样。我更喜欢阻止正在播放的线程,直到 Playback 因事件侦听器而停止。另外,为了获得最佳兼容性,我使用 MP3Sharp 加载 MP3 文件,然后将其传递给 NAudio,因为 NAudio 没有附带 MP3 编解码器。

    using System;
    using NAudio.Wave;
    using System.Threading;
    using MP3Sharp;
    using System.IO;
    
    namespace jessielesbian.NAudioTest
    {
        public static class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("loading and parsing MP3 file...");
                MP3Stream stream = new MP3Stream("c:\\workspaces\\Stunning!  Boeing's 737 MAX on Flying Display.mp3");
                WaveFormat waveFormat = new WaveFormat(stream.Frequency, stream.ChannelCount);
                Console.WriteLine("allocating playback cache...");
                FastWaveBuffer fastWaveBuffer = new FastWaveBuffer(waveFormat, (int) stream.Length);
                Console.WriteLine("populating playback cache...");
                stream.CopyTo(fastWaveBuffer);
                fastWaveBuffer.Seek(0, SeekOrigin.Begin);
                Console.WriteLine("unloading MP3 file...");
                stream.Dispose();
                Console.WriteLine("prepairing player...");
                WaveOutEvent waveOutEvent = new WaveOutEvent();
                waveOutEvent.Init(fastWaveBuffer);
                waveOutEvent.Volume = 1;
                Console.WriteLine("arming ManualResetEvent...");
                ManualResetEvent manualResetEvent = new ManualResetEvent(false);
                waveOutEvent.PlaybackStopped += (object sender, StoppedEventArgs e) => {
                    manualResetEvent.Set();
                };
                Console.WriteLine("done!");
                waveOutEvent.Play();
                manualResetEvent.WaitOne();
            }
        }
        public sealed class FastWaveBuffer : MemoryStream, IWaveProvider
        {
            public FastWaveBuffer(WaveFormat waveFormat, byte[] bytes) : base(bytes)
            {
                WaveFormat = waveFormat;
            }
            public FastWaveBuffer(WaveFormat waveFormat, int size = 4096) : base()
            {
                WaveFormat = waveFormat;
                Capacity = size;
            }
            public WaveFormat WaveFormat
            {
                get;
            }
        }
    }
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-14
      • 1970-01-01
      • 2013-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多