9-7 共有録画 (Share Record) 機能の実践チュートリアル

前の章では、基本的な録画 API を使用しました。しかし、多くのプロフェッショナルなアプリケーション(放送のディレクションや医療手術の分割画面表示など)では、同じ映像ソースに対して「プレビュー表示」と「独立した録画」を同時に行い、さらに画面上に特定のテキストプロンプトを追加する必要があることがよくあります。

このニーズを解決するために、NexVDO SDK は強力な Share Record(共有録画) 機能を提供しています。これにより、開発者はディレクターのように映像と音声の行き先を自由に割り当てることができます。今日は、以前学んだ Callback(コールバック)メカニズムと組み合わせて、「デュアルウィンドウ表示」、「独立した録画」、そして「OSD テキストオーバーレイ」をサポートするアプリケーションを構築します!


© Blender Foundation | Big Buck Bunny | CC BY 3.0

コア API の理解 - 共有録画 ( Share Record )

Share Record エンジンを起動するには、「映像の取得」と「映像の処理」を2つの段階に分ける必要があります。Callback 内で生の非圧縮データを取得し、それを Share Record エンジンに「供給(フィード)」して処理させます。

標準的な使用手順は以下の通りです:

1. QCAP_SET_VIDEO_SHARE_RECORD_PROPERTY :Share Record の映像プロパティを設定します。
2. QCAP_SET_AUDIO_SHARE_RECORD_PROPERTY Share Record の音声プロパティを設定します。
3. QCAP_START_SHARE_RECORD Share Record エンジンを起動します。
4. QCAP_SET_VIDEO_SHARE_RECORD_UNCOMPRESSION_BUFFER Callback 内で映像の非圧縮バッファを継続的に供給します。
5. QCAP_SET_AUDIO_SHARE_RECORD_UNCOMPRESSION_BUFFER Callback 内で音声の非圧縮バッファを継続的に供給します。
6. QCAP_STOP_SHARE_RECORD Share Record エンジンを停止します。


 

コアコンセプト:Share Record の「映像の分岐(分流)」

詳細な API パラメータに入る前に、まず Share Record エンジンが基盤レイヤーで実際にどのように動作するのかを理解する必要があります。なぜ「それは単なるレコーダーではなく、レンダラーでもある」と言われるのでしょうか?

以下の概念図をご覧ください:


図に示すように、従来の録画方法は「1つのキャプチャーカードを1つの録画ファイルにバインドする」というものでした。しかし、マルチアングルやプロのディレクションシナリオでは、複数の映像ソース( 図の ch1, ch2, ch3, ch4 など)を同時に持つ場合があります。

Share Record エンジンを通じて、開発者は「プロのディレクター」に変身できます。これらのソースからの生の画面(バッファ)をすべてエンジンに供給すると、エンジンはあなたのコマンドに従って、これらの画面を自由に「分岐( 分流 )」および「再構築」することができます。ch3ch4、または ch1 をどのディスプレイ画面に独立して出力するか、あるいはどの独立した録画ファイルとして保存するかを任意に決定できます!

これこそが Share Record の最大の魅力です:「画面キャプチャ」と「レンダリング/録画」を完全に切り離し、開発者に映像割り当ての究極の自由を与えます!

この分岐の概念を理解すると、今後の API で頻繁に iRecNum  (エンジンチャンネル)を指定する必要がある理由がわかるでしょう。「表示」と「録画」のデュアルトラック並行を実現するために、SDK は最大64個の独立した Share Record チャンネル (  iRecNum の範囲は 0〜63)を提供しています。今日の実装では、 表示用にチャンネル 0 を、専用の録画用にチャンネル 1 を割り当てます。

QCAP_SET_VIDEO_SHARE_RECORD_PROPERTY

この API は以前の基本録画 API と似ていますが、「出力表示とカラースペース」に関する設定が追加されています。



QCAP_SET_AUDIO_SHARE_RECORD_PROPERTY

映像の設定が完了したら、次に音声のエンコードと周波数を設定します。

QCAP_START_SHARE_RECORD

この API は、基本的な分岐(分流)と録画機能に加えて、映像・音声の遅延、自動ファイル分割、AES128 ファイル暗号化などの高度な設定もサポートしています。

QCAP_SET_VIDEO_SHARE_RECORD_UNCOMPRESSION_BUFFER

開発者のヒント : 入力された画面をクロッピング(切り抜き)する必要がある場合は、代わりに末尾に _EX が付くバージョンの API を使用してください。

QCAP_SET_AUDIO_SHARE_RECORD_UNCOMPRESSION_BUFFER

