2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Kurentoの独自Moduleを作る

Posted at

概要

前回、KurentoでMCU接続のGroup Callを行うサンプルを作成しましたが、Kurento標準のCompositeMixerエレメントでは、レイアウトのパターンが決まっていて自由に配置する事ができませんでした。このレイアウトを変更するためには、独自のKurentoエレメントを作成する必要があります。

そこで今回は新規にKuretno Moduleを作成し、CompositeMixerエレメントと同じ機能を持つCustomMixerという名前のエレメントを追加して動作させてみます。CustomMixerを変更して、オリジナルのレイアウトに変更する作業は次回に行います。

独自Kurento Moduleとエレメント追加&動作確認は、以下の手順で行っていきます。

  1. Module作成ツールのインストール

  2. Module作成ツールを使って雛形を作る

  3. 既存のコードをベースにElement本体を作る

  4. ビルド環境を整える

  5. ビルドをする

  6. debパッケージの作成とインストール

  7. JAVA Client用ライブラリの作成とインストール

  8. 動作確認

Module作成ツールのインストール

Kurento Moduleの作成作業は、kurento-media-serverを動作させるUbuntuマシンにログインして行います。

まずは、作業用ディレクトリを作っておきます。

cd
mkdir work
cd work

自作エレメントの作成の際に参照するので、オリジナルのkurento−elementsのソースを取得しておきます。

git clone https://github.com/Kurento/kms-elements.git
cd kms-elements
git checkout 6.16.0
cd ..

Kurento Moduleを自作するときには、kurento-module-scaffoldというツールを使います。kurento-module-scaffoldはkurento-media-server-devというパッケージに入っているのでインストールします。

sudo apt update && apt install -y kurento-media-server-dev

Module作成ツールを使って独自のModuleを作る

kurento-module-scaffoldを使って新しいmodule("MyModule")を作成します。一番目の引数にmodule名(Module名はCamelCaseで指定する必要あり)2番目の引数に出力ディレクトリを指定します。3番目の引数を与えるとOpenCV用のフィルタモジュールを作成しますが、ここではGstermer用のモジュールを作成するので何も指定せずに実行します。

kurento-module-scaffold MyModule .

このコマンドにより、my-moduleフォルダが作成されて、モジュールのソースコード一式がそのフォルダの中に作成されます。

cd my-module

MyModuleのソースコードは、以下のようなフォルダ構成になっています。

my-module (ルート)
|-- src
|   |-- gst-plugins  ... Kurento Media Server内に生成されるCustomMixerの本体のソースコード
|   |-- server
|       |-- implementation ... Kurento ClientからCustomMixerを呼び出すAPIのコード
|       |-- interface ... CustomMixerモジュールの記述ファイル(.kmf)
|-- debianパッケージを生成するためのフォルダ

ソースコードの雛形が作成されました。

既存のコードをベースにElementを作る

ここからMyModuleの中にCustomMixer Elementを作成していきます。エレメントのコードを0から作るのは大変なので、標準のKurento-elementsモジュールに含まれるCompositeMixerをコピーして作成します。

src/server/inferfaceフォルダ内のモジュール記述ファイル(xxx.kmd.json)に作成するelementの情報を記述します。雛形を作成した段階で、src/server/interfaceフォルダの中に、mymodule.MyModule.kmd.jsonというファイルがあるので、ファイル名をmymodule.CustomMixer.kmd.jsonに変更します。

mv src/server/interface/mymodule.MyModule.kmd.json src/server/interface/mymodule.CustomMixer.kmd.json

mymodule.CustomMixer.kmd.jsonの内容をオリジナルのCompositeMixerの記述ファイル(kms-elements/src/server/interface/elements.Composite.kmd.json)を参考に以下の通りに書き換えます。

src/server/interface/mymodule.CustomMixer.kmd.json
{
  "remoteClasses": [
    {
      "name": "CustomMixer",
      "extends": "Hub",
      "doc": "CustomMixer interface. Documentation about the module",
      "constructor": {
        "doc": "Create an element",
        "params": [
          {
            "name": "mediaPipeline",
            "doc": "the parent :rom:cls:`MediaPipeline`",
            "type": "MediaPipeline",
            "final": true
          }
        ]
      }
    }
  ]
}

このファイルでは作成するエレメントの名前、親クラス、説明、パラメータなどを記述します。記述ファイルを作成したら、cmakeを実行するとAPIを作成するコード(C++)を src/server/implementation/objectフォルダの中に自動生成します。ここでは、プロジェクトのルートフォルダの下に"build"フォルダを作成してcmake ..を実行します。

mkdir build
cd build
cmake ..
cd ..

