PlayCtrl.dll、HCNetSDK.dll 等非受控 DLL。IObjectSafety 介面讓 IE 信任載入。.cab 或 .msi。<object codebase="Setup.exe"> 自動下載安裝。PlayM4_GetPort(ref nPort) // 取得空閒播放通道
PlayM4_SetStreamOpenMode(nPort, 0) // 設定串流模式
PlayM4_OpenStream(nPort, headBuf, 40, 1024*1024) // 開啟串流 (頭部 40 bytes 關鍵)
PlayM4_SetDisplayBuf(nPort, 15) // 設定顯示緩衝幀數
PlayM4_Play(nPort, pictureBox.Handle) // 開始渲染
PlayM4_InputData(nPort, buf, len) // 送入視訊資料
PlayM4_Stop / CloseStream / FreePort // 停止釋放
[Guid("A4277AC0-7F3F-4950-9130-27025D6E18F8")]
public partial class Player : UserControl, IObjectSafety
{
int _port = -1;
Socket _socket;
Thread _recvThread;
bool _isPlaying;
// JS 呼叫:初始化連線
public void InitPlay(string ip, int port)
{
CloseAll();
var ep = new IPEndPoint(IPAddress.Parse(ip), port);
_socket = new Socket(ep.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_recvThread = new Thread(() => {
_socket.Connect(ep);
byte[] buf = new byte[262144];
while (true)
{
int len = _socket.Receive(buf);
var type = len == 40 ? StreamType.Head : StreamType.Body;
ProcessData(buf, (uint)len, type);
Thread.Sleep(100);
}
}) { IsBackground = true };
}
// JS 呼叫:開始播放
public bool ShowVideo() { _recvThread.Start(); return true; }
// 頁面關閉時釋放
public void PageClose() { /* 關閉 Socket、SDK 資源 */ }
private void ProcessData(byte[] buf, uint len, StreamType type)
{
if (type == StreamType.Head)
{
// 頭部 40 bytes 初始化 SDK
PlayM4_GetPort(ref _port);
PlayM4_SetStreamOpenMode(_port, 0);
PlayM4_OpenStream(_port, buf, len, 1024*1024);
PlayM4_SetDisplayBuf(_port, 15);
this.Invoke(() => PlayM4_Play(_port, pictureBox1.Handle));
_isPlaying = true;
}
else if (_isPlaying)
{
PlayM4_InputData(_port, buf, len);
}
}
// IObjectSafety 實作...
enum StreamType { Head, Body }
}
<object id="player" classid="clsid:A4277AC0-7F3F-4950-9130-27025D6E18F8"
width="600" height="400" codebase="Setup.exe"></object>
<script>
var channel = 1;
window.onbeforeunload = function() { player.PageClose(); getServer("unload"); };
function getServer(op) {
var xhr = new XMLHttpRequest();
xhr.open("GET", "ServerHandler.ashx?channel=" + channel + "&operate=" + op, false);
xhr.send();
return xhr.responseText; // 回傳 "IP:Port:Count"
}
function Show(ch) {
getServer("unload"); // 釋放前一通道
channel = ch;
var info = getServer("load").split(':'); // 取得中轉伺服器 IP:Port
player.PageClose();
player.InitPlay(info[0], parseInt(info[1]));
player.ShowVideo();
document.getElementById("but"+ch).disabled = true;
}
// 定時心跳保持 Session
setInterval(function() { getServer("refresh"); }, 3000);
</script>
<a href="#" onclick="Show(1)" id="but1">視頻 1</a>
<a href="#" onclick="Show(2)" id="but2">視頻 2</a>
Invoke 回 UI 執行緒呼叫 SDK 渲染。codebase="Setup.exe" 讓 IE 自動下載安裝 ActiveX;需簽名並加入信任站台。至此三篇系列完整實現:中轉伺服器突破 6 連線限制,Web ActiveX 播放器提供無縫瀏覽體驗,JS 控制介面支援多通道切換與心跳保活。