본문으로 건너뛰기
Version: 5.5

그룹 영상 통화

그룹 영상 통화를 구현하는 예제 코드입니다.

필수 조건

시작하기 전에 다음 작업을 수행해야 합니다.

그룹 영상 통화 구현 시 고려 사항

joinConference()를 호출한 다음에는 반환된 PlanetKitConferenceResultreason 속성을 확인해야 합니다.

  • reasonPlanetKitStartFailReason.NONE인 경우 성공을 의미합니다.
  • 그렇지 않으면 실패를 의미하며 reason에 따라 적절한 조치를 취해야 합니다.

권한 요청

통화하기 전에 다음의 런타임 권한을 획득하세요.

  • Manifest.permission.READ_PHONE_STATE
  • Manifest.permission.RECORD_AUDIO
  • Manifest.permission.BLUETOOTH_CONNECT (targetSdkVersion 31 이상)
  • Manifest.permission.CAMERA

변수 준비

주요 속성 및 이벤트 리스너에 대한 변수를 준비합니다.

PlanetKitMyMediaStatusListener는 로컬 사용자의 미디어 상태 변경 이벤트를 처리하는 데 사용됩니다. 마이크가 음소거되거나 음소거 해제되는 경우나 오디오 설명이 업데이트되는 경우 또는 비디오 상태가 업데이트되는 경우 등 이벤트를 기반으로 로컬 사용자의 UI를 업데이트할 수 있습니다.

val myUserId = "test user id"      // The local user's user ID
val serviceId = "test service id" // Service ID

// PlanetKitMyMediaStatusListener object
val myMediaStatusListener = object : PlanetKitMyMediaStatusListener {
override fun onMyAudioMuted() {
// This is called when the local user's audio is muted.
// Write your own code here.
}

override fun onMyAudioUnmuted() {
// This is called when the local user's audio is unmuted.
// Write your own code here.
}

override fun onMyAudioDescriptionUpdated(audioDescription: PlanetKitAudioDescription) {
// This is called when the local user's audio description is updated.
// Write your own code here.
}

override fun onVideoStatusUpdated(videoStatus: PlanetKitVideoStatus) {
// This is called when the local user's video status is updated.
// Write your own code here.
}
}

로컬 사용자의 비디오 미리보기

미리보기 기능을 사용하면 로컬 사용자가 그룹 통화 세션과 관계없이 자신의 비디오를 미리 볼 수 있습니다.

로컬 사용자의 비디오 미리보기를 시작하려면 PlanetKitCameraManagerstartPreview()를 호출하세요.

fun startPreviewExample(preview: PlanetKitVideoView)
{
PlanetKit.getCameraManager().startPreview(preview)
}

로컬 사용자의 비디오 미리보기를 중지하려면 PlanetKitCameraManagerstopPreview()를 호출하세요.

fun stopPreviewExample(preview: PlanetKitVideoView)
{
PlanetKit.getCameraManager().stopPreview(preview)
}

그룹 통화 입장

그룹 통화에 입장하려면 적절한 PlanetKitConferenceParam과 함께 PlanetKit.joinConference()를 호출하세요. PlanetKitConferenceParam을 만들려면 PlanetKitConferenceParam.Builder()를 사용하세요.

  • 영상 그룹 통화에 입장하도록 PlanetKitMediaType.AUDIOVIDEO를 인자로 PlanetKitConferenceParam.BuildermediaType()을 호출하세요.
  • 로컬 사용자의 초기 비디오 상태는 PlanetKitConferenceParam.BuildersetInitialMyVideoState()로 설정할 수 있습니다.
    • initialMyVideoState 속성의 기본값은 PlanetKitInitialMyVideoState.RESUME입니다.
    • PlanetKitInitialMyVideoState.PAUSE를 인자로 setInitialMyVideoState()를 호출하여 로컬 사용자의 초기 비디오 상태가 일시 중지로 설정된 경우 로컬 사용자의 비디오는 전송되지 않습니다. 이 경우 로컬 사용자의 비디오는 통화가 연결된 후 resumeMyVideo()를 호출하여 전송할 수 있습니다.
fun joinConferenceExample(roomId: String, accessToken: String, initialMyVideoState: PlanetKitInitialMyVideoState)
{
val param = PlanetKitConferenceParam.Builder()
.myId(myUserId)
.roomId(roomId)
.myServiceId(serviceId)
.roomServiceId(serviceId)
.accessToken(accessToken)
.mediaType(PlanetKitMediaType.AUDIOVIDEO)
.setInitialMyVideoState(initialMyVideoState)
.build()

val result = PlanetKit.joinConference(param, conferenceListener = object : ConferenceListener {

override fun onConnected(conference: PlanetKitConference,
isVideoHwCodecEnabled: Boolean,
isVideoShareModeSupported: Boolean) {
// This is called when the call is connected.
// Write your own code here.
}

override fun onDisconnected(conference: PlanetKitConference,
param: PlanetKitDisconnectedParam) {
// This is called when the call is disconnected.
// Write your own code here.
}

override fun onPeerListUpdated(param: PlanetKitConferencePeerListUpdatedParam) {
// This is called when the list of peers is updated.
// The following is an example function. For more information, see the "Manage peers using PlanetKitPeerControl" section.
handlePeerListUpdate(param)
}

override fun onPeersVideoUpdated(conference: PlanetKitConference, param: PlanetKitConferenceVideoUpdateParam) {
// This is called when the video of one or more peers is updated.
// Write your own code here.
}
})

if (result.reason == PlanetKitStartFailReason.NONE) {
// The "result.conference" instance is the main instance to call APIs from now on.
// You must keep it to control this call.
}
else {
// Handle an error by referring to result.reason.
}
}

