I.はじめに
ビデオ監視業界の分野では、Haikangがボスにふさわしく、長年最初の王位を占めています。最近、ビデオ監視システムをHaikang SDKのカーネルに変更する必要があるため、SDKのユーザーマニュアルとSDKに関連することを慎重に調べましたドキュメントとファイルは公式ウェブサイトから直接ダウンロードでき、頻繁に更新されます。現在、WindowsとLinuxのSDKが提供されています。WinのSDKはまだ迅速かつ完全に更新されていますが、Linuxのsdkは文句を言われる必要があります。非常に古いものです。非常に古いバージョンで、パッケージファイルを見ないでください。非常に新しいです。実際、内部のコンテンツは非常に古いです。なぜオフィシャルがLinuxでSDKも更新しないのかわかりません。おそらくLinuxへの需要はそれほど高くないかもしれませんが、国内生産です。 Linuxの活発な進歩により、Linuxは近い将来徐々に改善されると推定されていますが、おそらく当局はすでにこの計画を立てています。また、Linuxの開発キットは、当局によって内部的に使用される新しいものであると個人的に推測されています。はい、Linuxでさまざまなクライアントを自分で作成することを計画している可能性があります。
公式のSDKマニュアルはまだ非常に詳細であり、VC / JAVA / C#などの言語でデモコードも提供しました。これは賞賛に値します。製品は引き続き売れ続けます。根深い理由があるはずです。製品自体の優れた品質に加えて、周辺のサービスも維持する必要があります。開発にQtを使用することに慣れているため、VCデモを直接コンパイルして1ステップで実行しました。インターフェイスは比較的シンプルで見苦しいですが、必要な機能のほとんどはまだ使用でき、多くのボタンが表示されない場合があります。それが何であれ、私たちが欲しいのは関数です。対応するメソッド関数の使用方法を示します。インターフェイスの美化については、プロのUI女の子に渡してみてください。UI女の子がいない場合は、自分でいくつかのqssスタイルシートを入手してください。それをやり遂げる、インターフェイスの美化のコアは主に2つのポイントです:レイアウト+色。
公式は、一般的に使用されているデバイスのすべてのSDKをパッケージ化しました。1つのヘッダーファイルは大きく、ヘッダーファイルHCNetSDK.hは47,451行です。私の考えでは、ユーザーの便宜のために、1つのヘッダーファイルにそれらを配置します。内部では、実際、これらのSDKはカメラだけでなく、NVR / CVRやその他のデバイスもサポートしています。互換性と価格が優れています。同じSDKを使用できます。公式は、異なるカテゴリの1つのカテゴリを統合することです。一般的な顔認識、赤外線温度測定など、ハードウェア製品間のSDKにはまだいくつかの違いがあります。これらはすべて新しく追加されたハードウェアと機能ですが、全体的なインターフェースと使用プロセスは通常同じです。
デコードプロセスフロー:
- NET_DVR_Initを呼び出してSDKを初期化し、プロジェクトで一度だけ初期化する必要があります。
- NET_DVR_SetConnectTime、NET_DVR_SetReconnectを呼び出して、接続時間と再接続時間を設定します。
- NET_DVR_PREVIEWINFO構造データを入力してログインします。
- NET_DVR_Login_V30を呼び出して、デバイスにログインします。
- NET_DVR_RealPlay_V40を呼び出してビデオを再生します。
- NET_DVR_StopRealPlayを呼び出して、再生を停止します。
- NET_DVR_Logoutを呼び出して、デバイスからログアウトします。
2.機能
- ビデオストリームとローカルMP4ファイルの再生をサポートします。
- ハンドルとコールバックの2つのモードをサポートします。
- メインインターフェイスにスタックされていないマルチスレッドディスプレイイメージ。
- Webカメラを自動的に再接続します。
- 境界線のサイズ、オフセット、境界線の色を設定できます。
- OSDラベルを描画するかどうか、つまりラベルテキストまたは画像とラベル位置を描画するかどうかを設定できます。
- 2つのOSD位置とスタイルを設定できます。
- ファイルに保存するかどうか、ファイル名を設定できます。
- ファイルを直接haikangwidgetコントロールにドラッグして再生できます。
- h264 / h265ビデオストリームをサポートします。
- 再生を一時停止して再開できます。
- 単一のビデオファイルのストレージとビデオファイルのタイミングストレージをサポートします。
- 上部のフローティングバーをカスタマイズし、クリック信号通知を送信して、それを有効にするかどうかを設定します。
- 画面のストレッチ塗りつぶしまたは同じ比率の塗りつぶしを設定できます。
- デコードを速度優先、品質優先、およびイコライゼーション処理に設定できます。
- ビデオのスクリーンショット(元の写真)とスクリーンショット(ビデオ形式)を撮ることができます。
- ビデオファイルはMP4ファイルとして保存されます。
- フォーカス制御、パン/チルト制御をサポートします。
- カスタマイズ可能な機能。
3、レンダリング
4、関連サイト
- 国内サイト:https : //gitee.com/feiyangqingyun/QWidgetDemo
- 国際サイト:https : //github.com/feiyangqingyun/QWidgetDemo
- 個人ホームページ:https : //blog.csdn.net/feiyangqingyun
- Zhihuホームページ:https ://www.zhihu.com/people/feiyangqingyun/
- エクスペリエンスアドレス:https : //blog.csdn.net/feiyangqingyun/article/details/97565652
5、コアコード
bool HaiKangThread::playRtsp()
{
bool ok = false;
QString ip, userName, userPwd;
int port, streamType;
getInfo(ip, port, streamType, userName, userPwd);
//登录设备
NET_DVR_DEVICEINFO_V30 deviceInfo;
long userid = NET_DVR_Login_V30(ip.toUtf8().data(), port, userName.toUtf8().data(), userPwd.toUtf8().data(), &deviceInfo);
if (userid >= 0) {
qDebug() << TIMEMS << "登录海康设备成功" << userid << deviceInfo.sSerialNumber;
//这里还需要拿到视频流的宽高
//qDebug() << TIMEMS << url << "videoWidth:" << videoWidth << "videoHeight:" << videoHeight;
//以下参数具体见对应头文件说明
NET_DVR_PREVIEWINFO previewInfo;
previewInfo.lChannel = 1;
previewInfo.dwStreamType = streamType;
previewInfo.dwLinkMode = (transport == "tcp" ? 0 : 1);
previewInfo.bBlocked = 0;
previewInfo.byProtoType = 1;
previewInfo.byPreviewMode = 0;
previewInfo.dwDisplayBufNum = 15;
//回调则可以拿到音视频数据,否则就直接句柄播放
if (callback) {
hand = NET_DVR_RealPlay_V40(userid, &previewInfo, RealDataCallBack, this);
} else {
previewInfo.hPlayWnd = (HWND)playWidget->winId();
hand = NET_DVR_RealPlay_V40(userid, &previewInfo, NULL, NULL);
}
if (hand >= 0) {
ok = true;
qDebug() << TIMEMS << "打开视频数据成功" << url << "码流" << streamType;
} else {
qDebug() << TIMEMS << "打开视频数据失败" << url << NET_DVR_GetLastError();
}
} else {
qDebug() << TIMEMS << "登录海康设备失败" << NET_DVR_GetLastError();
}
return ok;
}
bool HaiKangThread::playLocal()
{
//转码以便支持中文路径
QTextCodec *codec = QTextCodec::codecForName("gb2312");
QByteArray data = codec->fromUnicode(url);
PlayM4_GetPort(&port);
bool ok = PlayM4_OpenFile(port, data.data());
if (ok) {
//设置文件播放完毕回调函数
PlayM4_SetFileEndCallback(port, FileEndCallback, this);
//回调则可以拿到音视频数据,否则就直接句柄播放
if (callback) {
PlayM4_SetDecCallBackMend(port, DecCallBack, (quser)this);
PlayM4_Play(port, NULL);
} else {
PlayM4_Play(port, (HWND)playWidget->winId());
}
//同时播放声音
PlayM4_PlaySound(port);
//倒放
//PlayM4_ReversePlay(port);
//快进播放,多次调用速度更快
//PlayM4_Fast(port);
//PlayM4_Fast(port);
ok = true;
qDebug() << TIMEMS << "打开视频文件成功" << url;
} else {
qDebug() << TIMEMS << "打开视频文件失败" << url << PlayM4_GetLastError(port);
}
return ok;
}
bool HaiKangThread::init()
{
//判断该摄像机是否能联通
if (checkConn && isRtsp) {
if (!checkUrl(url, checkTime)) {
return false;
}
}
if (playWidget == NULL) {
return false;
}
//视频流和本地文件分别处理
bool ok = false;
if (isRtsp) {
ok = playRtsp();
} else {
ok = playLocal();
}
if (!ok) {
return false;
}
//设置保存文件
this->initSave();
return true;
}
void HaiKangThread::free()
{
if (isRtsp) {
//停止播放+登出设备
NET_DVR_StopRealPlay(hand);
NET_DVR_Logout(hand);
hand = -1;
} else {
//停止播放+关闭文件+释放端口
PlayM4_Stop(port);
PlayM4_StopSound();
PlayM4_CloseFile(port);
PlayM4_FreePort(port);
port = -1;
}
}