与 Naudio RadioStreaming 的 Unity
Posted
技术标签:
【中文标题】与 Naudio RadioStreaming 的 Unity【英文标题】:Unity with Naudio RadioStreaming 【发布时间】:2015-08-09 16:38:15 【问题描述】:我在 Unity 游戏中使用基于 NAudio Demo modified for streaming a Shoutcast 的脚本。
我尝试使用 MonoBehvaiour 类中的更新来删除原始的 while 循环,但在我使用此脚本进行流式传输时,我只听到了一些噪音但没有音乐。
在执行与格式相关时,我通常会遇到错误
MmException: AcmNotPossible 调用 acmStreamConvert NAudio.MmException.Try(MmResult 结果,System.String 函数) NAudio.Wave.Compression.AcmStreamHeader.Convert (Int32 bytesToConvert, System.Int32& sourceBytesConverted) NAudio.Wave.Compression.AcmStream.Convert (Int32 bytesToConvert, System.Int32& sourceBytesConverted) NAudio.Wave.AcmMp3FrameDecompressor.DecompressFrame (NAudio.Wave.Mp3Frame frame, System.Byte[] dest, Int32 destOffset)
我在网上尝试过使用不同的收音机,但我总是收到这个错误。我不知道发生了什么...有什么帮助吗?
public class NAudiostreamer : MonoBehaviour
private IWavePlayer mWaveOutDevice;
private WaveStream mMainOutputStream;
private WaveChannel32 mVolumeStream;
private VolumeWaveProvider16 volumeProvider;
private string m_Url = "http://37.59.32.115:8122/";
enum StreamingPlaybackState
Stopped,
Playing,
Buffering,
Paused
private volatile StreamingPlaybackState playbackState = StreamingPlaybackState.Stopped;
private bool fullyDownloaded = false;
public bool m_Play = false;
float timer;
void Update()
if (m_Play)
playbackState = StreamingPlaybackState.Buffering;
StreamMP3(m_Url);
m_Play = false;
switch (playbackState)
case StreamingPlaybackState.Buffering:
case StreamingPlaybackState.Playing:
StreamMP3(m_Url);
break;
default:
break;
HttpWebRequest webRequest;
BufferedWaveProvider bufferedWaveProvider = null;
byte[] buffer = new byte[16384 * 4];
private void StreamMP3(string lUrl)
this.fullyDownloaded = false;
webRequest = (HttpWebRequest)WebRequest.Create(lUrl);
int metaInt = 0; // blocksize of mp3 data
webRequest.Headers.Clear();
webRequest.Headers.Add("GET", "/ HTTP/1.0");
webRequest.Headers.Add("Icy-MetaData", "1");
webRequest.UserAgent = "WinampMPEG/5.09";
HttpWebResponse resp = null;
try
resp = (HttpWebResponse)webRequest.GetResponse();
catch(WebException e)
if (e.Status != WebExceptionStatus.RequestCanceled)
Debug.LogError(e.Message);
return;
// needs to be big enough to hold a decompressed frame
try
// read blocksize to find metadata block
metaInt = Convert.ToInt32(resp.GetResponseHeader("icy-metaint"));
catch
IMp3FrameDecompressor decompressor = null;
try
using (var responseStream = resp.GetResponseStream())
ReadFullyStream readFullyStream = new ReadFullyStream(responseStream);
//do
if (bufferedWaveProvider != null && bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4)
Debug.LogError("Buffer getting full, taking a break");
Thread.Sleep(500);
else
Mp3Frame frame = null;
try
frame = Mp3Frame.LoadFromStream(readFullyStream, true);
catch (EndOfStreamException)
this.fullyDownloaded = true;
Debug.LogError("reached the end of the MP3 file / stream");
// reached the end of the MP3 file / stream
// break;
catch (WebException)
// probably we have aborted download from the GUI thread
// break;
if (decompressor == null && frame != null)
// don't think these details matter too much - just help ACM select the right codec
// however, the buffered provider doesn't know what sample rate it is working at
// until we have a frame
WaveFormat waveFormat = new Mp3WaveFormat(frame.SampleRate, frame.ChannelMode == ChannelMode.Mono ? 1 : 2, frame.FrameLength, frame.BitRate);
decompressor = new AcmMp3FrameDecompressor(waveFormat);
if(bufferedWaveProvider == null)
this.bufferedWaveProvider = new BufferedWaveProvider(decompressor.OutputFormat);
this.bufferedWaveProvider.BufferDuration = TimeSpan.FromSeconds(20); // allow us to get well ahead of ourselves
int decompressed = decompressor.DecompressFrame(frame, buffer, 0);
if(bufferedWaveProvider != null)
bufferedWaveProvider.AddSamples(buffer, 0, decompressed);
if (this.mWaveOutDevice == null && this.bufferedWaveProvider != null)
Debug.Log("Creating WaveOut Device");
this.mWaveOutDevice = new WaveOut();
this.volumeProvider = new VolumeWaveProvider16(bufferedWaveProvider);
this.volumeProvider.Volume = 100.0f;
mWaveOutDevice.Init(volumeProvider);
else if (bufferedWaveProvider != null)
double bufferedSeconds = bufferedWaveProvider.BufferedDuration.TotalSeconds;
if(bufferedSeconds > 0.2f && playbackState == StreamingPlaybackState.Buffering)
Debug.Log("PLaying music...");
mWaveOutDevice.Play();
playbackState = StreamingPlaybackState.Playing;
finally
if (decompressor != null)
decompressor.Dispose();
【问题讨论】:
【参考方案1】:ACM 错误意味着机器上没有 ACM MP3 解码器,或者可能接收到损坏的帧(或某些专辑封面被误解为帧)。是后者,您可以捕获错误并忽略它。如果是前者,则需要安装解码器,或使用不同的 MP3 帧解压缩器。 (可能是NLayer one)。
【讨论】:
以上是关于与 Naudio RadioStreaming 的 Unity的主要内容,如果未能解决你的问题,请参考以下文章
NAudio 与 MultiplexingSampleProvider 和 WasapiOut
NAudio - WaveOut 与 WaveOffsetStream 一起使用时不会引发 PlaybackStopped 事件
如何使用 NAudio 将两个 wav 音频文件与 30 秒的白色声音连接起来