使用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);
}
答案 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);
}
}