我已经疯了。所以我决定寻求帮助。
场景:在网页中,通过TCP套接字连接到服务器,并在循环中逐字节获取数据。这些数据是连续的。
问题:如何创建一个接收并向播放器发送数据的WebSocket(html5标签)。
Default.aspx的
<asp:Literal ID="ltrPlayer" runat="server" />
Default.aspx.cs
protected void Page_Load(object sender, EventArgs e)
{
string tele = HttpContext.Current.Request.QueryString["tele"];
string ramal = HttpContext.Current.Request.QueryString["ramal"];
string dac = HttpContext.Current.Request.QueryString["dac"];
string cti = HttpContext.Current.Request.QueryString["cti"];
if ((tele != null) && (ramal != null) && (dac != null) && (cti != null))
{
string strAudio = "<audio controls='controls'>";
strAudio += "<source src='Play.ashx?tele=" + tele + "&ramal=" + ramal + "&dac=" + dac + "&cti=" + cti + "' type='audio/x-wav' controls preload='auto'>";
strAudio += "Seu browser não oferece suporte a este player.";
strAudio += "</audio>";
ltrPlayer.Text = strAudio;
}
}
Play.ashx
<%@ WebHandler Language="C#" Class="Play" %>
using System;
using System.Web;
using System.Net;
using System.IO;
using Alvas.Audio; // Make the conversion VOX to WAV
using System.Media;
using System.Configuration;
using System.Net.Sockets;
using System.Text;
public class Play : IHttpHandler
{
private NetworkStream ns;
public void ProcessRequest(HttpContext context)
{
string tele = HttpContext.Current.Request.QueryString["tele"];
string ramal = HttpContext.Current.Request.QueryString["ramal"];
string dac = HttpContext.Current.Request.QueryString["dac"];
string cti = HttpContext.Current.Request.QueryString["cti"];
if ((tele != null) && (ramal != null) && (dac != null) && (cti != null))
{
try
{
TcpClient oClient = new TcpClient();
oClient.Connect(tele, 22000);
ns = oClient.GetStream();
write(ns, "ondelogar");
ns = oClient.GetStream();
write(ns, "monitorarRamalViaRede(tele;ramal;dac;cti)");
Thread.Sleep(1000);
do
{
if (oClient.GetStream().DataAvailable == true)
{
using (StringReader reader = new StringReader(read(ns)))
{
string line;
while ((line = reader.ReadLine()) != null)
{
Byte[] byteOut = new Byte[line.Length / 2];
int i = 0;
while (i < (line.Length / 2))
{
byteOut[i / 2] = Convert.ToByte(line.Substring(i, 2), 16);
i = i + 2;
}
Stream s = new MemoryStream(byteOut);
BinaryReader br = new BinaryReader(s);
MemoryStream pcmStream = new MemoryStream();
IntPtr pcmFormat = AudioCompressionManager.GetPcmFormat(1, 16, 6000);
WaveWriter ww = new WaveWriter(pcmStream, AudioCompressionManager.FormatBytes(pcmFormat));
Vox.Vox2Wav(br, ww);
WaveReader wr = new WaveReader(pcmStream);
byte[] pcmData = pcmStream.ToArray();
br.Close();
ww.Close();
wr.Close();
pcmStream.Close();
Array.Clear(byteOut, 0, byteOut.Length);
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader("content-disposition", string.Format("attachment; filename=\"{0}\"", "BufferDeAudio"));
HttpContext.Current.Response.ContentType = "audio/x-wav";
HttpContext.Current.Response.BinaryWrite(pcmData);
HttpContext.Current.Response.End();
}
}
}
}
while (oClient.GetStream().DataAvailable == true);
ns.Close();
}
catch (Exception)
{
}
HttpContext.Current.Response.End();
}
}
private void write(NetworkStream ns, string message)
{
byte[] msg = Encoding.ASCII.GetBytes(message + Environment.NewLine);
ns.Write(msg, 0, msg.Length);
}
private string read(NetworkStream ns)
{
StringBuilder sb = new StringBuilder();
if (ns.CanRead)
{
byte[] readBuffer = new byte[1024];
int numBytesRead = 0;
do
{
numBytesRead = ns.Read(readBuffer, 0, readBuffer.Length);
sb.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numBytesRead));
sb.Replace(Convert.ToChar(24), ' ');
sb.Replace(Convert.ToChar(255), ' ');
sb.Replace('?', ' ');
}
while (ns.DataAvailable);
}
return sb.ToString();
}
public bool IsReusable
{
get
{
return false;
}
}
}
然后,当循环逐行接收数据时,我发送给播放器。但我听到的唯一声音是循环的最后一行。
我试图将玩家置于一个线程中但没有成功。
这可能吗?有什么想法吗?
答案 0 :(得分:1)
关闭while循环中的响应流。这将关闭连接并中断传出流。
考虑类似的事情:
HttpContext.Current.Response.Clear();
HttpContext.Current.Response.AddHeader(...))
HttpContext.Current.Response.ContentType = "audio/x-wav";
...
while ((line = reader.ReadLine()) != null)
{
...
HttpContext.Current.Response.BinaryWrite(pcmData);
HttpContext.Current.Response.Flush();
}
HttpContext.Current.Response.End();
答案 1 :(得分:0)
Play.ashx
public void ProcessRequest(HttpContext context)
{
string tele = HttpContext.Current.Request.QueryString["tele"];
string ramal = HttpContext.Current.Request.QueryString["ramal"];
string dac = HttpContext.Current.Request.QueryString["dac"];
string cti = HttpContext.Current.Request.QueryString["cti"];
if ((tele != null) && (ramal != null) && (dac != null) && (cti != null))
{
string strLine = string.Empty;
string strNewLine = string.Empty;
int intCountBuffer = 0;
MemoryStream pcmStream = null;
MemoryStream audioStream = null;
bool blnArmazenarBuffer = true;
try
{
TcpClient oClient = new TcpClient();
oClient.Connect(tele, 22000);
ns = oClient.GetStream();
write(ns, "ondelogar");
ns = oClient.GetStream();
write(ns, "monitorarRamalViaRede(" + tele + ";" + ramal + ";" + dac + ";" + cti + ")");
Thread.Sleep(1000);
context.Response.ClearContent();
context.Response.ClearHeaders();
context.Response.BufferOutput = false;
context.Response.AddHeader("Content-Disposition", "attachment; filename=Gravacao");
context.Response.ContentType = "audio/x-wav";
int readCount;
byte[] data = new byte[oClient.ReceiveBufferSize];
while ((readCount = ns.Read(data, 0, oClient.ReceiveBufferSize)) != 0)
{
using (StringReader readerTest = new StringReader(read(ns)))
{
strLine = readerTest.ReadLine();
if (strLine.Substring(0, 13) == "BufferDeAudio")
{
strLine = strLine.Replace("BufferDeAudio(", string.Empty);
strLine = strLine.Replace(")", string.Empty);
strLine = strLine.Replace(" ", string.Empty);
strLine = strLine.Trim();
if (blnArmazenarBuffer == true)
{
strNewLine += strLine;
intCountBuffer++;
// Holds 10 packages (or 10 seconds) in buffer
// Note: Only for ensuring that the first transmission is delivered.
if (intCountBuffer >= 10)
{
pcmStream = VoxToWav(strNewLine);
strNewLine = string.Empty;
// ChunkSize
// Note. See the documentation on: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
pcmStream.Position = 4;
pcmStream.WriteByte(12);
pcmStream.Position = 5;
pcmStream.WriteByte(77);
pcmStream.Position = 6;
pcmStream.WriteByte(104);
pcmStream.Position = 7;
pcmStream.WriteByte(28);
// SubChunk2Size
pcmStream.Position = 40;
pcmStream.WriteByte(232);
pcmStream.Position = 41;
pcmStream.WriteByte(76);
pcmStream.Position = 42;
pcmStream.WriteByte(104);
pcmStream.Position = 43;
pcmStream.WriteByte(28);
if (context.Response.IsClientConnected)
{
// The first time you step through the loop, i send wav header
audioStream = new MemoryStream();
audioStream.Position = 0;
pcmStream.Position = 0;
audioStream.Write(pcmStream.ToArray(), 0, (Int32)pcmStream.Length);
}
blnArmazenarBuffer = false;
}
}
else
{
pcmStream = VoxToWav(strLine);
strLine = string.Empty;
if (context.Response.IsClientConnected)
{
// Here I have already sent the header. So no need to send it over again.
audioStream = new MemoryStream();
byte[] arr1 = pcmStream.ToArray();
int x = 44;
while (x < (arr1.Length))
{
audioStream.Position = x - 44;
audioStream.WriteByte(arr1[x]);
x++;
}
}
}
context.Response.OutputStream.Write(audioStream.ToArray(), 0, (Int32)audioStream.Length);
context.Response.OutputStream.Flush();
context.Response.OutputStream.Close();
audioStream.Dispose();
}
}
}
}
catch (Exception ex)
{
if (File.Exists(path))
{
StreamWriter w = File.AppendText(path);
w.WriteLine("{0} {1}", DateTime.Now.ToLongTimeString(), DateTime.Now.ToLongDateString());
w.WriteLine(" :");
w.WriteLine(" :{0}", "Play.ashx");
w.WriteLine(" :{0}", ex.Message);
w.WriteLine("-------------------------------");
w.Flush();
w.Close();
}
}
ns.Close();
}
}
private void write(NetworkStream ns, string message)
{
byte[] msg = Encoding.ASCII.GetBytes(message + Environment.NewLine);
ns.Write(msg, 0, msg.Length);
}
private string read(NetworkStream ns)
{
StringBuilder sb = new StringBuilder();
if (ns.CanRead)
{
byte[] readBuffer = new byte[1024];
int numBytesRead = 0;
do
{
numBytesRead = ns.Read(readBuffer, 0, readBuffer.Length);
sb.AppendFormat("{0}", Encoding.ASCII.GetString(readBuffer, 0, numBytesRead));
sb.Replace(Convert.ToChar(24), ' ');
sb.Replace(Convert.ToChar(255), ' ');
sb.Replace('?', ' ');
}
while (ns.DataAvailable);
}
return sb.ToString();
}
private MemoryStream VoxToWav(string strLine)
{
//How do I get the data in hexadecimal. This trick is to order them in pairs.
byte[] byteOut = new byte[strLine.Length / 2];
int j = 0;
while (j < (strLine.Length))
{
byteOut[j / 2] = Convert.ToByte(strLine.Substring(j, 2), 16);
j = j + 2;
}
Stream s = new MemoryStream(byteOut);
BinaryReader br = new BinaryReader(s);
MemoryStream pcmStream = new MemoryStream();
IntPtr pcmFormat = AudioCompressionManager.GetPcmFormat(1, 16, 6000);
WaveWriter ww = new WaveWriter(pcmStream, AudioCompressionManager.FormatBytes(pcmFormat));
Vox.Vox2Wav(br, ww);
return pcmStream;
}
public bool IsReusable
{
get
{
return false;
}
}
谢谢大家!