3

I'm already going crazy. So I decided to ask for help.

Scenario: In a web page, connect to the server via TCP socket, and in a loop I get the data byte by byte. These data are continuous.

Question: How do I make a WebSocket that receive and send data to the player ( html5 tag).

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;
 }
 }
}

Then, as the loop receives the data line by line, I am sending to the player. But the only sound I hear is the last line of the loop.

I tried to put the player in a thread without success.

Is this possible? Any idea?

asked Nov 9, 2012 at 16:03
1

2 Answers 2

1

You close the response stream inside your while loop. This will close the connection and interrupt the outgoing stream.

Consider something like:

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(); 
answered Nov 17, 2012 at 13:59
Sign up to request clarification or add additional context in comments.

1 Comment

Hello Lukas! Thanks for the reply! I made the change you suggested. But it still did not work. While the application is in the loop. The command Response.Flush() sends several times the bytes to the browser. But the browser does not respond. Only when the loop is over the browser is released and plays the last data packet. Can you help?
0

After several attempts, finally managed to get a satisfactory result. See the code.

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;
 }
}

Thank you all!

answered Nov 30, 2012 at 12:53

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.