本文にスキップする
Version: 1.0

グループビデオ通話

グループビデオ通話を実装するサンプルコードです。

前提条件

開始する前に、次の作業が必要です。

グループビデオ通話実装時の考慮事項

joinConference()を呼び出した後、返却されたPlanetKitJoinConferenceResultreasonプロパティを確認する必要があります。

  • reasonPlanetKitStartFailReason.NONEの場合、成功を意味します。
  • それ以外は失敗を意味し、reasonに応じて適切に処理する必要があります。

デバイス権限のリクエスト

Dart permission_handlerパッケージを使用してマイク、電話、Bluetooth接続、カメラの権限をリクエストします。

import 'package:permission_handler/permission_handler.dart';
final status = await [Permission.microphone, Permission.phone, Permission.bluetoothConnect, Permission.camera].request();

変数の用意

主要プロパティとイベントハンドラーに対する変数を用意します。

  • PlanetKitConferenceEventHandlerは、グループ通話のステータス変更イベントを処理するのに使用されます。詳しくは、グループ通話フローを参照してください。
  • PlanetKitMyMediaStatusHandlerは、ローカルユーザーのメディアステータス変更イベントを処理するのに使用されます。マイクがミュートもしくはミュート解除された場合やオーディオの説明が更新された場合、ビデオのステータスが変更された場合など、イベントに基づいてローカルユーザーのUIを更新できます。
final String _myUserId = "test user id";
final String _serviceId = "test service id";
PlanetKitConference? _conference;
List<Peer> _peers = [];

bool isMyAudioMuted = false;
bool isMyVideoPaused = false;
bool isVideoEnabled = false;

int volume = 0;

final _eventHandler = PlanetKitConferenceEventHandler(
onConnected: (conference) => print("connected"),
onDisconnected: (conference, reason, source, byRemote) => print("disconnected $reason"),
onPeerListUpdated: _onPeerListUpdated);

final _myMediaStatusHandler = PlanetKitMyMediaStatusHandler(
onAudioDescriptionUpdate: (status, averageVolumeLevel) => volume = averageVolumeLevel,
onMicMute: (status) => isMyAudioMuted = true,
onMicUnmute: (status) => isMyAudioMuted = false,
onVideoStatusUpdate: (status, videoStatus) {
if (videoStatus.state == PlanetKitVideoState.enabled) {
isMyVideoPaused = false;
isVideoEnabled = true;
} else if (videoStatus.state == PlanetKitVideoState.disabled) {
isVideoEnabled = false;
} else if (videoStatus.state == PlanetKitVideoState.paused) {
isMyVideoPaused = true;
isVideoEnabled = true;
}
});

グループ通話参加

グループ通話に参加するには、PlanetKitJoinConferenceParamBuilder()を使ってPlanetKitJoinConferenceParamを作成し、これを引数としてPlanetKitManager.instance.joinConference()を呼び出します。

  • グループビデオ通話に参加するためにPlanetKitMediaType.audiovideoを引数としてPlanetKitJoinConferenceParamBuildersetMediaType()を呼び出します。
  • ローカルユーザーのビデオの初期状態は、PlanetKitJoinConferenceParamBuildersetInitialMyVideoState()で設定できます。
    • initialMyVideoStateプロパティのデフォルト値は、PlanetKitInitialMyVideoState.resumeです。
    • PlanetKitInitialMyVideoState.pauseを引数としてsetInitialMyVideoState()を呼び出してローカルユーザーのビデオの初期状態が一時停止に設定された場合、ローカルユーザーのビデオは送信されません。通話接続後にローカルユーザーのビデオを転送するには、resumeMyVideo()を呼び出します。
Future<bool> joinConference(String roomId, String accessToken) async {
var builder = PlanetKitJoinConferenceParamBuilder()
.setMyUserId(_myUserId)
.setMyServiceId(_serviceId)
.setRoomServiceId(_serviceId)
.setRoomId(roomId)
.setAccessToken(accessToken);
.setMediaType(PlanetKitMediaType.audiovideo)
.setInitialMyVideoState(initialMyVideoState);

PlanetKitJoinConferenceParam? param;
try {
param = builder.build();
} catch (error) {
print("failed to build join conference param $error");
return false;
}
final result =
await PlanetKitManager.instance.joinConference(param, _eventHandler);

if (result.reason != PlanetKitStartFailReason.none) {
print("join conference result ${result.reason}");
return false;
}

// Store conference instance and set MyMediaStatusHandler.
_conference = result.conference;
_conference?.myMediaStatus.setHandler(_myMediaStatusHandler);
return true;
}

PlanetKitPeerControlを使用してピア管理

PlanetKitConferenceEventHandler.onPeerListUpdated()およびPlanetKitPeerControlを使用してグループ通話に参加したピアを管理します。ピアリストが更新されたら、モニタリングするピアに対するPlanetKitPeerControlを作成します。

class Peer {
final PlanetKitPeerControl control;
bool videoAvailable = false;

Peer({required this.control});

void register() async {
final handler =
PlanetKitPeerControlHandler(onVideoUpdate: (control, videoStatus) {
videoAvailable =
videoStatus.state == PlanetKitVideoState.enabled ? true : false;
});
await control.register(handler);
}

void unregister() async {
await control.unregister();
}

void startVideo(String viewId) async {
await control.startVideo(viewId);
}

void stopVideo(String viewId) async {
await control.stopVideo(viewId);
}
}

ビデオのレンダリング

ピアのビデオをレンダリングするには、PlanetKitVideoViewBuilderを使用してPlanetKitVideoViewを作成し、PlanetKitPeerControlに追加する必要があります。

ピアのビデオに対するPlanetKitVideoViewを作成した後、startVideo(viewId)を呼び出してピアのビデオビューをPlanetKitPeerControlに追加します。

ピアのビデオを表示するには、メディアタイプがPlanetKitMediaType.audiovideoである必要があります。

class PeerView extends StatelessWidget {
final Peer peer;
PeerView({required this.peer});


Widget build(BuildContext context) {
if (peer.videoAvailable) {
return VideoView(peer: peer);
} else {
return Text("video not available");
}
}
}

class VideoView extends StatelessWidget {
const VideoView({super.key, required this.peer});
final Peer peer;


Widget build(BuildContext context) {
final videoView = PlanetKitVideoViewBuilder.instance
.create(PlanetKitViewScaleType.fitCenter);

videoView.onCreate.listen((id) {
peer.startVideo(id);
});

videoView.onDispose.listen((id) {
peer.stopVideo(id);
});

return videoView;
}
}

グループ通話退出

グループ通話から退出するには、leaveConference()を呼び出します。

Future<bool> leaveConference() async {
return await _conference?.leaveConference() ?? false;
}

CallKit連携のための追加実装(任意)

Note

この手順は、iOSアプリケーションにのみ適用されます。

CallKitフレームワークを使用する場合、PlanetKitJoinConferenceParamcallKitTypePlanetKitCallKitType.userに設定する必要があります。

その後、CXProviderDelegate.provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession)PlanetKitConference.notifyCallKitAudioActivation()を呼び出し、PlanetKitでオーディオを有効にする必要があります。

関連サンプルコード

関連ドキュメント