Core SDK を使って、RealtimeKit ミーティングの参加者ビデオフィードに背景エフェクトとぼかしを追加します。
npm i @cloudflare/realtimekit-virtual-backgroundyarn add @cloudflare/realtimekit-virtual-backgroundpnpm add @cloudflare/realtimekit-virtual-backgroundbun add @cloudflare/realtimekit-virtual-backgroundビデオミドルウェアのデフォルトのフレーム単位レンダリングを無効にします。このミドルウェア自身に制御を任せることで、速度と品質が向上します。
await meeting.self.setVideoMiddlewareGlobalConfig({
disablePerFrameCanvasRendering: true,
});ビデオ背景トランスフォーマーオブジェクトを作成します。
import RealtimeKitVideoBackgroundTransformer from "@cloudflare/realtimekit-virtual-background";
const videoBackgroundTransformer =
await RealtimeKitVideoBackgroundTransformer.init({
meeting,
});videoBackgroundTransformer は、次の 2 種類のミドルウェアを公開します。
createStaticBackgroundVideoMiddleware を使い、画像を背景に設定します。
const imageUrl = "https://images.unsplash.com/photo-1487088678257-3a541e6e3922";
meeting.self.addVideoMiddleware(
await videoBackgroundTransformer.createStaticBackgroundVideoMiddleware(
imageUrl,
),
);createBackgroundBlurVideoMiddleware を使い、背景をぼかします。パラメーターとして blurStrength(0〜100)を渡します(デフォルトは 50%)。
meeting.self.addVideoMiddleware(
await videoBackgroundTransformer.createBackgroundBlurVideoMiddleware(50),
);初期化の前に、ブラウザー対応を確認します。
if (RealtimeKitVideoBackgroundTransformer.isSupported()) {
const videoBackgroundTransformer =
await RealtimeKitVideoBackgroundTransformer.init({
meeting: meeting,
});
meeting.self.addVideoMiddleware(
await videoBackgroundTransformer.createStaticBackgroundVideoMiddleware(
imageUrl,
),
);
}よりシャープな結果を得るには、カスタムのセグメンテーション設定を渡します。
const videoBackgroundTransformer =
await RealtimeKitVideoBackgroundTransformer.init({
meeting,
segmentationConfig: {
model: "mlkit", // 'meet' | 'mlkit'
backend: "wasmSimd",
inputResolution: "256x256", // meet の場合は '256x144'
pipeline: "webgl2", // 'webgl2' | 'canvas2dCpu'
// canvas2dCpu はぼかしがシャープ、webgl2 は高速
targetFps: 35,
},
});npm i @cloudflare/realtimekit-virtual-backgroundyarn add @cloudflare/realtimekit-virtual-backgroundpnpm add @cloudflare/realtimekit-virtual-backgroundbun add @cloudflare/realtimekit-virtual-backgroundimport { useState, useEffect } from "react";
import { useRealtimeKitClient } from "@cloudflare/realtimekit-react";
import RealtimeKitVideoBackgroundTransformer from "@cloudflare/realtimekit-virtual-background";
function App() {
const [meeting] = useRealtimeKitClient();
const [videoBackgroundTransformer, setVideoBackgroundTransformer] =
useState(null);
useEffect(() => {
const initializeTransformer = async () => {
if (!meeting) return;
// ブラウザー対応を確認する
if (!RealtimeKitVideoBackgroundTransformer.isSupported()) {
console.warn("Video background not supported in this browser");
return;
}
// デフォルトのフレーム単位レンダリングを無効にする
await meeting.self.setVideoMiddlewareGlobalConfig({
disablePerFrameCanvasRendering: true,
});
// トランスフォーマーを初期化する
const transformer = await RealtimeKitVideoBackgroundTransformer.init({
meeting,
});
setVideoBackgroundTransformer(transformer);
};
initializeTransformer();
}, [meeting]);
const applyStaticBackground = async (imageUrl) => {
if (!videoBackgroundTransformer) return;
meeting.self.addVideoMiddleware(
await videoBackgroundTransformer.createStaticBackgroundVideoMiddleware(
imageUrl,
),
);
};
const applyBlur = async (blurStrength = 50) => {
if (!videoBackgroundTransformer) return;
meeting.self.addVideoMiddleware(
await videoBackgroundTransformer.createBackgroundBlurVideoMiddleware(
blurStrength,
),
);
};
const removeBackground = () => {
// すべてのビデオミドルウェアを削除する
meeting.self.removeVideoMiddleware();
};
return (
<div>
<button
onClick={() =>
applyStaticBackground(
"https://images.unsplash.com/photo-1487088678257-3a541e6e3922",
)
}
>
背景を適用
</button>
<button onClick={() => applyBlur(50)}>ぼかしを適用</button>
<button onClick={removeBackground}>背景を削除</button>
</div>
);
}よりシャープな結果を得るには、カスタムのセグメンテーション設定を渡します。
const transformer = await RealtimeKitVideoBackgroundTransformer.init({
meeting,
segmentationConfig: {
model: "mlkit", // 'meet' | 'mlkit'
backend: "wasmSimd",
inputResolution: "256x256", // meet の場合は '256x144'
pipeline: "webgl2", // 'webgl2' | 'canvas2dCpu'
// canvas2dCpu はぼかしがシャープ、webgl2 は高速
targetFps: 35,
},
});npm i @cloudflare/realtimekit-virtual-backgroundyarn add @cloudflare/realtimekit-virtual-backgroundpnpm add @cloudflare/realtimekit-virtual-backgroundbun add @cloudflare/realtimekit-virtual-backgroundコンポーネントの TypeScript ファイルで次のようにします。
import { Component, OnInit } from "@angular/core";
import RealtimeKitClient from "@cloudflare/realtimekit";
import RealtimeKitVideoBackgroundTransformer from "@cloudflare/realtimekit-virtual-background";
@Component({
selector: "app-meeting",
templateUrl: "./meeting.component.html",
})
export class MeetingComponent implements OnInit {
meeting: any;
videoBackgroundTransformer: any;
async ngOnInit() {
// ミーティングを初期化する
this.meeting = await RealtimeKitClient.init({
authToken: "<participant_auth_token>",
});
await this.meeting.join();
// ブラウザー対応を確認する
if (!RealtimeKitVideoBackgroundTransformer.isSupported()) {
console.warn("Video background not supported in this browser");
return;
}
// デフォルトのフレーム単位レンダリングを無効にする
await this.meeting.self.setVideoMiddlewareGlobalConfig({
disablePerFrameCanvasRendering: true,
});
// トランスフォーマーを初期化する
this.videoBackgroundTransformer =
await RealtimeKitVideoBackgroundTransformer.init({
meeting: this.meeting,
});
}
async applyStaticBackground(imageUrl: string) {
if (!this.videoBackgroundTransformer) return;
this.meeting.self.addVideoMiddleware(
await this.videoBackgroundTransformer.createStaticBackgroundVideoMiddleware(
imageUrl,
),
);
}
async applyBlur(blurStrength: number = 50) {
if (!this.videoBackgroundTransformer) return;
this.meeting.self.addVideoMiddleware(
await this.videoBackgroundTransformer.createBackgroundBlurVideoMiddleware(
blurStrength,
),
);
}
removeBackground() {
// すべてのビデオミドルウェアを削除する
this.meeting.self.removeVideoMiddleware();
}
}コンポーネントのテンプレートで次のようにします。
<button
(click)="applyStaticBackground('https://images.unsplash.com/photo-1487088678257-3a541e6e3922')"
>
背景を適用
</button>
<button (click)="applyBlur(50)">ぼかしを適用</button>
<button (click)="removeBackground()">背景を削除</button>よりシャープな結果を得るには、カスタムのセグメンテーション設定を渡します。
this.videoBackgroundTransformer =
await RealtimeKitVideoBackgroundTransformer.init({
meeting: this.meeting,
segmentationConfig: {
model: "mlkit", // 'meet' | 'mlkit'
backend: "wasmSimd",
inputResolution: "256x256", // meet の場合は '256x144'
pipeline: "webgl2", // 'webgl2' | 'canvas2dCpu'
// canvas2dCpu はぼかしがシャープ、webgl2 は高速
targetFps: 35,
},
});あらかじめパッケージ化されたフィルターをプロジェクトに追加するには、build.gradle ファイルに次の依存関係を追加します。
dependencies {
// (other dependencies)
implementation 'com.cloudflare.realtimekit:filters:0.1.0'
}このパッケージは現在 VirtualBackgroundVideoFilter を公開しており、FilterVideoProcessor と組み合わせて使えます。
// カスタム背景画像でバーチャル背景フィルターを作成する
val bgFilter = VirtualBackgroundVideoFilter(context, R.drawable.background)
// フィルターでビデオプロセッサーを初期化する
val processor = FilterVideoProcessor(eglBase, bgFilter)
// // ミーティングビルダーにビデオプロセッサーを設定する
val meeting = RealtimeKitMeetingBuilder
.setVideoProcessor(eglBase, processor)
.build(activity)ライブビデオストリームにエフェクト、フィルター、分析を直接適用する、独自のカスタムフィルターも作成できます。VideoProcessor API は、ビデオフレームを操作するための柔軟で強力な手段を提供します。
次の 3 種類のビデオプロセッサーを提供します。
- NoDropVideoProcessor: フレームを落とさずにカスタムのビデオ処理ができます。
- ChainVideoProcessor: 複数のフレームプロセッサーを連結します。ビデオストリームに複数のエフェクトやフィルターを適用するときに便利です。
- FilterVideoProcessor: ビデオストリームに 1 つのエフェクトまたはフィルターを適用するための、よりシンプルで効率的な方法です。
それでも、VideoProcessor インターフェースを直接実装して、独自のカスタムビデオプロセッサーを作成できます。
import realtimekit.org.webrtc.VideoFrame
import realtimekit.org.webrtc.VideoProcessor
import realtimekit.org.webrtc.VideoSink
class CustomVideoProcessor : VideoProcessor {
override fun onCapturerStarted(started: Boolean) {}
override fun onCapturerStopped() {}
override fun onFrameCaptured(frame: VideoFrame?) {}
override fun setSink(sink: VideoSink?) {}
}VideoProcessor を作成して設定したら、RealtimeKitMeetingBuilder オブジェクトに渡します。カメラがキャプチャしたビデオフレームは、他の参加者へ送る前、またはローカルで描画する前に処理されます。
// 'myCustomProcessor' は任意の VideoProcessor 実装のインスタンスです
// (例: ChainVideoProcessor、FilterVideoProcessor など)。
val myCustomProcessor = CustomProcessor()
// ミーティングビルダーにビデオプロセッサーを設定する
val meeting = RealtimeKitMeetingBuilder
.setVideoProcessor(processor = myCustomProcessor)
.build(activity)
// ビルダーに EglBase を渡すこともできます
// FilterVideoProcessor を使うときに便利です
val eglBase = EglBase.create()
val meeting = RealtimeKitMeetingBuilder
.setVideoProcessor(eglBase = eglBase, processor = myCustomProcessor)
.build(activity)