C#CSCore没有来自mp3文件的声音

时间:2017-12-23 16:52:04

标签: c# .net cscore

使用CSCore库,我在一个名为BGM的单独文件中编写了用于在类BGM.cs中播放mp3文件的代码,并且播放的方法是BGM.Play("file directory");,这被称为在表格中。但不知何故,我无法从中获得任何声音。我已经检查了音量,编解码器和输出,我想不出任何可能导致这个问题的事情。

这是类文件的代码:

public class BGM
{
    public static void Play(string file)
    {
        using (IWaveSource soundSource = GetSoundSource(file))
        {
            using (ISoundOut soundOut = GetSoundOut())
            {
                soundOut.Initialize(soundSource);
                soundOut.Volume = 0.8f;
                soundOut.Play();
            }
        }
    }
    private static ISoundOut GetSoundOut()
    {
        if (WasapiOut.IsSupportedOnCurrentPlatform)
            return new WasapiOut();
        else
            return new DirectSoundOut();
    }
    private static IWaveSource GetSoundSource(string file)
    {
        return CodecFactory.Instance.GetCodec(file);
    }

1 个答案:

答案 0 :(得分:0)

实际上有几个原因导致你的mp3没有播放。

第一个原因是你还没有指定设备来播放声音。下面的代码获得了第一个可以呈现声音的设备,但如果用户将多个设备连接到他们的计算机上,那么它将永远不会是正确的。你必须妥善处理。必须在WasapiOut对象上设置设备。

第二个原因是您在using方法中使用Play语句。虽然清理实施IDisposable的对象总是一个好主意,但您不能立即这样做。在这种情况下,soundOut.Play()不是阻止方法,这意味着控件立即退出方法,导致Dispose()soundOut上的soundSource被调用。这意味着声音实际上永远不会被播放(也许它会在短时间内开始,但还不足以真正听到它)。基本上,您需要保留引用,并在播放完成后才处理它们。

请查看AudioPlayerSample,了解如何实施完整的解决方案。我的代码应该让你开始。

void Main()
{
    using(var player = new BGM(@"D:\Test.mp3"))
    {
        player.Play();

        // TODO: Need to wait here in order for playback to complete
        // Otherwise, you need to hold onto the player reference and dispose of it later
        Console.ReadLine();
    }
}

public class BGM : IDisposable
{
    private bool _isDisposed = false;
    private ISoundOut _soundOut;
    private IWaveSource _soundSource;

    public BGM(string file)
    {
        _soundSource = CodecFactory.Instance.GetCodec(file);
        _soundOut = GetSoundOut();
        _soundOut.Initialize(_soundSource);
    }

    public void Play()
    {
        if(_soundOut != null)
        {
            _soundOut.Volume = 0.8f;
            _soundOut.Play();
        }
    }

    public void Stop()
    {
        if(_soundOut != null)
        {
            _soundOut.Stop();
        }
    }

    private static ISoundOut GetSoundOut()
    {
        if (WasapiOut.IsSupportedOnCurrentPlatform)
        {
            return new WasapiOut
            {
                Device = GetDevice()
            };
        }

        return new DirectSoundOut();
    }

    private static IWaveSource GetSoundSource(string file)
    {
        return CodecFactory.Instance.GetCodec(file);
    }

    public static MMDevice GetDevice()
    {
        using(var mmdeviceEnumerator = new MMDeviceEnumerator())
        {
            using(var mmdeviceCollection = mmdeviceEnumerator.EnumAudioEndpoints(DataFlow.Render, DeviceState.Active))
            {
                // This uses the first device, but that isn't what you necessarily want
                return mmdeviceCollection.First();
            }
        }
    }

    protected virtual void Dispose(bool disposing)
    {
        if (!_isDisposed)
        {
            if (disposing)
            {
                if(_soundOut != null)
                {
                    _soundOut.Dispose();
                }

                if(_soundSource != null)
                {
                    _soundSource.Dispose();
                }
            }

            _isDisposed = true;
        }
    }

    public void Dispose()
    {
        Dispose(true);
    }
}