核心邏輯說明
StartCap/StopCap 按鈕事件分別寫入檔案頭與結束碼 (0x00000002),關鍵在 _write 函式。
- 回調函式
StreamDirectReadCallback 邊寫入記憶體邊寫入檔案,輸出 .264 檔。frameType == PktSysHeader 表示檔案頭,僅出現一次。
gFileHandle 為檔案指標陣列,檔案開啟後回調持續寫入資料。
C# 實作程式碼
// 儲存檔案頭
byte[] FileHeader;
int FileHeaderLen;
volatile int CaptureState;
private void btnStart_Click(object sender, EventArgs e)
{
using (FileStream fs = new FileStream(@"C:\hik.264", FileMode.Create))
{
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(FileHeader);
bw.Flush();
}
CaptureState = 1;
}
uint endCode = 0x00000002;
private void btnStop_Click(object sender, EventArgs e)
{
CaptureState = 0;
using (FileStream fs = new FileStream(@"C:\hik.264", FileMode.Append))
{
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(endCode);
}
}
public int STREAM_DIRECT_READ_CALLBACK1(int channelNum, IntPtr DataBuf, int Length, FrameType_t frameType, IntPtr context)
{
int status = 0;
if (frameType > 0)
{
if (frameType == FrameType_t.PktSysHeader)
{
FileHeader = new byte[Length];
Marshal.Copy(DataBuf, FileHeader, 0, Length);
FileHeaderLen = Length;
}
if (frameType == FrameType_t.PktIFrames || frameType == FrameType_t.PktSubIFrames)
status = 1;
else
status = 0;
if (frameType == FrameType_t.PktMotionDetection || frameType == FrameType_t.PktOrigImage)
return 0;
}
if (Length == 0) return 0;
if (frameType == FrameType_t.PktAudioFrames)
{
WriterVideoCapture(Length, DataBuf);
HikServer.MP4_ServerWriteDataEx(channelNum, DataBuf, Length, (int)frameType, status, 0);
}
else if (frameType == FrameType_t.PktSubIFrames || frameType == FrameType_t.PktSubPFrames ||
frameType == FrameType_t.PktSubBBPFrames || frameType == FrameType_t.PktSubSysHeader)
{
HikServer.MP4_ServerWriteDataEx(channelNum, DataBuf, Length, (int)frameType, status, 1);
}
else
{
WriterVideoCapture(Length, DataBuf);
HikServer.MP4_ServerWriteDataEx(channelNum, DataBuf, Length, (int)frameType, status, 0);
}
return 0;
}
private void WriterVideoCapture(int length, IntPtr dataBuf)
{
if (CaptureState == 1)
{
using (FileStream fs = new FileStream(@"C:\hik.264", FileMode.Append))
{
BinaryWriter bw = new BinaryWriter(fs);
byte[] byteBuf = new byte[length];
Marshal.Copy(dataBuf, byteBuf, 0, length);
bw.Write(byteBuf);
bw.Flush();
}
}
}