로컬 사용자에 대한 미디어 상태 리스너 설정(선택 사항)

통화가 연결되면 필요에 따라 로컬 사용자에 대한 미디어 상태 리스너를 설정하세요.

fun setMyMediaStatusListenerExample(): Boolean
{
var conference = PlanetKit.getConference() ?: return false

conference.getMyMediaStatus()?.addHandler(myMediaStatusListener, null) {
}

return true
}

로컬 사용자를 위한 비디오 뷰 추가

addMyVideoView()를 호출하여 로컬 사용자의 비디오가 렌더링될 비디오 뷰를 추가하세요. 비디오 렌더링은 로컬 사용자의 비디오 상태에 따라 시작되거나 중지됩니다.

fun addMyVideoViewExample(myVideoView: PlanetKitVideoView): Boolean
{
var conference = PlanetKit.getConference() ?: return false

conference.addMyVideoView(myVideoView)

return true
}

피어를 위한 비디오 뷰 추가

addPeerVideoView()를 호출하여 피어의 비디오가 렌더링될 비디오 뷰를 추가하세요.

fun addPeerVideoViewExample(peer: PlanetKitConferencePeer, peerVideoView: PlanetKitVideoView): Boolean
{
var conference = PlanetKit.getConference() ?: return false

conference.addPeerVideoView(peer, peerVideoView)

return true
}

각 피어에 대한 피어 컨트롤 생성

피어 목록이 업데이트되면 새로 추가된 피어에 대해 PlanetKitPeerControl을 생성하고 PeerControlListener 객체를 등록하세요. PeerControlListener를 사용하여 각 피어의 상태 변경을 처리할 수 있습니다.

class PeerContainer internal constructor(
peer: PlanetKitConferencePeer
) {
val peerControl: PlanetKitPeerControl = peer.createPeerControl()
?: throw IllegalStateException("Failed to create peer control.")

init {
val peerControlListener = object : PlanetKitPeerControl.PeerControlListener {
override fun onMicMuted(peer: PlanetKitConferencePeer) {
// This is called when the peer's audio is muted.
// Write your own code here.
}

override fun onMicUnmuted(peer: PlanetKitConferencePeer) {
// This is called when the peer's audio is unmuted.
// Write your own code here.
}

override fun onAudioDescriptionUpdated(
peer: PlanetKitConferencePeer,
audioDescription: PlanetKitAudioDescription
) {
// This is called when the peer's audio description is updated.
// Write your own code here. The following is an example of implementation.
val yourOwnThresholdTalkingVolumeLevel = 10
val isPeerTalking =
audioDescription.averageVolumeLevel >= yourOwnThresholdTalkingVolumeLevel
}

override fun onVideoUpdated(
peer: PlanetKitConferencePeer,
videoStatus: PlanetKitVideoStatus,
subgroupName: String?
) {
// This is called when the peer's video is updated.
// Write your own code here. The following is an example of implementation.
when (videoStatus.videoState) {
PlanetKitVideoStatus.VideoState.DISABLED -> {
// The peer's video is disabled.
// The video stops even if you don't call peerControl.stopVideo().
}

PlanetKitVideoStatus.VideoState.ENABLED -> {
// The peer's video is enabled.
// If you call peerControl.startVideo(), the peer's video is received and rendered.
peerControl.startVideo(
PlanetKitVideoResolution.RECOMMENDED,
subgroupName
)
}

PlanetKitVideoStatus.VideoState.PAUSED -> {
// Write your own code for paused video.
}
}
}

override fun onDisconnected(peer: PlanetKitConferencePeer) {
// This is called when the peer is disconnected from the call.
// Write your own code here.
}
}

peerControl.register(peerControlListener)
}
}

// Example function called in the onPeerListUpdated callback.
private val peerContainerList = mutableListOf<PeerContainer>()
fun handlePeerListUpdate(param: PlanetKitConferencePeerListUpdatedParam) {
// Process added peers.
for (addedPeer in param.addedPeers) {
// Create peer control for your class.
peerContainerList.add(PeerContainer(addedPeer))
}

// Process removed peers.
for (removedPeer in param.removedPeers) {
peerContainerList.removeIf {
it.peerControl.peer.isSameMember(removedPeer)
}
}
}

그룹 통화 퇴장

그룹 통화에서 퇴장하려면 leaveConference()를 호출하세요.

fun leaveConferenceExample(): Boolean
{
var conference = PlanetKit.getConference() ?: return false

conference.leaveConference()

return true
}

관련 예제 코드

관련 문서