C# WaveOut在另一个环境中播放时口吃

C# WaveOut在另一个环境中播放时口吃,c#,streaming,naudio,waveout,C#,Streaming,Naudio,Waveout,我正在使用NAudio library实时播放mp3。我已经准备了一个代码来做这件事,除了在另一个进程中播放另一个媒体(例如Youtube、本地mp3播放器……)时,它通常工作得很好。在那个时候,mp3是口吃。我不知道为什么会这样。如何解决这个问题 要在控制台应用程序中流式处理的代码。复制粘贴,你可以试试 static void Main(字符串[]args) { AcmMp3FrameDecompressor decompressor=null; BufferedWaveProvider=nu

我正在使用NAudio library实时播放mp3。我已经准备了一个代码来做这件事,除了在另一个进程中播放另一个媒体(例如Youtube、本地mp3播放器……)时,它通常工作得很好。在那个时候,mp3是口吃。我不知道为什么会这样。如何解决这个问题

要在控制台应用程序中流式处理的代码。复制粘贴,你可以试试

static void Main(字符串[]args)
{
AcmMp3FrameDecompressor decompressor=null;
BufferedWaveProvider=null;
波形格式mp3format=null;
WaveOut WaveOut=新的WaveOut();
长尺寸=0;
字节[]decbuffer=新字节[50*1024];
//我正在使用listentoyoutube.com转换的mp3链接
//但是链接会过期,所以我没有放任何链接
字符串url=“”;
字符串path=path.Combine(path.GetTempPath(),“test.mp3”);
CheckUrlandCreateTools(url、ref解压器、ref MP3格式、ref大小);
FileStream fs=newfilestream(路径,FileMode.Create,FileAccess.ReadWrite);
HttpWebRequest req=WebRequest.Create(url)为HttpWebRequest;
HttpWebResponse resp=req.GetResponse()作为HttpWebResponse;
Stream remote=resp.GetResponseStream();
Mp3Frame=null;
MemoryStream ms=null;
字节[]缓冲区=新字节[1024];
int read=0;
长偏移=0;
provider=新的BufferedWaveProvider(decompressor.OutputFormat);
provider.BufferDuration=TimeSpan.FromSeconds(20);
waveOut.Init(提供者);
waveOut.Play();
while(waveOut.PlaybackState==PlaybackState.Playing)
{
如果((read=remote.read(buffer,0,buffer.Length))>0)
fs.写入(缓冲区,0,读取);
fs.Flush();
ms=新内存流(ReadStreamPartially(fs,偏移量,100*1024));
尝试
{
frame=Mp3Frame.LoadFromStream(毫秒);
if(frame==null)
继续;
}
抓住
{
继续;
}
偏移量+=毫秒位置;
int decompressed=解压器。DecompressFrame(frame,decbuffer,0);
AddSamples(decbuffer,0,解压缩);
if(IsBufferNearlyFull(提供程序))
睡眠(500);
}
}
公共静态字节[]ReadStreamPartially(System.IO.FileStream流,
长偏移量,长计数)
{
长原始位置=流位置;
流位置=偏移量;
字节[]读缓冲区=新字节[4096];
字节[]总计=新字节[计数];
int totalBytesRead=0;
内特比德;
而((byteRead=stream.ReadByte())!=-1)
{
SetByte(总计,总计字节读取,(字节)字节读取);
totalBytesRead++;
if(totalBytesRead==计数)
打破
}
if(totalBytesRead<计数)
{
字节[]临时=新字节[totalBytesRead];
Buffer.BlockCopy(总计、0、临时、0、总计字节读取);
流位置=原始位置;
返回温度;
}
流位置=原始位置;
返回总数;
}
公共静态bool IsBufferNearlyFull(BufferedWaveProvider BufferedWaveProvider)
{
返回bufferedWaveProvider!=null&&
bufferedWaveProvider.BufferLength-bufferedWaveProvider.BufferedBytes
0)
{
Buffer.BlockCopy(Buffer,0,storer,total,bytesRead);
总计+=字节读取;
Mp3Frame=Mp3Frame.LoadFromStream(新内存流(存储器));
如果(frame==null)继续;
格式=新的Mp3WaveFormat(frame.SampleRate,frame.ChannelMode==ChannelMode.Mono?1:2,
frame.FrameLength,frame.BitRate);
解压缩器=新的AcmMp3FrameDecompressor(格式);
请求中止();
分别关闭();
str.Close();
打破
}
}
公共静态HttpWebRequest SendRequest(字符串url,长从,长到)
{
HttpWebRequest req=WebRequest.Create(url)为HttpWebRequest;
请求凭证=CredentialCache.DefaultCredentials;
req.Accept=“*/*”;
req.KeepAlive=false;
req.UserAgent=“Mozilla/4.0(兼容;MSIE 6.0;Windows NT 5.2;.NET CLR 1.0.3705;”);
req.AllowAutoRedirect=真;
如果(到>0)
请求添加范围(从,到);
返回请求;
}
}

不要在visual studio中进行测试,请在发布模式下编译项目,然后重试。(运行exe文件)哇,真管用。我刚刚学会了释放模式。发布模式消耗的资源是否比调试模式少?请查看。(另外,选中“生成选项”选项卡中的“优化代码”)
    static void Main(string[] args)
    {
        AcmMp3FrameDecompressor decompressor = null;
        BufferedWaveProvider provider = null;
        WaveFormat mp3format = null;
        WaveOut waveOut = new WaveOut();
        long size = 0;
        byte[] decbuffer = new byte[50 * 1024];

        //I am using mp3 links converted by listentoyoutube.com 
        //But links will be expired, so I didnt put any

        string url = "";
        string path = Path.Combine(Path.GetTempPath(), "test.mp3");

        CheckUrlandCreateTools(url, ref decompressor, ref mp3format, ref size);

        FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite);
        HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
        HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
        Stream remote = resp.GetResponseStream();
        Mp3Frame frame = null;
        MemoryStream ms = null;
        byte[] buffer = new byte[1024];
        int read = 0;
        long offset = 0;
        provider = new BufferedWaveProvider(decompressor.OutputFormat);
        provider.BufferDuration = TimeSpan.FromSeconds(20);
        waveOut.Init(provider);
        waveOut.Play();
        while (waveOut.PlaybackState == PlaybackState.Playing)
        {
            if((read = remote.Read(buffer, 0, buffer.Length)) > 0)
            fs.Write(buffer, 0, read);
            fs.Flush();
            ms = new MemoryStream(ReadStreamPartially(fs, offset, 100 * 1024));
            try
            {
                frame = Mp3Frame.LoadFromStream(ms);
                if (frame == null)
                    continue;
            }
            catch
            {
                continue;
            }

            offset += ms.Position;
            int decompressed = decompressor.DecompressFrame(frame, decbuffer, 0);
            provider.AddSamples(decbuffer, 0, decompressed);
            if (IsBufferNearlyFull(provider))
                Thread.Sleep(500);
        }
    }

    public static byte[] ReadStreamPartially(System.IO.FileStream stream,
                                        long offset, long count)
    {
        long originalPosition = stream.Position;
        stream.Position = offset;

        byte[] readBuffer = new byte[4096];
        byte[] total = new byte[count];
        int totalBytesRead = 0;
        int byteRead;

        while ((byteRead = stream.ReadByte()) != -1)
        {
            Buffer.SetByte(total, totalBytesRead, (byte)byteRead);
            totalBytesRead++;
            if (totalBytesRead == count)
                break;
        }
        if (totalBytesRead < count)
        {
            byte[] temp = new byte[totalBytesRead];
            Buffer.BlockCopy(total, 0, temp, 0, totalBytesRead);
            stream.Position = originalPosition;
            return temp;
        }
        stream.Position = originalPosition;
        return total;
    }
    public static bool IsBufferNearlyFull(BufferedWaveProvider bufferedWaveProvider)
    {
        return bufferedWaveProvider != null &&
               bufferedWaveProvider.BufferLength - bufferedWaveProvider.BufferedBytes
               < bufferedWaveProvider.WaveFormat.AverageBytesPerSecond / 4;
    }
    public static void CheckUrlandCreateTools(string url, ref AcmMp3FrameDecompressor decompressor,
        ref WaveFormat format, ref long size)
    {
        HttpWebRequest req = SendRequest(url, 0, 0);
        HttpWebResponse resp = req.GetResponse() as HttpWebResponse;
        size = resp.ContentLength;
        Stream str = resp.GetResponseStream();
        byte[] buffer = new byte[1024];
        byte[] storer = new byte[1024 * 100];
        int bytesRead = 0;
        int total = 0;
        while ((bytesRead = str.Read(buffer, 0, buffer.Length)) > 0)
        {
            Buffer.BlockCopy(buffer, 0, storer, total, bytesRead);
            total += bytesRead;

            Mp3Frame frame = Mp3Frame.LoadFromStream(new MemoryStream(storer));
            if (frame == null) continue;

            format = new Mp3WaveFormat(frame.SampleRate, frame.ChannelMode == ChannelMode.Mono ? 1 : 2,
            frame.FrameLength, frame.BitRate);
            decompressor = new AcmMp3FrameDecompressor(format);

            req.Abort();
            resp.Close();
            str.Close();

            break;
        }
    }

    public static HttpWebRequest SendRequest(string url, long from, long to)
    {
        HttpWebRequest req = WebRequest.Create(url) as HttpWebRequest;
        req.Credentials = CredentialCache.DefaultCredentials;
        req.Accept = "*/*";
        req.KeepAlive = false;
        req.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)";
        req.AllowAutoRedirect = true;
        if (to > 0)
            req.AddRange(from, to);
        return req;
    }
}