開発者のヒント : ここでの pFrameBuffer の音声フォーマットが、前に QCAP_SET_AUDIO_SHARE_RECORD_PROPERTY で設定したフォーマットと異なる場合、ユーザーは末尾に  _EX が付くバージョンの API を使用して、入力音声の実際のフォーマットをエンジンに伝える必要があります

QCAP_STOP_SHARE_RECORD

この Share Record チャンネルを使用しなくなった場合は、この API を呼び出してエンジンを停止し、リソースを解放する必要があります。


コア API の理解 - テキストオーバーレイ ( OSD )

完璧な分岐( 分流 )エンジンを手に入れたら、NexVDO に内蔵されている OSD エンジンを使って、出力映像に様々なテキストプロンプトや透かし( ウォーターマーク )を追加することもできます。SDK は、開発者が自由に割り当てられる最大 512 個の独立した OSD レイヤー ( 0〜511 ) を提供します。

テキストを完璧に描画するための標準的なプロセスは「2ステップ」です:まずテキストの境界サイズを取得し、次にテキストと色を描画します。


© Blender Foundation | Big Buck Bunny | CC BY 3.0

【ステップ 1:テキスト境界取得 API - QCAP_GET_OSD_TEXT_BOUNDARY】 実際に文字を描画する前に、使用するフォントとサイズをエンジンに伝え、システムにこの文字列が占める幅と高さを計算させる必要があります。

QCAP_GET_OSD_TEXT_BOUNDARY

QCAP_SET_OSD_TEXT

ステップ 2 : オーバーレイするテキストの幅と高さの境界を取得したら、指定された X/Y 座標にテキストを正確に描画できます。この API の最も特別な点は、アルファ透明チャンネル(透過度)を持つ16進数カラーフォーマット  ( 0xAARRGGBB ) をサポートしていることです。


 

ここで、重要なライフサイクルについて強調しておきます:開発者は QCAP_CREATE を呼び出してデバイスを作成した後であれば、いつでもこの API を使用してテキストをオーバーレイできます。 つまり、映像が正式に起動したり録画が開始されたりするのを待たずに、あらかじめ画面に透かしやプロンプトテキストを配置しておくことができるということです!

開発者のヒント : 録画が終了した時、または そのレイヤーの OSD テキストを消去したい時は、pszString パラメータに NULL を渡すだけで OSD をオフにできます!

UI 表示インターフェースの構築

強力な基盤 API の知識を得たところで、まずは「デュアルウィンドウの分岐(分流)」を完璧に表現できるグラフィカルインターフェースを構築しましょう。9-5 で作成したプロジェクトの基礎を引き継ぎ、 mainwindow.uiを開いてデザインモード (Design Mode) に入ってください:

2つ目の表示キャンバス (QFrame) の追加

• 左側のツールバー ( Widget Box ) から Frame コンテナを見つけ、 それを元のプレビューキャンバスの右側にドラッグ&ドロップします。 
• 右下のプロパティエディタ ( Property Editor ) で、この新しいキャンバスの  objectName を PreviewWindow2 に命名します。これが、私たちの Share Record エンジン専用の分岐表示画面になります!

4組のコントロールボタン ( QPushButton ) の作成

• ツールバーから4つの Push Buttons を画面下部にドラッグ&ドロップします。
• それぞれの表示テキスト ( text プロパティ ) を、 「START DISPLAY」「STOP DISPLAY」「START RECORD」、および 「STOP RECORD」 に変更します。

ボタンクリックイベント ( Slots ) の作成

• これら4つのボタンをそれぞれ右クリックし、 「Go to slot...(スロットへ移動)」 ➔ clicked()を選択して、Qt Creator に mainwindow.cpp 内で対応するコードブロックを自動生成させます。

コアコードの記述

UI の準備が整ったら、 まずはチャンネル 0 (iRecNum = 0) を使用して「同期デュアルスクリーン表示」機能を実現します。

変数の宣言と UI フールプルーフ(エラー防止)メカニズム

Share Record エンジンを正式に呼び出す前に、プログラムの安定性を確保するために2つのことをしっかり行う必要があります:「エンジンの現在のステータスを記録すること」と「ユーザーがむやみにボタンを押すのを防ぐこと」です。

以下の手順に従って、デュアルウィンドウプログラムのための厳格なセーフティネット(保護網)を構築しましょう:

プログラムに現在の Share Record エンジンの動作ステータスを知らせるために、 mainwindow.h を開き、 public セクションで2つのブール (Boolean) 変数を宣言します:



次に mainwindow.cppを開きます。プログラムの起動時(つまり  MainWindow::MainWindow コンストラクタ内)に、これら2つの変数を false に初期化する必要があります。



同時に、起動前にユーザーが「STOP」ボタンを押してしまうのを防ぐため、Qt に内蔵されている setEnabled() 関数を利用してボタンの利用可能ステータスを管理します:



ボタンクリックイベントでのステータス切り替え ユーザーが「START」をクリックした後、すぐに「START」ボタンをグレーアウト(無効化)し、「STOP」ボタンを点灯(有効化)させなければなりません。先ほど作成した4つの Slot 関数に、それぞれ以下のステータス切り替えロジックを追加してください:



プログラム終了前の安全な終了(セーフエグジット)、mainwindow.cpp  内のデストラクタ ( MainWindow::~MainWindow )を見つけ、 QCAP_STOP を呼び出して基盤デバイスを閉じる前に、先ほど作成した「STOP ボタン」イベントを強制的に呼び出し、エンジンが安全に閉じられることを確認してください:

UI フールプルーフメカニズムとステータス変数の設定が完了したら、いよいよこのレッスンのメインイベント(ハイライト)に入ります!次の実装フェーズでは、強力な Share Record エンジンを段階的に呼び覚まし、ダイナミックな OSD テキストをプロジェクトに完璧に融合させます。

mainwindow.cpp を開き、以下の手順に従って4つのボタンに魂を吹き込んでいきましょう:

実装その1:「純粋な表示用」分岐エンジンの起動

まず、 「START DISPLAY」「STOP DISPLAY」チャンネル 0 (iRecNum = 0) を起動して映像を右側のウィンドウに専用で分岐(分流)させ、「STOP DISPLAY」をクリックした時にそれを閉じることです 

1. START DISPLAY (表示開始) の実装 on_pushButton_clicked() 内で PreviewWindow2 をバインドし、エンジンのフラグを純粋な表示用  ( FLAG_DISPLAY ) に設定してください:

➤ 開発者必修の「パラメータ連動」の極意 : 実践開発において、 Format Changed Callback がトリガーされた時に、ついでに最新のデータをこれらの変数に保存しておく ことを強くお勧めします。マルチストリームエンジンを起動する準備ができ、複雑なコーデックパラメータを設定する必要がある時に、これらの変数をそのまま API に渡すことができます!これには3つの大きな利点があります:

1. 完全な手動設定不要のエラー防止(フールプルーフ) : コード内に幅、高さ、フレームレートを「ハードコーディング(固定値として記述)」する必要がありません。
2. 入力ソースとの完璧なマッチング : エンコーダ (Encoder) が受信する解像度が、現在のハードウェアキャプチャ状態と 100% 一致することを保証します。
3. 動的な変化へのシームレスな適応 : ユーザーが途中で異なる解像度のカメラに変更した場合でも、次回の起動時にパラメータが自動的に更新されます!



2. Callback 内でチャンネル 0 にデータを提供する
    
   エンジン起動後、それ自体には映像がありません。ハードウェアが取得したデータをチャンネル 0 に供給するために、 on_video_preview_cb と  on_audio_preview_cb に移動する必要があります:
    
    ➤ Callback の概念の復習 : 9-5 ステータスコールバックと画像スナップショット機能のサンプル
    
    • 映像データ ( Video ) : キャプチャーカードから   on_video_preview_cb 内で送られる非圧縮の生映像は、デフォルトで  NV12 フォーマットのカラースペースになっています。したがって、QCAP_SET_VIDEO_SHARE_RECORD_UNCOMPRESSION_BUFFER を呼び出す際は、パラメータに   QCAP_COLORSPACE_TYPE_NV12 を明示的に指定する必要があります。これにより、エンジンはこの画像を正しく解読してレンダリングできます!
    • 音声データ ( Audio ) : 同様に on_audio_preview_cb がデフォルトで送出する音声は、非圧縮の生の  PCM フォーマットです。 ( 今後の高度な開発において、入力される音声フォーマットが先ほど設定したプロパティと異なる場合は、エンジンにフォーマットの違いを知らせるために、末尾に _EX が付くバージョンの API を使用することを忘れないでください!)





3. STOP DISPLAY ( 表示停止 ) の実装

実装その2:「独立した録画と OSD」エンジンの構築

次に、他の2つの録画ボタンを処理します。今回は チャンネル 1 (iRecNum = 1)を使用し、映像を MP4 として保存するだけでなく、録画の瞬間に赤色の "START RECORD" というプロンプトテキストをオーバーレイ(重ね合わせ)します!

