映像レンダリングガイド¶
概要¶
Sora Flutter SDK での映像レンダリングの方法について説明します。
描画までの流れは次のとおりです。
- 映像の
textureIdを取得する
- ローカル映像は
LocalVideoTrack.textureIdからtextureIdを取得する- リモート映像は
SoraTrackEventで受け取ったRemoteMediaStreamTrack.textureIdを使う
- 取得した
textureIdを Flutter のTextureに渡して描画する
イベント全体の一覧や SoraConnection.events の使い方は イベント をご確認ください。
TextureId を取得する¶
ローカル映像¶
ローカル映像を表示するには、まず送信用の MediaStream を用意します。 MediaStream の作成方法は メディアデバイスガイド をご確認ください。
ローカル映像の textureId は LocalVideoTrack.textureId ( Future<int> ) で取得します。
final stream = await MediaDevices.getUserMedia(
const GetUserMediaOptions(audio: true, video: true),
);
final videoTrack = stream.getVideoTracks().first;
final textureId = await videoTrack.textureId;
ただし、 createExternalVideoTrack で生成した外部映像入力用の LocalVideoTrack は textureId を返しません。詳細は 外部映像入力ガイド をご確認ください。
リモート映像¶
受信したリモート映像から textureId を取得する方法を説明します。
リモート映像を受信するまでの基本的な流れは 導入ガイド をご確認ください。また、 conn.events によりイベント購読しているものとします。
リモート映像は conn.events の SoraTrackEvent で受け取ります。トラックは RemoteMediaStreamTrack として通知され、 kind == 'video' の場合のみ textureId が non-null になります。
final remoteTextureIds = <String, int>{};
conn.events.listen((event) {
switch (event) {
case SoraTrackEvent(:final track):
final textureId = track.textureId;
if (track.kind == 'video' && textureId != null) {
setState(() {
remoteTextureIds[track.trackId] = textureId;
});
}
default:
break;
}
});
trackId は、複数リモートトラックを識別する際に利用できます。
remote track event の型や通知タイミングの詳細は イベント を参照してください。
Texture によるレンダリング¶
textureId を Flutter の Texture ウィジェットに渡してレンダリングします。リモートトラックの textureId は int? なので、 kind == 'video' を確認してから利用します。
Widget buildVideo(int textureId) {
return Texture(textureId: textureId);
}
final localVideo = buildVideo(textureId);
final remoteVideo = buildVideo(track.textureId!);
複数のリモート映像を並べて表示する場合は、受信したトラックのリストを GridView や Wrap などに流し込みます。
Widget buildRemoteVideos(Map<String, int> remoteTextureIds) {
return GridView.count(
crossAxisCount: 2,
children: remoteTextureIds.values
.map((textureId) => Texture(textureId: textureId))
.toList(),
);
}
削除されたリモートトラックの映像を取り除く¶
リモート側の切断等により SoraRemoveTrackEvent が通知された映像トラックの textureId は描画に使えなくなるため、対応する Texture をツリーから取り除きます。
// trackId をキーに textureId を管理するマップです
final remoteTextureIds = <String, int>{};
conn.events.listen((event) {
switch (event) {
case SoraTrackEvent(:final track):
final textureId = track.textureId;
if (track.kind == 'video' && textureId != null) {
setState(() {
remoteTextureIds[track.trackId] = textureId;
});
}
// SoraRemoveTrackEvent で該当する trackId をリストから削除します
case SoraRemoveTrackEvent(:final track):
if (track.kind == 'video') {
setState(() {
// trackId をキーに管理すると、SoraRemoveTrackEvent を受けたタイミングで該当する Texture を自然に表示から外せます
remoteTextureIds.remove(track.trackId);
});
}
default:
break;
}
});