⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 avstream.cs

📁 语音视频功能 里面实现了基本的QQ与语音对话
💻 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 + -