본문으로 건너뛰기
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 프레임워크를 사용하는 경우 PlanetKitJoinConferenceParam에서 callKitTypePlanetKitCallKitType.user로 설정해야 합니다.

그런 다음 CXProviderDelegate.provider(_ provider: CXProvider, didActivate audioSession: AVAudioSession)에서 PlanetKitConference.notifyCallKitAudioActivation()을 호출하여 PlanetKit에서 오디오가 활성화되도록 해야 합니다.

관련 예제 코드

관련 문서