これで、src/server/implementation/objectの中にCustomMixerImpl.cppCustomMixerImpl.hppができました。

ls src/server/implementation/objects/
> CustomMixerImpl.cpp  CustomMixerImpl.hpp

APIを生成するコードが自動生成されたのですが、一部不完全なので追記が必要な箇所があります。親クラスのコンストラクタを呼び出すコードをCompositeMixerのコードに従って追記します。CustomMixerImpl.cppのコード21行目から25行目までのCustomMixerImplコンストラクタのコードを以下のコードに置き換えて、親クラスのコンストラクタが呼ばれるように書き換えます。

src/server/implementation/objects/CustomMixerImpl.cpp
#define FACTORY_NAME "custommixer"

CustomMixerImpl::CustomMixerImpl (const boost::property_tree::ptree &conf, std::shared_ptr<MediaPipeline> mediaPipeline) 
    : HubImpl (conf, std::dynamic_pointer_cast<MediaObjectImpl> (mediaPipeline), FACTORY_NAME) 
{
}

以上で新しいエレメントのためのKurento APIを作成するコードができました。

次にCustomMixerの処理の内容を記述します。オリジナルのCompositeMixerをベースに、kmscompositemixer.cの中の"COMPOSITE"の文字列を"CUSTOM"に置換します。全部大文字、先頭大文字、全部小文字の3パターンとも書き換えて、src/gst-plugin/gstcustommixer.cとして書き込みます。以下のコマンドをプロジェクトのルートディレクトリで実行します。

sed -e 's/COMPOSITE/CUSTOM/g' -e 's/Composite/Custom/g' -e 's/composite/custom/g' ../kms-elements/src/gst-plugins/kmscompositemixer.c > src/gst-plugins/gstcustommixer.c

ヘッダーファイルも同様に作成します。

sed -e 's/COMPOSITE/CUSTOM/g' -e 's/Composite/Custom/g' -e 's/composite/custom/g' ../kms-elements/src/gst-plugins/kmscompositemixer.h > src/gst-plugins/gstcustommixer.h

gstcustommixer.cppファイルの先頭部分を編集してgstcustommixer.hをincludeするように修正します。

src/gst-plugins/gstcustommixer.c
// kmscustommixer.h から gstcustommixer.hに変更する
#include "gstcustommixer.h"

同様にmymodule.cファイルの先頭部分を編集してgstcustommixer.hをincludeするように修正します。

src/gst-plugins/mymodule.c
// gstmymodule.h から gstcustommixer.hに変更する
#include "gstcustommixer.h"

さらにmymodule.cファイルのinit()関数から呼び出されるCustomMixer エレメントの初期化関数を書き換えます。

src/gst-plugins/mymodule.c
static gboolean
init (GstPlugin *plugin)
{
    // gst_my_module_plugin_initからkms_custom_mixer_plugin_initに変更
    if (!kms_custom_mixer_plugin_init (plugin))  
    return FALSE;

  return TRUE;
}

src/gst-pluginsフォルダの中に、gstmymodule.cppとgstmymodule.hのファイルがありますが、これは自動生成された中身のないフィルタエレメントのコードで不要なので削除しても構いません。

エレメントのコードの作成は以上です。

ビルド環境を整える

kurentoのヘッダーファイルと、ライブラリがリンクできるようにプロジェクトのルートフォルダにある.CMakeLists.txtの51行目の# Generate file "config.h"の直前に以下の2行を追記します。

.CMakeLists.txt
include(GenericFind)
generic_find(LIBNAME KmsGstCommons REQUIRED)

src/gst-plugins/CMakeLists.txt を修正して、kurentoのヘッダーファイルとライブラリの設定を追記します。またソースコードとしてgstcustommixer.cとgstcustommixer.hを指定します。

src/gst-plugins/CMakeLists.txt
include_directories(
  ${GSTREAMER_INCLUDE_DIRS}
  ${GSTREAMER_VIDEO_INCLUDE_DIRS}
  ${CMAKE_CURRENT_SOURCE_DIR}
  ${OPENCV_INCLUDE_DIRS}
  ${KmsGstCommons_INCLUDE_DIRS}      # 行追加
)

set(MY_MODULE_SOURCES
  mymodule.c
  gstcustommixer.h                   # gstcustommixer.hを指定
  gstcustommixer.c                   # gstcustommixer.cを指定
)

add_library(mymodule MODULE ${MY_MODULE_SOURCES})
if(SANITIZERS_ENABLED)
  add_sanitizers(mymodule)
endif()

target_link_libraries(mymodule
  ${GSTREAMER_LIBRARIES}
  ${GSTREAMER_VIDEO_LIBRARIES}
  ${OPENCV_LIBRARIES}
  ${KmsGstCommons_LIBRARIES}         # 行追加
)