1. START RECORD (録画と OSD の開始) の実装 on_pushButton_3_clicked() 内に以下のロジックを追加してください。今回はウィンドウをバインドせず( NULL を入力)、OSD の動的計算と描画を追加することに注意してください:



温故知新:完璧なパラメータ連動 「実装その1」で使用したテクニックと同様に、ここでも Callback で取得した m_nVideoWidth などの変数を、そのまま iRecNum = 1の録画エンジンに供給します。



2. Callback のスイッチボード(メイン処理)に「チャンネル 1」の信号を補充する ハードウェアキャプチャーカードには Callback スイッチボードが1つしかないため、先ほど記述した on_video_preview_cb に戻り、「チャンネル 0」のロジックの下に、 続けてチャンネル 1 に割り当てられたロジックを追加する必要があります:





3. STOP RECORD (録画停止と OSD のクリア) の実装
録画を停止する際、チャンネル 1 を閉じることに加えて最も重要なのは、画面上のプロンプトテキストを消去するために、QCAP_SET_OSD_TEXT  の文字列パラメータに  NULL を渡すことです:



【開発者のための落とし穴回避ガイド:「録画チャンネル」と「OSD レイヤー」を混同しないように!】この OSD コードを書く際、初心者が最もよく犯す間違いは、パラメータ内の「0」と「1」に騙されることです!両者の違いを必ず明確にしてください: 

• Share Record チャンネル (iRecNum) : 録画専用としてチャンネル 1 を指定したため、  QCAP_START_SHARE_RECORD を呼び出す際の最初のパラメータは 1になります。
• OSD オーバーレイレイヤー (iOsdNum) : SDK は 512 個 (0〜511) の独立した OSD キャンバスを提供します。OSD はハードウェアデバイス ( m_pDevice )に直接作用するため、  QCAP_SET_OSD_TEXT を呼び出す際に2番目のパラメータに渡す 0 は、「0 番目の OSD レイヤー」を表しており、 0 番目の録画チャンネルではありません!

最終確認(動作検証)

すべてのコードの準備が整いました。Qt Creator の左下にある 「Build and RUN(ビルドして実行)」 (緑色の再生ボタン)をクリックして、プロジェクトをコンパイルおよび実行してください。

Next, please follow the steps below to personally verify Implementation 1 and Implementation 2 :

次に、以下の手順に従って、実装その1と実装その2を実際に検証してみましょう:

プログラムが正常に起動し、カメラの映像をキャプチャしたら、 「START DISPLAY」 ボタンをクリックしてください。この時、元々真っ黒だった右側の PreviewWindow2 ウィンドウが瞬時に点灯し、左側のメインウィンドウと完全に同期し、遅延が全くない分岐(分流)映像がスムーズに再生され始めます!


© Blender Foundation | Big Buck Bunny | CC BY 3.0

続いて、下部にある 「START RECORD」 ボタンをクリックします。すると、画面の左上隅に鮮明な "START RECORD" の OSD プロンプトテキストがすぐにポップアップ表示されます!


© Blender Foundation | Big Buck Bunny | CC BY 3.0

最終的な動画ファイルの検証 : 数秒間録画した後、 「STOP RECORD」ボタンをクリックすると、画面上のプロンプトテキストがスマートに消えることがわかります( NULL を渡すことに成功したためです)。最後に、プロジェクトの build フォルダに移動してターミナルを開き、以下を入力してください:

➤  ffmpeg のインストールについてはこちらを復習できます: 9-6 オーディオ・ビデオ録画機能の実践チュートリアル

ffplay SHARERECORD.MP4

 

再生中の動画に、OSD プロンプトテキストが含まれた高画質な映像が完璧に表示されていれば—おめでとうございます! 私たちはゼロから NexVDO SDK の Share Record エンジン と OSD オーバーレイ技術  をマスターしました。

あなたはもう単に「画面を録画する」だけではありません。どの映像を表示し、どの映像を録画し、さらに画面上にどのようなカスタマイズされた字幕を追加するかを自由に決定できるようになりました。将来、マルチチャンネルの独立した録画が必要なセキュリティ監視システムに直面しようとも、複雑なレイヤーの重ね合わせが必要な放送用ライブ配信ソフトウェアに直面しようとも、この基盤となるロジックはあなたの最も強力な開発の武器となるでしょう!

次の課題に挑む準備はできましたか?それでは、次のレッスンでお会いしましょう!

Copyright © 2026 YUAN High-Tech Development Co., Ltd.
All rights reserved.