前三篇已實現文字聊天、共享白板、語音聊天功能。本篇將完成視訊會話的關鍵技術實作。
Silverlight 4 內建攝影機與麥克風存取 API,但 WPF 4 缺乏對應內建控制項。經搜尋,在 CodePlex 找到開源專案 WebCam control for WPF,作為本實作的攝影機資料來源。

流程與語音聊天類似:客戶端捕獲影像 → UDP 傳送至 WCF 服務 → 服務轉發給目標客戶端 → 客戶端播放。差別在於資料來源為攝影機而非麥克風。
新增視窗 WebcamPlayerForm,左右分欄顯示本地與遠端影像:

public partial class WebcamPlayerForm : Window
{
private IPEndPoint _serverEndPoint;
private UdpClient _socket;
public WebcamPlayerForm(IPEndPoint serverEndpoint, string caller, string callee)
{
InitializeComponent();
_serverEndPoint = serverEndpoint;
_socket = new UdpClient(0); // 隨機可用埠
// 兩個 DispatcherTimer 分別處理捕獲與播放
var captureTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
captureTimer.Tick += CaptureVideo;
captureTimer.Start();
var playTimer = new DispatcherTimer { Interval = TimeSpan.FromMilliseconds(1000) };
playTimer.Tick += PlayVideo;
playTimer.Start();
}
private void CaptureVideo(object sender, EventArgs e)
{
try
{
if (webcamPlayer.CurrentBitmap != null)
{
byte[] bytes = ConvertImageSourceToByteArray(webcamPlayer.CurrentBitmap);
_socket.Send(bytes, bytes.Length, _serverEndPoint);
}
}
catch { }
}
private void PlayVideo(object sender, EventArgs e)
{
try
{
lock (_socket)
{
if (_socket.Available > 0)
{
IPEndPoint ep = new IPEndPoint(IPAddress.Any, 0);
byte[] received = _socket.Receive(ref ep);
image1.Source = ConvertByteArrayToImageSource(received);
}
}
}
catch { }
}
// ImageSource ↔ byte[] 轉換方法(JPEG 編碼/解碼)
public byte[] ConvertImageSourceToByteArray(ImageSource image) { ... }
public ImageSource ConvertByteArrayToImageSource(byte[] bytes) { ... }
}
public class UdpVideoServer
{
private Thread _listenerThread;
private List<IPEndPoint> _users = new List<IPEndPoint>();
private UdpClient _udpSender = new UdpClient();
public UdpClient UdpListener { get; set; }
public IPAddress ServerAddress { get; set; }
public void Start()
{
UdpListener = new UdpClient(0);
_listenerThread = new Thread(Listen) { IsBackground = true };
_listenerThread.Start();
}
private void Listen()
{
while (true)
{
IPEndPoint sender = new IPEndPoint(IPAddress.Any, 0);
byte[] received = UdpListener.Receive(ref sender);
if (!_users.Contains(sender)) _users.Add(sender);
foreach (var ep in _users)
{
if (!ep.Equals(sender))
_udpSender.Send(received, received.Length, ep);
}
}
}
}



單機雙開測試畫面僅單側顯示,雙筆電實測效果良好。核心技術棧:WCF 雙工通訊協商連線、UDP 低延遲影像傳輸、開源 WebCam 控制項、JPEG 影像編解碼。完整程式碼後續將上傳 CodePlex。