install(
  TARGETS mymodule
  RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  LIBRARY DESTINATION ${CMAKE_INSTALL_GST_PLUGINS_DIR}
  ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)

ビルドをする

ここで、ビルドディレクトリを作ってcmake ..を実行すると、コードが自動生成されてmakeできるようになり、makeします。

cd build
cmake ..
make

ビルドしてできたモジュールのライブラリ(libmymodule.so)がbuild/srcディレクトリの中に作成されました。

debパッケージの作成とインストール

モジュールのライブラリをkurento-media-serverが起動時に読み込んで実行できるようにするためにdebianパッケージを作成します。

プロジェクトのルートフォルダに戻って、debパッケージのビルドツールがインストールされていなければインストールします。

cd .. 
sudo apt update && sudo apt install --no-install-recommends --yes dpkg-dev

ルートディレクトリでパッケージを作成します。

dpkg-buildpackage -us -uc

これで、作成したライブラリのdebパッケージができました。生成されたdebパッケージはルートフォルダの親フォルダにあります。

ls ../*.deb
../my-module-dev_0.0.1~rc1_amd64.deb  ../my-module_0.0.1~rc1_amd64.deb

パッケージをkurento-media-serverが動作するUbuntuにインストールします。

sudo dpkg -i ../my-module_0.0.1~rc1_amd64.deb

インストールできたかどうかは kurento-media-server-vオプション付きで起動するとわかります。

$ kurento-media-server -v
Kurento Media Server version: 6.16.0
Found modules:
	'core' version 6.16.0
	'elements' version 6.16.0
	'filters' version 6.16.0
	'mymodule' version 0.0.1~1.g13fd0d5

作成したモジュールが無事にkurento-media-serverに読み込まれるようになりました。

JAVA Client用ライブラリの作成とインストール

Java Client用のライブラリを作成します。このライブラリを読み込ませるとKurento Client ApplicationからMyModule内のCustomMixerを呼び出して使用することができるようになります。

cd build
cmake .. -DGENERATE_JAVA_CLIENT_PROJECT=TRUE
make java

ビルド終了後、build/java/targetディレクトリの下にcustommixer-0.0.1-SNAPSHOT.jarファイルが作成されました。

このファイルは、kurento-clientから、kurento-media-serverのCustomMixerを作成・制御するためのAPIを含むライブラリです。kurento-clientを動作させるマシンにインストールする必要がありますので、このファイルをMacにコピーしてローカルのmvnリポジトリにインストールします。

Macの任意のディレクトリで以下を実行します。

scp <username>@<kuernto host IP>:~/work/my-module/build/java/target/mymodule-0.0.1-SNAPSHOT.jar .

mvn install:install-file \
-Dfile=./mymodule-0.0.1-SNAPSHOT.jar \
-DgroupId=org.kurento.module \
-DartifactId=mymodule \
-Dversion=0.0.1-SNAPSHOT \
-Dpackaging=jar \
-DgeneratePom=true

動作確認

これを前回作ったkurento-group-call-mcuで動かして試してみましょう。

kurento-group-call-mcuプロジェクトのルートディレクトリにあるpom.xmlの<dependencies>の項目に以下を追記します。

pom.xml
		<dependency>
			<groupId>org.kurento.module</groupId>
			<artifactId>mymodule</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>

javaのコードを今回作成したCustomMixerを使うように修正します。

room.javaのソースコードでImportするモージュール名を以下の様にComposteからCustomMixerに変更し、

room.java
-import org.kurento.client.Composite;
+import org.kurento.module.mymodule.CustomMixer;

以下room.java中のComposteクラスをCustomMixerクラスに置き換えます。(3箇所くらい)

Ubuntu 側でkurento-media-serverを起動してからKurento Clientを起動します。

# Ubuntuマシンで実行
GST_DEBUG="1,Kurento*:5,custommixer*:5" kurento-media-server

環境変数GST_DEBUGに上記の様にデバッグオプションを指定してから起動すると、kurento-media-serverとKurentoClient間のメッセージのやり取りを確認することができます。ログを解析すると、CustomMixerが呼び出されていることを確認することができます。

Mac側

# Macで実行
cd kurento-group-call-mcu
./start.sh

macのブラウザからlocalhost:8443にアクセスして前回作った標準のComposite による画面合成と全く同様に動くとこを確認できればOKです。

まとめ

新規にKuretno Moduleを作成し、CompositeMixerエレメントと同じ機能を持つCustomMixerという名前のエレメントを追加して動作させてみました。次回はCustomMixerを変更して、独自のレイアウトに変更する作業を行います。

ここまでのソースコードはこちらでダウンロードできます。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?