C# WaveOut在另一个环境中播放时口吃
我正在使用NAudio library实时播放mp3。我已经准备了一个代码来做这件事,除了在另一个进程中播放另一个媒体(例如Youtube、本地mp3播放器……)时,它通常工作得很好。在那个时候,mp3是口吃。我不知道为什么会这样。如何解决这个问题 要在控制台应用程序中流式处理的代码。复制粘贴,你可以试试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
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;
}
}