其实严格来讲,这个实现并非真正意义上的视频通信,既不是P2P的,也没有很高的性能,因为基本上是两个客户端同时往服务器上传递视频信息,然后由服务器进行中转到对方。
重点在于两点
这边是单向的客户端定时向服务器传递带聊天标识的数据流:
[DataContract]
public class UserVideo
{
[DataMember]
public string UserName { get ; set ; }
[DataMember]
public string PartnerName { set ; get ; }
[DataMember]
public byte [] VideoByte { set ; get ; }
}
public class UserVideo
{
[DataMember]
public string UserName { get ; set ; }
[DataMember]
public string PartnerName { set ; get ; }
[DataMember]
public byte [] VideoByte { set ; get ; }
}
服务契约只有两个,一个是用来存储视频流,一个是用来提供视频流的
[ServiceContract]
public interface IChatService
{
[OperationContract]
void SendVideo(UserVideo userVideo);
[OperationContract]
List < UserVideo > GetVideos( string userName, string partnerName);
}
public interface IChatService
{
[OperationContract]
void SendVideo(UserVideo userVideo);
[OperationContract]
List < UserVideo > GetVideos( string userName, string partnerName);
}
public
class
ChatService : IChatService
{
private static List < UserVideo > listVideos = new List < UserVideo > ();
public void SendVideo(UserVideo userVideo)
{
listVideos.Add(userVideo);
}
public List < UserVideo > GetVideos( string userName, string partnerName)
{
var list = listVideos.Where(m => m.UserName == userName && m.PartnerName == partnerName).ToList();
listVideos.RemoveAll(m => m.PartnerName == partnerName && m.UserName == userName);
return list;
}
}
{
private static List < UserVideo > listVideos = new List < UserVideo > ();
public void SendVideo(UserVideo userVideo)
{
listVideos.Add(userVideo);
}
public List < UserVideo > GetVideos( string userName, string partnerName)
{
var list = listVideos.Where(m => m.UserName == userName && m.PartnerName == partnerName).ToList();
listVideos.RemoveAll(m => m.PartnerName == partnerName && m.UserName == userName);
return list;
}
}
接下来是host方法
最后是启动服务进行监听
public
class
Program
{
static void Main( string [] args)
{
MyHost.open();
System.Console.WriteLine( " 服务已经启动... 敲任意键停止服务 " );
System.Console.ReadLine();
MyHost.Close();
}
}
客户端方法:
开始视频播放
this .btnStartVideo.Click += (o, ev) =>
{
if (source != null )
{
source.Stop();
source.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
VideoBrush vBrush = new VideoBrush();
vBrush.SetSource(source);
this .rectangleUser.Fill = vBrush;
if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
{
source.Start();
}
}
};
向服务器发送数据流
this .btnSendVideo.Click += (o, ev) =>
{
timerForSend = new System.Windows.Threading.dispatcherTimer();
timerForSend.Interval = new TimeSpan( 0 , 0 , 150 );
timerForSend.Tick += (o1, e1) => {
proxy = new ChatServiceClient();
WriteableBitmap bmp = new WriteableBitmap( this .rectangleUser, null );
MemoryStream ms = new MemoryStream();
EncodeJpeg(bmp, ms);
UserVideo userVideo = new UserVideo();
userVideo.PartnerName = this .Partner;
userVideo.UserName = this .User;
userVideo.VideoByte = ms.GetBuffer();
proxy.SendVideoCompleted += (o2, e2) => { };
proxy.SendVideoAsync(userVideo);
};
timerForSend.Start();
};
{
static void Main( string [] args)
{
MyHost.open();
System.Console.WriteLine( " 服务已经启动... 敲任意键停止服务 " );
System.Console.ReadLine();
MyHost.Close();
}
}
客户端方法:
开始视频播放
this .btnStartVideo.Click += (o, ev) =>
{
if (source != null )
{
source.Stop();
source.VideoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
VideoBrush vBrush = new VideoBrush();
vBrush.SetSource(source);
this .rectangleUser.Fill = vBrush;
if (CaptureDeviceConfiguration.AllowedDeviceAccess || CaptureDeviceConfiguration.RequestDeviceAccess())
{
source.Start();
}
}
};
向服务器发送数据流
this .btnSendVideo.Click += (o, ev) =>
{
timerForSend = new System.Windows.Threading.dispatcherTimer();
timerForSend.Interval = new TimeSpan( 0 , 0 , 150 );
timerForSend.Tick += (o1, e1) => {
proxy = new ChatServiceClient();
WriteableBitmap bmp = new WriteableBitmap( this .rectangleUser, null );
MemoryStream ms = new MemoryStream();
EncodeJpeg(bmp, ms);
UserVideo userVideo = new UserVideo();
userVideo.PartnerName = this .Partner;
userVideo.UserName = this .User;
userVideo.VideoByte = ms.GetBuffer();
proxy.SendVideoCompleted += (o2, e2) => { };
proxy.SendVideoAsync(userVideo);
};
timerForSend.Start();
};
从服务期上取得数据流
void
ReceiveVideo()
{
timerForReceive = new System.Windows.Threading.dispatcherTimer();
timerForReceive.Interval = new TimeSpan( 0 , 100 );
timerForReceive.Tick += (o, e) => {
proxy = new ChatServiceClient();
proxy.GetVideosCompleted += (se, ev) =>
{
if (ev.Error == null )
{
foreach (ChatService.UserVideo video in ev.Result)
{
this .imagePartner.dispatcher.BeginInvoke(() => {
MemoryStream ms = new MemoryStream(video.VideoByte);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(ms);
imagePartner.source = bitmap;
ms.Close();
});
}
}
};
proxy.GetVideosAsync(User, Partner);
};
timerForReceive.Start();
}
{
timerForReceive = new System.Windows.Threading.dispatcherTimer();
timerForReceive.Interval = new TimeSpan( 0 , 100 );
timerForReceive.Tick += (o, e) => {
proxy = new ChatServiceClient();
proxy.GetVideosCompleted += (se, ev) =>
{
if (ev.Error == null )
{
foreach (ChatService.UserVideo video in ev.Result)
{
this .imagePartner.dispatcher.BeginInvoke(() => {
MemoryStream ms = new MemoryStream(video.VideoByte);
BitmapImage bitmap = new BitmapImage();
bitmap.SetSource(ms);
imagePartner.source = bitmap;
ms.Close();
});
}
}
};
proxy.GetVideosAsync(User, Partner);
};
timerForReceive.Start();
}
单工模式的缺点显而易见,请求--》答复比较耗时,我们下一步将会改造成双工模式的TCP通信。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。