前言:

由于對戰視訊采用控制台程式,并沒有在伺服器運作,是以線上示範版本裡一進入顯示是顯示“未連結”的提示。

1:由于silverlight不支援點對點方式傳輸,是以隻能通過伺服器中轉方式進行。
2:視訊的傳輸是圖檔位元組,是以壓縮圖檔是相當必要的。
3:中間的服務選什麼?一開始我是在嘗試使用wcf的tcp方式,後來折騰配置檔案太痛苦,直接轉使用socket通訊,一來有性能優勢,二來減少折騰。

1:用戶端打開視訊
2:用戶端向遠端socket注冊[按規則定好的]編号[服務端根據編号查要轉發的對象]
3:服務端接收編号并注冊,收集一系列編号清單。
4:用戶端發送視訊
5:服務端接收視訊,并根據規則查找另一個編号,将視訊位元組轉發
6:另一個用戶端接收視訊并顯示

1:如何打開視訊
在siverlight中打開視訊相當的簡單,都有注釋,就不多解說了
代碼如下:

private void btnstart_click(object sender, routedeventargs e)
{
videocapturedevice device = capturedeviceconfiguration.getdefaultvideocapturedevice();//擷取系統預設視訊裝置
if (device == null)
{
messagebox.show("沒有檢測到裝置!");
return;
}
if (capturedeviceconfiguration.requestdeviceaccess())//請求裝置
capturesource source = new capturesource()//資料源
{
videocapturedevice = device//設定屬性,将資料源綁定到視訊
};
videobrush brush = new videobrush();//視訊刷子
brush.setsource(source);//視訊刷子從視訊源擷取視訊
source.start();
myvideo.fill = brush;//最後填充rectangle [myvideo隻是一個普通rectangle]
}

界面rectangle代碼:
<canvas width="160" height="160" background="red" margin="22,109,518,531" name="canvideo">
<rectangle height="160" name="myvideo" stroke="black" strokethickness="1" width="160" canvas.left="0" canvas.top="0" />
</canvas>
運作後我們看下效果,[這裡用了本地的虛拟視訊,開了3個浏覽器并排截了圖,第4張是不一樣的哦],中間提示确認是否打開視訊就不截圖了:
2:silverlight如何使用socket進行通訊
由于silverlight一般是不允許跨域通訊,是以,其socket通訊也要比普通的socket通訊麻煩一小點,不過這麻煩的小點隻表現在服務端。
下面進行代碼解析:以下代碼将一步扣一步,具體的連環扣如下:建立連結-》注冊編号-》開新線程待接收視訊-》收到視訊處理顯示。
2.1:與遠端建立連結:

socket videosocket;//全局定義一個socket
private void btnsocketconn_click(object sender, routedeventargs e)
if (videosocket == null)//執行個體化socket
videosocket = new socket(addressfamily.internetwork, sockettype.stream, protocoltype.tcp);
socketasynceventargs socketevent=new socketasynceventargs()//通訊參數
remoteendpoint=new ipendpoint(ipaddress.parse("192.168.0.48"),4505),//設定連接配接的ip與端口
};
socketevent.completed += new eventhandler<socketasynceventargs>(socketevent_completed);
videosocket.connectasync(socketevent);//異步連結到遠端
void socketevent_completed(object sender, socketasynceventargs e)//連結完成後
//這裡要寫點什麼呢?

2.2:注冊編号[這裡的規則是“房間号+棋手顔色值”]

void socketevent_completed(object sender, socketasynceventargs e)
if (e.socketerror == socketerror.success)
byte[] buffer = system.text.encoding.utf8.getbytes("11");//我的編号,11=1房間+紅色玩家1,對應的就是12=1房間+黑色玩家2
socketasynceventargs dataevent = new socketasynceventargs();
dataevent.setbuffer(buffer, 0, buffer.length);
dataevent.completed += new eventhandler<socketasynceventargs>(dataevent_completed);
videosocket.sendasync(dataevent);//發送号碼到服務端注冊
void dataevent_completed(object sender, socketasynceventargs e)
{
//号碼發送過去了,接下這裡幹點什麼呢?

2.3:開新線程,等待接收對方視訊

void dataevent_completed(object sender, socketasynceventargs e)
system.threading.thread thread = new system.threading.thread(new system.threading.threadstart(receive));//開啟線程
thread.start();
void receive()//接收視訊處理
byte[] buffer = new byte[1024 * 1024];
while (true)
socketasynceventargs receiveevent = new socketasynceventargs();
receiveevent.setbuffer(buffer, 0, buffer.length);
receiveevent.completed += new eventhandler<socketasynceventargs>(receiveevent_completed);
videosocket.receiveasync(receiveevent);
system.threading.thread.sleep(50);//小小休眠一下,不要幹活太累
void receiveevent_completed(object sender, socketasynceventargs e)
//如果收到視訊,我們要怎麼處理呢?

2.4:将視訊顯示出來,需要用主線程來操作

synchronizationcontext syn=synchronizationcontext.current;//擷取目前主線程
byte[] data=e.buffer;
if (data[0]>0)
{
syn.post(setvideo, data);//由于新線程無法對控件進行操作,需要主線程來調用
}
}
void setvideo(object data)//設定視訊
memorystream stream=null;
writeablebitmap img=null;
try
stream = new memorystream(data as byte[]);
img = new writeablebitmap(160, 160);
img.setsource(stream);
imgvideo.source = img;//直接賦下值,就設定好了。
catch
finally
if (stream != null)
stream.close();
}
if (img != null)
img = null;

上面的imgvideo為:
<image height="160" horizontalalignment="left" margin="207,109,0,0" name="imgvideo" stretch="fill" verticalalignment="top" width="160" />
至此,我們連續完成了“打開視訊—》注冊—》等待接收-》接收時開主線程顯示”,我們提前看一下完成後接收時的效果圖:
紅色塊是顯示視訊的區域,目前圖檔說明左側沒有開啟視訊,隻是開了接收,右側開了視訊,并發送視訊。
下面再順路看一下開啟的服務端中轉socket的運作:
ok,本節就先到此,下節我們再講“視訊圖檔的壓縮與發送”+服務端進行中轉流程
最後:謝謝大家對本系列的喜歡,謝謝支援~
ps:傳說點一下推薦會有10個園豆,喜歡麻煩點一下“推薦”,thank you very much!!
版權聲明:本文原創發表于部落格園,作者為路過秋天,原文連結:
http://www.cnblogs.com/cyq1162/archive/2010/12/01/1893583.html