Amazon Chime SDK の新機能 Video Processing APIを使って仮想背景を作る

4 min read読了の目安(約3900字

この記事は、こちらの記事を改変したものになります。
https://cloud.flect.co.jp/entry/2020/12/29/152543

はじめに

12月21日にAmazon Chime SDK JS version 2.3.0がリリースされました。
このリリースでは、新機能Video Processing APIが追加されましたよ!

https://github.com/aws/amazon-chime-sdk-js/blob/master/CHANGELOG.md

Video Processing APIはビデオ会議で用いる自分のカメラの映像(フレーム)を転送前に編集するAPIです。これを使えば、たとえば、カメラに写り込んだ背景をぼかす仮想背景機能が実現できます。実現方法は、公式のドキュメントを読む限り、以前、Qiitaのほうで紹介した方法に近いように思われます。とうとう公式実装が来たか!という感じです。ワクワクしますね。

それでは早速Video Processing APIを使って仮想背景を作ってみることにしましょう。

Video Processing APIの使い方

image

ドキュメントにも記載されているとおり、Video Processing APIでは、入力デバイス[1]のフレームを一つ以上のVideoFrameProcessorがパイプライン処理する形で映像の編集を行います。Video Processing APIでは、このパイプライン処理をラップするVideoTransformDeviceというクラス(interface)が提供されています。このクラスのコンストラクタに入力デバイスとVideoFrameProcessorの配列を渡してあげて、インスタンスを生成します。
このVideoTransformDeviceのインスタンスは仮想的なビデオ入力デバイスとしてAmazon Chimeに渡すことが可能ですので、chooseVideoInputDeviceで渡してあげます。

つまり、

const transformDevice = new DefaultVideoTransformDevice(
    logger,
    deviceId, 
    [new SomeVideoFrameProcessorA(), ...]  // 映像編集機能を実装したVideoFrameProcessor
);

とVideoTransformDeviceを作成し、

meetingSession.audioVideo.chooseVideoInputDevice(deviceId)

としていたところ

meetingSession.audioVideo.chooseVideoInputDevice(transformDevice)

といったカタチで渡してあげることになります。

今回は、背景を他の画像に置き換える単一のVideoFrameProcessorを作成して仮想背景機能を実現します。VideoTransformDeviceの作成の仕方はこんな感じになります。

const transformDevice = new DefaultVideoTransformDevice(
    logger,
    deviceId, 
    [new VirtualBackground()]  // 仮想背景機能を実装したVideoFrameProcessor
);

仮想背景機能(VideoFrameProcessor)

VideoFrameProcessor はフレームの映像処理を行うprocessメソッドを持つクラス(interface)です。このprocessメソッドの中身で人物と背景を識別し、背景を別の映像に置き換えます。人物と背景の識別には、以前の記事でご紹介したBodypixを用います[2]

processメソッドは、フレームのデータ(VideoFrameBuffer)の配列を引数として受けとるので、ここから映像データを抜き出して加工します。
ざっくり下記のような感じです。

    async process(buffers: VideoFrameBuffer[]){
        for(const f of buffers){
            const canvas = f.asCanvasElement() // 映像データの抜き出し。
            // (1)映像の編集処理
        }
        return Promise.resolve(buffers)
    }

上記のソースコードの(1)映像の編集処理の部分で、bodypixを使って人物と背景を識別し、背景の置き換えを行います。
具体的な処理は[以前の記事](
processメソッドは、フレームのデータ(VideoFrameBuffer)の配列を引数として受けとるので、ここから画像データを抜き出して加工します。
ざっくり下記のような感じです。

    async process(buffers: VideoFrameBuffer[]){
        for(const f of buffers){
            const canvas = f.asCanvasElement() // 画像データの抜き出し。
            // (1)画像の編集処理
        }
        return Promise.resolve(buffers)
    }

上記のソースコードの(1)画像の編集処理の部分で、bodypixを使って人物と背景を識別し、背景の置き換えを行います。具体的な処理は以前の記事に記載してありますので、ここでは省略します。

たったこれだけです。以前ご紹介したように自分でこれをやるためには、ダミーのHTMLVideoElementを用意して、ループを回してフレームの取得し、画像の編集といったことを実装する必要がアリましたが、そういった処理がごっそりと不要となります。

動作確認

では、動作を確認してみましょう。背景が画像に入れ替わっていますね。

20201229120135

リポジトリ

今回作成したソースコードは次のリポジトリに置いてあります。

https://github.com/w-okada/chime-videoprocess-ts

動作方法はリポジトリのREADMEをご確認ください。

まとめ

以上、Amazon Chime SDK の新機能 Video Processing APIsを用いて仮想背景を実装してみました。かなり簡単に実装できるようになっており、これまで我々が苦労して実装していたかなりの部分を省略することができました。なんとも複雑な気分ですが、メンテナンスが公式にされるので、トータルとしてはありがたいですかね。

下記のリポジトリでは、ここで紹介した機能以外にも、チャット機能やホワイトボード機能も搭載したバージョンを公開しています。
またCognito連携も実装しています。下記のリポジトリに公開していますので、是非ご活用ください。

https://github.com/w-okada/flect-chime-sdk-demo

謝辞

本文中の動画はこちらのサイトのものを使わせていただきました。

https://pixabay.com/ja/videos/
脚注
  1. 例によって、入力デバイスはデバイスID以外にも、MediaStreamを受け付けられるようになっています(Good!)。 ↩︎

  2. 最近はGoogleMeetの仮想背景が高性能と評判で、Apach2.0ライセンスで公開されているTFLiteモデルを有志でTFJS化する試みがなされてようとしていますが、それはまた別のお話。 ↩︎