📄 avstream.cs
字号:
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;using System.IO;
using gowk.multimedia;
using System.Runtime.InteropServices;
using System.Net.Sockets;
using System.Net;
namespace gowk.multimedia
{
/// <summary>
/// AVChanel 的摘要说明。
/// </summary>
public class AVChanel
{
Socket sock;
byte[] buffer;
ICCompressor cp;
ICDecompressor dp;
G729 g729;
EndPoint rmtEP;
int localPort=4567;
private bool connected;
public bool Connected
{
get{return this.connected;}
// set{this.connected=value;}
}
public event AVChanelEventHandler AudioData,VideoData,SteamStart,StreamEnd,StreamError;
public AVChanel()
{
this.rmtEP=new IPEndPoint(IPAddress.Any,0);
}
public void Open()
{
this.sock=new Socket(AddressFamily.InterNetwork,SocketType.Dgram,ProtocolType.Udp);
// int port=3456;
while(true)
{
try
{
this.sock.Bind(new IPEndPoint(IPAddress.Any,this.localPort));
break;
}
catch(System.Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message);
this.localPort++;
}
}
this.IniVideoCompress();
this.ReceiveInternal();
this.IniAudioCompress();
}
private void ReceiveInternal()
{
this.buffer=new byte[65535];
// EndPoint rep=new IPEndPoint(IPAddress.Any,0);
try
{
if(this.sock==null)return;
this.sock.BeginReceiveFrom(buffer,0,buffer.Length,SocketFlags.None,ref this.rmtEP,new AsyncCallback(this.ACB),null);
}
catch(System.Net.Sockets.SocketException se)
{
this.OnStreamError(new AVChanelEventArgs(null));
System.Diagnostics.Trace.WriteLine(se.Message+":"+se.StackTrace);
}
catch(System.ObjectDisposedException odd)
{
gowk.utility.Diagnostics.Debug.Write(odd);
}
}
private void ACB(System.IAsyncResult iar)
{
// EndPoint rep=new IPEndPoint(IPAddress.Any,0);
// EndPoint ep=(EndPoint)iep;
// System.Diagnostics.Trace.WriteLine(iar.IsCompleted.ToString());
int cnt=0;
try
{
if(this.sock==null)return;
cnt=this.sock.EndReceiveFrom(iar,ref this.rmtEP);
}
catch(System.Net.Sockets.SocketException se)
{
this.OnStreamError(new AVChanelEventArgs(null));
System.Diagnostics.Trace.WriteLine(se.Message+":"+se.StackTrace);
}
catch(System.ObjectDisposedException odd)
{
gowk.utility.Diagnostics.Debug.Write(odd);
}
if(cnt>0)
{
// byte[] b=(byte[])iar.AsyncState;
byte[] n=new byte[cnt-1];
Buffer.BlockCopy(this.buffer,1,n,0,cnt-1);
switch(this.buffer[0])
{
case 0:
this.OnAudioData(new AVChanelEventArgs(n));
break;
case 1:
this.OnVideoData(new AVChanelEventArgs(n));
break;
case 2:
if(this.rmtEP==null)
{
IPEndPoint rmt=(IPEndPoint)iar.AsyncState;
this.rmtEP=rmt;
}
this.OnStreamStart(new AVChanelEventArgs(null));
break;
case 3:
this.OnStreamEnd(new AVChanelEventArgs(null));
break;
}
}
this.ReceiveInternal();
}
private void OnAudioData(AVChanelEventArgs e)
{
// System.Diagnostics.Trace.WriteLine("audio:"+e.Data.Length.ToString());
byte[] dst=this.g729.Decode(e.Data);
if(this.AudioData!=null)this.AudioData(this,new AVChanelEventArgs(dst));
}
public byte[] en(byte[] data)
{
return this.g729.Encode(data);
}
public byte[] de(byte[] data)
{
return this.g729.Decode(data);
}
private void OnVideoData(AVChanelEventArgs e)
{
// System.Diagnostics.Trace.WriteLine("video:"+e.Data.Length.ToString());
byte[] decompressdata=this.dp.Process(e.Data);
if(this.VideoData!=null)this.VideoData(this,new AVChanelEventArgs(decompressdata));
}
private void OnStreamStart(AVChanelEventArgs e)
{
if(!this.Connected)
{
this.connected=true;
if(this.SteamStart!=null)this.SteamStart(this,e);
this.SendHello();
}
}
private void SendHello()
{
byte[] b=new byte[1];
b[0]=2;
this.Send(b);
}
private void SendBye()
{
byte[] b=new byte[1];
b[0]=3;
this.Send(b);
}
public void Disconnect()
{
if(!this.Connected)return;
this.SendBye();
System.Threading.Thread.Sleep(50);
this.connected=false;
// this.sock.Shutdown(System.Net.Sockets.SocketShutdown.Both);
}
public void Close()
{
if(this.sock!=null)
{
lock(this.sock)
{
// this.sock.Shutdown(System.Net.Sockets.SocketShutdown.Both);
this.sock.Close();
this.sock=null;
}
}
if(this.dp!=null)
{
this.dp.Close();
}
if(this.cp!=null)
{
this.cp.Close();
}
}
private void OnStreamEnd(AVChanelEventArgs e)
{
this.connected=false;
if(this.StreamEnd!=null)this.StreamEnd(this,e);
}
private void OnStreamError(AVChanelEventArgs e)
{
this.connected=false;
if(this.StreamError!=null)this.StreamError(this,e);
}
public void Connect(string rmtip,int port)
{
this.rmtEP=new IPEndPoint(IPAddress.Parse(rmtip),port);
this.SendHello();
}
private void Send(byte[] bs)
{
try
{
this.sock.BeginSendTo(bs,0,bs.Length,SocketFlags.None,this.rmtEP,new AsyncCallback(this.SendCallback),null);
}
catch(System.Net.Sockets.SocketException se)
{
System.Diagnostics.Trace.WriteLine(se.Message+":"+se.StackTrace);
this.OnStreamError(new AVChanelEventArgs(null));
// System.Diagnostics.Debug.Assert(false,se.Message+"error code:"+se.ErrorCode.ToString());
// throw;
}
}
public int LocalPort
{
get{return this.localPort;}
set{this.localPort=value;}
}
public void SendCallback(System.IAsyncResult iar)
{
try
{
int cnt=this.sock.EndSendTo(iar);
}
catch(System.Exception ex)
{
System.Diagnostics.Trace.WriteLine(ex.Message+":"+ex.StackTrace);
this.OnStreamError(new AVChanelEventArgs(null));
}
}
public void SendAudio(byte[] bs)
{
/* double sum=0.0;
for(int i=0;i<bs.Length;i+=20)
{
short s=System.BitConverter.ToInt16(bs,i);
int v=bs[i];
sum+=s;
}
double avg=sum/(int)(bs.Length/20);
System.Diagnostics.Trace.WriteLine("avg:"+avg.ToString());*/
byte[] compresseddata=this.g729.Encode(bs);
byte[] b=new byte[compresseddata.Length+1];
b[0]=0;
Buffer.BlockCopy(compresseddata,0,b,1,compresseddata.Length);
this.Send(b);
}
public void SendVideo(byte[] bs)
{
byte[] compresseddata=this.cp.Process(bs);
// if(compresseddata==null)return;
byte[] b=new byte[compresseddata.Length+1];
b[0]=1;
Buffer.BlockCopy(compresseddata,0,b,1,compresseddata.Length);
this.Send(b);
}
private void IniVideoCompress()
{
COMPVARS pp=new COMPVARS();
pp.cbSize=Marshal.SizeOf(pp);
pp.dwFlags=1;
pp.fccHandler=FOURCC.MP42;;
pp.fccType=FOURCC.ICTYPE_VIDEO;
pp.lDataRate=120;
pp.lKey=15;
pp.lQ=-1;
pp.lQ=1000;
COMPVARS p2=pp;
BITMAPINFOHEADER bmi=new BITMAPINFOHEADER();
bmi.biCompression =(int) BI.BI_RGB;
bmi.biWidth = 160;
bmi.biHeight = 120;
bmi.biPlanes = 1;
bmi.biBitCount = 24;
bmi.biXPelsPerMeter = 0;
bmi.biYPelsPerMeter = 0;
bmi.biClrUsed = 0;
bmi.biClrImportant = 0;
bmi.biSizeImage=57600;
bmi.biSize=Marshal.SizeOf(bmi);
BITMAPINFO bi=new BITMAPINFO();
bi.bmiHeader=bmi;
BITMAPINFOHEADER bmi2=new BITMAPINFOHEADER();
bmi2.biCompression =FOURCC.MP42;
bmi2.biWidth = 160;
bmi2.biHeight = 120;
bmi2.biPlanes = 1;
bmi2.biBitCount = 24;
bmi2.biXPelsPerMeter = 0;
bmi2.biYPelsPerMeter = 0;
bmi2.biClrUsed = 0;
bmi2.biClrImportant = 0;
bmi2.biSize=40;
bmi2.biSizeImage=57600;
BITMAPINFO bi2=new BITMAPINFO();
bi2.bmiHeader=bmi2;
this.dp=new ICDecompressor(new COMPVARS(),bi2,FOURCC.MP42);
this.dp.Open();
this.cp=new ICCompressor(pp,bi,FOURCC.MP42);
this.cp.Open();
}
private void IniAudioCompress()
{
this.g729=new G729();
this.g729.InitalizeDecode();
this.g729.InitalizeEncode();
}
public delegate void AVChanelEventHandler(object sender,AVChanelEventArgs e);
public class AVChanelEventArgs:System.EventArgs
{
public byte[] Data;
public AVChanelEventArgs(byte[] data)
{
this.Data=data;
}
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -