video

来源:互联网 发布:mysql空间数据库 编辑:程序博客网 时间:2024/04/29 17:52

Introduction

I saw that there are many members asking about how to create an Audio/Video Conferencing System Using .NET, we know that there is no any managed class that supports Audio or Video Streaming in .NET, So I decided to write some applications that can help to write your conferencing application, from time to time you will find a new examples and tutorials about VOIP, Video Conferencing & Network Programming examples in my site www.fadidotnet.org. and also in our Forums http://www.fadidotnet.org/vb. That Specialized In Network Programming and VOIP.

 

Introduction to H.323:

H.323 is an umbrella recommendation from the ITU-T, that defines the protocols to provide audio-visual communication sessions on any packet network. It is currently implemented by various Internet real-time applications such as NetMeeting and Ekiga (the latter using the OpenH323 implementation). It is a part of the H.32x series of protocols which also address communications over ISDN, PSTN or SS7. H.323 is commonly used in VoIP, Internet Telephony, or IP Telephony and IP-based videoconferencing. For More Info About H.323 See Internet Telephony with H.323 From Microsoft MSDN.

 

 

Introduction to TAPI 3 Telephony:

TAPI version 3 is a COM-based API that merges classic and IP telephony. Possible applications range from simple voice calls over the Public Switched Telephone Network (PSTN) to multicast multimedia IP conferencing with quality of service (QOS).

There are four major components to TAPI 3:

- COM API
- TAPI Server
- Telephony Service Providers (TSPs)
- Media Stream Providers (MSPs) 

The API is implemented as a suite of Component Object Model (COM) objects. Moving TAPI to the object-oriented COM model allows developers to write TAPI-enabled applications in many languages, such as .NET, Java, or C++. Use of COM enables component upgrades of TAPI features.

The COM-based telephony API, TAPI 3.x, is available starting with Microsoft Windows X. TAPI 3.x provides greatly enhanced development tools for the modern world of communication programming, where a "call" may be a video stream on an IP-based network, and there is no phone set involved in the session.

Generally speaking, application writers will find TAPI 3.x provides better support to implement flexible communications controls, For More Info. See Telephony Integration and Conferencing From Microsoft MSDN.

 

Introduction to RTP:

 

RTP - Real Time Transport Protocol is Internet protocol for transmitting real-time data such as audio and video. RTP itself does not guarantee real-time delivery of data, but it does provide mechanisms for the sending and receiving applications to support streaming data. Typically, RTP runs on top of the UDP protocol, although the specification is general enough to support other transport protocols. to know how windows supports Real Time Communication See This RTCP API Article.

 

RTP Header:

 

RTP Header

 

Where:
V indicates the version of RTP used
P indicates the padding, a byte not used at bottom packet to reach the parity packet dimension
X is the presence of the header extension
CC field is the number of CSRC identifiers following the fixed header. CSRC field are used, for example, in conference case.
M is a marker bit
PT payload type

 

RTP Packet Implementation:

using System;using System.Collections.Generic;using System.Text;public class RTPpacket{//size of the RTP header:static int HEADER_SIZE = 12;//Fields that compose the RTP headerpublic int Version;public int Padding;public int Extension;public int CC;public int Marker;public int PayloadType;public int SequenceNumber;public int TimeStamp;public int Ssrc;//Bitstream of the RTP headerpublic byte[] header;//size of the RTP payloadpublic int payload_size;//Bitstream of the RTP payloadpublic byte[] payload;//--------------------------//Constructor of an RTPpacket object from header fields and payload bitstream//--------------------------public RTPpacket(int PType, int Framenb, int Time, byte[] data, int data_length){//fill by default header fields:Version = 2;Padding = 0;Extension = 0;CC = 0;Marker = 0;Ssrc = 0;//fill changing header fields:SequenceNumber = Framenb;TimeStamp = Time;PayloadType = PType;//build the header bistream://--------------------------header = new byte[HEADER_SIZE];//.............//TO COMPLETE//.............//fill the header array of byte with RTP header fields//header[0] = ...// ..... //fill the payload bitstream://--------------------------payload_size = data_length;payload = new byte[data_length];//fill payload array of byte from data (given in parameter of the constructor)//......// ! Do not forget to uncomment method printheader() below !}//--------------------------//Constructor of an RTPpacket object from the packet bistream //--------------------------public RTPpacket(byte[] packet, int packet_size){//fill default fields:Version = 2;Padding = 0;Extension = 0;CC = 0;Marker = 0;Ssrc = 0;//check if total packet size is lower than the header sizeif (packet_size >= HEADER_SIZE){//get the header bitsream:header = new byte[HEADER_SIZE];for (int i = 0; i < HEADER_SIZE; i++)header[i] = packet[i];//get the payload bitstream:payload_size = packet_size - HEADER_SIZE;payload = new byte[payload_size];for (int i = HEADER_SIZE; i < packet_size; i++)payload[i - HEADER_SIZE] = packet[i];//interpret the changing fields of the header:
PayloadType = header[1] & 127;
SequenceNumber = unsigned_int(header[3]) + 256 * unsigned_int(header[2]);
TimeStamp = unsigned_int(header[7]) + 256 * unsigned_int(header[6]) + 65536
* unsigned_int(header[5]) + 16777216 * unsigned_int(header[4]);
}}//--------------------------//getpayload: return the payload bistream of the RTPpacket and its size//--------------------------
public int getpayload(byte[] data){for (int i = 0; i < payload_size; i++)data[i] = payload[i];return (payload_size);}//--------------------------//getpayload_length: return the length of the payload//--------------------------public int getpayload_length(){return (payload_size);}//--------------------------//getlength: return the total length of the RTP packet//--------------------------public int getlength(){return (payload_size + HEADER_SIZE);}//--------------------------//getpacket: returns the packet bitstream and its length//--------------------------public int getpacket(byte[] packet){//construct the packet = header + payloadfor (int i = 0; i < HEADER_SIZE; i++)packet[i] = header[i];for (int i = 0; i < payload_size; i++)packet[i + HEADER_SIZE] = payload[i];//return total size of the packetreturn (payload_size + HEADER_SIZE);}//--------------------------//gettimestamp//--------------------------public int gettimestamp(){return (TimeStamp);}//--------------------------//getsequencenumber//--------------------------public int getsequencenumber(){return (SequenceNumber);}//--------------------------//getpayloadtype//--------------------------public int getpayloadtype(){return (PayloadType);} //--------------------------//print headers without the SSRC//--------------------------public void printheader(){//TO DO: uncomment/*for (int i=0; i < (HEADER_SIZE-4); i++){for (int j = 7; j>=0 ; j--)if (((1<<j) & header[i] ) != 0)System.out.print("1");elseSystem.out.print("0");System.out.print(" ");}System.out.println();*/}//return the unsigned value of 8-bit integer nbstatic int unsigned_int(int nb){if (nb >= 0)return (nb);elsereturn (256 + nb);}}

My Projects:

Example1: Voice Conferencing by Using OPEN H.323 Library

In This Example I Used the Openh323 ocx to create H.323 Voice Chat, its very easy to use

H323

H323Class h323 = new H323Class ();private void Form1_Load(object sender, System.EventArgs e){h323.AutoAnswer = true;h323.SilenceDetection = true;}private void button1_Click(object sender, System.EventArgs e){h323.RemoteHost = textBox1.Text;h323.Connect ();button1.Enabled = false;button2.Enabled = true;}private void button2_Click(object sender, System.EventArgs e){h323.Hangup();button2.Enabled = false;button1.Enabled = true;}private void button3_Click(object sender, System.EventArgs e){h323.Listen ();}private void checkBox1_CheckedChanged_1(object sender, System.EventArgs e){if (checkBox1.Checked){h323.SilenceDetection = true;}else h323.SilenceDetection = false;}private void checkBox2_CheckedChanged(object sender, System.EventArgs e){if (checkBox2.Checked){h323.AutoAnswer = true;}else h323.AutoAnswer = false;}private void checkBox3_CheckedChanged(object sender, System.EventArgs e){if (checkBox3.Checked){textBox2.Enabled = true;h323.UseGateway = true;h323.Gateway = textBox2.Text;}else{h323.UseGateway = false;textBox2.Enabled = false;}}

 

 

Example2: Voice Conferencing Using TAPI3.DLL

In This Example I Used the TAPI3 to Create an Audio Conferencing, For More Info. See Rendezvous Code Examples From Microsoft MSDN. 

TAPI 3 Voice Conference

tapi=new TAPIClass();tapi.Initialize();call_notify=new callnotification();call_notify.addtolist=new callnotification.listshow(this.status);
tapi.ITTAPIEventNotification_Event_Event+=new 
TAPI3Lib.ITTAPIEventNotification_EventEventHandler(call_notify.Event);tapi.EventFilter=(int)(T
API_EVENT.TE_CALLNOTIFICATION|TAPI_EVENT.TE_DIGITEVENT|TAPI_EVENT.TE_PHONEEVENT|TAPI_EVENT.TE_CALLSTATE|TAPI_EVENT.TE_GENERATEEVENT|TAPI_EVENT.TE_GATHERDIGITS|TAPI_EVENT.TE_REQUEST); ITCollection collec;ITAddress address;ITMediaSupport support;ITAddressCapabilities capability;collec=(ITCollection)tapi.Addresses;foreach(ITAddress addr in collec ){found=false;address=addr;support=(ITMediaSupport)address;capability=(ITAddressCapabilities)address;if(support.QueryMediaType(TapiConstants.TAPIMEDIATYPE_AUDIO)){found=true;}capability=null;support=null;address=null;if(found==true){if(addr.AddressName.ToUpper()=="H323 LINE"){call_address=addr;}//break;}}////
registration 
part
registration=tapi.RegisterCallNotifications(call_address,true,true,
TapiConstants.
TAPIMEDIATYPE_AUDIO,1);
private void button1
_Click(object sender, System.EventArgs e){string addr=textBox1.Text;
MessageBox.Show("
Dialing to "+addr+" ...");
call_control=call_address.CreateCall
(addr,TapiConstants.LINEADDRESSTYPE_IPADDRESS,
TapiConstants.TAPIMEDIATYPE_AUDIO | TapiConstants.TAPIMEDIATYPE_VIDEO);button1.Enabled=false;
IEnumStream enum_
stream;ITStreamControl pstream_control;pstream_control=(ITStreamControl)call_control;pstream_control.EnumerateStreams(out enum_stream);ITStream p_stream;uint a11=0;enum_stream.Next(1,out p_stream,ref a11);int imedia;
imedia=p_stream.MediaType;TERMINAL_DIRECTION dir;dir=p_stream.Direction;ITTerminal termi,termi1;ITTerminalSupport term_support=(ITTerminalSupport)call_address;termi=term_support.GetDefaultStaticTerminal(imedia,dir);p_stream.SelectTerminal(termi);enum_stream.Next(1,out p_stream,ref a11);
termi1=term_support.
GetDefaultStaticTerminal
(imedia,TERMINAL
_DIRECTION.TD_
CAPTURE);
p_stream.SelectTerminal(termi1);
call_control.Connect(false);}private void button2_Click(object sender, System.EventArgs e){call_control.Disconnect(DISCONNECT_CODE.DC_NORMAL);button1.Enabled=true;}

Example 3 and 4: Peer-to-Peer Video Voice Chat

In This Example I Used the Wave Library to capture and Send Voice throw network and I used the Stream Classes to Transfer captured Video Images from camera.

Peer-Peer Conerence System

#region Voice_In()private void Voice_In(){byte[] br;r.Bind(new IPEndPoint(IPAddress.Any, int.Parse(text_ReceiveingPORT.Text)));while (true){br = new byte[16384];r.Receive(br);m_Fifo.Write(br, 0, br.Length);}}#endregion#region Voice_Out()private void Voice_Out(IntPtr data, int size){//for Recorderif (m_RecBuffer == null || m_RecBuffer.Length < size)m_RecBuffer = new byte[size];System.Runtime.
InteropServices.Marshal.Copy(data, m_RecBuffer, 0, size);//Microphone ==> data ==> m_RecBuffer ==> m_Fifor.SendTo(m_RecBuffer, new IPEndPoint(IPAddress.Parse(text_IP.Text), 
int.Parse(text_SendingPort.Text)));} 
#endregionprivate WaveOutPlayer m_Player;private WaveInRecorder m_Recorder;private FifoStream m_Fifo = new FifoStream();private Socket r;private Thread t;private bool connected = false;private byte[] m_PlayBuffer;private byte[] m_RecBuffer;TcpClient myclient;MemoryStream ms;NetworkStream myns;BinaryWriter mysw;Thread myth;TcpListener mytcpl;Socket mysocket;NetworkStream ns;private void Form1_Load(object sender, System.EventArgs e)
{
myth= new Thread (new System.Threading .ThreadStart(Start_Receiving_Video_Conference)); 
// Start Thread 
Session
myth.Start (); // Start
Receiveing Camera
}
private void Start_Receiving_Video_Conference(){try{// Open The Portmytcpl = new TcpListener (int.Parse(text_Camera_rec_port.Text));mytcpl.Start (); // Start Listening on That Portmysocket = mytcpl.AcceptSocket (); // Accept Any Request From Client and Start a Sessionns = new NetworkStream (mysocket); // Receives The Binary Data From PortpictureBox2.Image = Image.FromStream(ns);mytcpl.Stop(); // Close TCP Sessionif (mysocket.Connected ==true) // Looping While Connected to Receive Another Message{while (true){Start_Receiving_Video_Conference (); // Back to First Method}}myns.Flush();}catch (Exception){}}private void Start_Sending_Video_Conference(string remote_IP,int port_number){try{ms = new MemoryStream();// Store it in Binary Array as StreampictureBox1.Image.Save(ms,System.Drawing.Imaging.ImageFormat.Jpeg);byte[] arrImage = ms.GetBuffer();myclient = new TcpClient (remote_IP,port_number);//Connecting with servermyns = myclient.GetStream ();mysw = new BinaryWriter (myns);mysw.Write(arrImage);//send the stream to above addressms.Flush();mysw.Flush();myns.Flush();ms.Close();mysw.Close ();myns.Close ();myclient.Close ();}
catch (Exception ex)
{ Capturing.Enabled = false;
 
MessageBox.Show(ex.Message,"Video Conference Error Message",
MessageBoxButtons.OK,
MessageBoxIcon.Error);}
}
private void Start() { Stop(); try { WaveFormat fmt = new WaveFormat
(44100, 16, 2);
m_Player = new WaveOutPlayer(-1, fmt, 16384, 3, new 
BufferFillEventHandler(Filler));
m_Recorder = new WaveInRecorder
(-1, fmt, 16384, 3, new BufferDoneEventHandler(Voice_Out));
}
 
catch
{Stop();throw;}}private void Stop(){if (m_Player != null)try{m_Player.Dispose();}finally{m_Player = null;}if (m_Recorder != null)try{m_Recorder.Dispose();}finally{m_Recorder = null;}m_Fifo.Flush(); // clear all pending data}private void Filler(IntPtr data, int size){if (m_PlayBuffer == null || m_PlayBuffer.Length < size)m_PlayBuffer = new byte[size];if (m_Fifo.Length >= size)m_Fifo.Read(m_PlayBuffer, 0, size);elsefor (int i = 0; i < m_PlayBuffer.Length; i++)m_PlayBuffer[i] = 0;System.Runtime.InteropServices.Marshal.Copy(m_PlayBuffer, 0, data, size);// m_Fifo ==> m_PlayBuffer==> data ==> Speakers}private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e){try{myth.Abort ();mytcpl.Stop ();ns.Flush();ns.Close();t.Abort();r.Close();Stop();myclient.Close ();ms.Close ();myns.Close ();mysw.Close (); }catch(Exception){}}private void button2_Click(object sender, System.EventArgs e){Stop();}private void button1_Click(object sender, System.EventArgs e){if (connected == false){t.Start();connected = true;}Start();}private void button4_Click(object sender, System.EventArgs e){this.WebCamCapture.TimeToCapture_milliseconds = 1;this.WebCamCapture.Start(0);Capturing.Enabled = true;}private void button3_Click(object sender, System.EventArgs e){this.WebCamCapture.Stop();Capturing.Enabled = false;}private void Capturing_Tick(object sender, System.EventArgs e){
Start_Sending_Video_Conference
(text_IP.Text,int.Parse(text_Camera_send_port.Text));}
private void WebCamCapture_ImageCaptured(object source, WebCam_Capture
.WebcamEventArgs e)
{this.pictureBox1.Image = e.WebCamImage;}

See: http://www.fadidotnet.org/online_book/Network_Programming_online.htm and http://www.fadidotnet.org/vb/forumdisplay.php?f=8 For More Info and Examples

 

 

 

原创粉丝点击