与 Naudio RadioStreaming 的统一

Unity with Naudio RadioStreaming

我正在使用基于我的 Unity 游戏中 NAudio Demo modified for streaming a Shoutcast 的脚本。

我尝试使用 MonoBehvaiour class 的更新删除原始的 while 循环,在使用此脚本进行流式传输时,我只听到一些噪音,但听不到音乐。

我通常在执行与格式相关的错误时遇到错误

MmException: AcmNotPossible calling acmStreamConvert NAudio.MmException.Try (MmResult result, System.String function) 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();
            }
        }
    }
}

ACM 错误意味着机器上没有 ACM MP3 解码器,或者可能收到了损坏的帧(或者某些专辑封面被误解为帧)。是后者,您可以捕获错误并忽略它。如果是前者,则需要安装解码器,或使用不同的 MP3 帧解压缩器。 (可能是NLayer one)。