Kakao i Connect Live::Kakao i Connect Live 1.0::Connect Live SDK::iOS SDK::Callback & Config

페이지 이동경로

Callback

iOS 버전의 Kakao i Connect Live SDK에서 제공하는 Callback 메서드는 다음과 같습니다.

공통

일대일 통화, 방송, 그룹 통화에서 공통적으로 사용되는 Callback 메서드는 다음과 같습니다.

onInit()

onInit() Callback 메서드는 SDK가 Kakao i Connect Live 서버에 정상적으로 접속하여 방송 또는 통신 인프라를 사용할 준비가 완료되었을 때 호출됩니다. onInit() 메서드는 일반적인 경우에는 사용되지 않으며, 디버깅(Debugging) 용도로만 사용됩니다.

코드예제onInit() Syntax

remonCast.onInit { () in
    ...   // 서비스에 맞게 구현
}

onClose()

onClose() Callback 메서드는 사용자 또는 상대방이 명시적으로 close() 메서드를 호출하거나, 네트워크 이상 등으로 연결이 종료될 때 호출됩니다. onClose() Callback이 호출되면 Remon 클래스에서 사용했던 모든 자원들의 연결이 해제됩니다.

코드예제onClose() Syntax

remonCast.onClose {
    ...   // 서비스에 맞게 구현
}

remonCast.close()

onError()

onError() Callback 메서드는 Remon 클래스 동작 중 에러가 발생했을 때 호출됩니다.

코드예제onError() Syntax

remonCast.onError { (error) in
    // RemonError
    switch error {
    case .ConnectChannelFailed(_)
    break;
    }
}

onRetry()

Remon 클래스 동작 중 네트워크 환경에 변경이 감지되면 재연결을 시도하게 되며, 이때 재연결 상태를 알려주는 onRetry() 메서드가 호출됩니다. 재연결 시도가 시작될 경우 completed 값을 false로 호출하며, 재연결이 완료되면 completed 값을 true로 호출합니다. 만약 재연결 시도 중 실패 또는 에러가 발생한 경우에는 onRetry() 메서드가 아닌 onError() 또는 onClose() 메서드가 호출됩니다.

코드예제onRetry() Syntax

self.remonCast.onRetry { (completed) in
    if completed {
        // 재연결이 완료됨
        // 재연결 시도 중 실패 시 호출 되지 않을 수 있음
    } else {
        // 재연결을 시도하며, 재연결 시도가 시작되면 항상 호출됨
    }
}

onRemoteVideoSizeChanged()

영상 사이즈와 영상 비율은 네트워크 상태 또는 영상 장치에 따라 모두 다를 수 있습니다. 따라서 Caller가 고정된 사이즈와 비율로 송출이 보장되지 않는 환경이라면 변화하는 영상 크기에 적절히 반응할 수 있도록 구현이 필요합니다.
상대방 영상(Remote View)을 보정하기 위해서는 onRemoteVideoSizeChanged() 메서드를 구현해야 합니다.

코드예제공통 onRemoteVideoSizeChanged

remonCall.onRemoteVideoSizeChanged {(view, size) in 
    let raito = size.height / size.width
    let oldSize = view.frame.size
    let newFrame = 
    CGRect(x: 0.0, y: 0.0, width: oldSize.width, height: oldSize.width * raito)
    view.frame = newFrame
}

onLocalVideoSizeChanged()

영상 사이즈와 영상 비율은 네트워크 상태 또는 영상 장치에 따라 모두 다를 수 있습니다. 따라서 Caller가 고정된 사이즈와 비율로 송출이 보장되지 않는 환경이라면 변화하는 영상 크기에 적절히 반응할 수 있도록 구현이 필요합니다.
자신의 영상(Local View)을 보정하기 위해서는 onLocalVideoSizeChanged() 메서드를 구현해야 합니다.

코드예제onLocalVideoSizeChanged

remonCall.onLocalVideoSizeChanged {(view, size) in 
    let raito = size.height / size.width
    let oldSize = view.frame.size
    let newFrame = 
    CGRect(x: 0.0, y: 0.0, width: oldSize.width, height: oldSize.width * raito)
    view.frame = newFrame
}

onStat()

사용자는 간혹 자신 또는 상대방의 네트워크 문제로 인하여 통화 품질이 안 좋거나 끊어진 상황에서도 네트워크 문제가 아닌 서비스 문제라고 생각하고 불만을 제기할 수 있습니다. 해당 경우에는 사용자에게 서비스 문제가 아닌 네트워크 문제임을 사전에 알려주거나 또는 다양한 UI 처리를 통해 정확한 안내를 하는 것이 좋습니다.

네트워크 상황 등에 따른 미디어 품질 문제를 정확하게 파악하기 위해서는 onState(report) Callback 메서드를 통해 통화 또는 방송 상태를 알 수 있는 report를 수신할 수 있습니다. report는 사용자가 remon 클래스 생성 시에 설정한 statInterval 간격을 기준으로 제공됩니다. 해당 report는 네트워크 상황과 같은 미디어 품질을 나타내기 때문에 사용자에게 로딩 UI 처리 등을 안내하는 경우에 유용하게 사용할 수 있습니다. report에 들어오는 값은 현재 통화 품질(음성 또는 영상)에 대해 다음과 같이 총 다섯 단계로 구분되어 표시됩니다. 현재 이러한 통화 품질 정보는 5초에 한 번씩 받을 수 있으며, result에서 받을 수 있는 여러 정보 중 result.rating은 네트워크 상황에 따른 통합적인 통화 품질 정보를 의미합니다.

방송 또는 통화 품질 상태
단계 품질
1 매우 좋은 상태
2 좋은 상태
3 나쁜 상태
4 매우 나쁜 상태
5 방송 또는 통화가 불가능한 상태

코드예제onStat() Syntax

let remonCall = RemonCall()
remoCall.onRemonStatReport{ (stat) in 
    let rating:RatingValue = stat.getRttRating()
    let level = rating.levle
}

방송

방송 서비스에서 제공하는 Callback 메서드는 다음과 같습니다.

onCreate()

onCreate() Callback 메서드는 방송 Caster에게만 사용되며, Caster는 create() 메서드를 통해 방송을 정상적으로 생성하고 송출합니다. onCreate() 메서드는 고유 구분자인 Channel ID를 생성하며, Viewer들은 해당 Channel ID를 사용하여 방송에 접속할 수 있습니다.

코드예제onCreate() Syntax

remonCast.onCreate { (channelId) in
    ...   // 서비스에 맞게 구현
}

remonCast.create()

onCreate() Elements
구분 타입 필수 여부 설명
channelld String 선택 Caster가 생성한 방송의 고유 아이디
- Channel ID 생성 규칙에 따라 생성할 수 있으며, 미지정 시 자동 생성됨

onJoin()

onJoin() Callback 메서드는 방송에 Viewer에게만 사용하며, Viewer가 join() 메서드의 Channel ID를 통해 연결이 완료되어 미디어 시청이 가능한 상태가 되면 호출됩니다.

코드예제onJoin() Syntax

remonCast.onJoin {
    ...   // 서비스에 맞게 구현
}

remonCast.join('{CHANNEL_ID}')

onJoin() 메서드 Elements
구분 타입 필수 여부 설명
CHANNEL_ID String 필수 Caster가 생성한 방송의 고유 아이디
- Viewer는 해당 Channel ID를 사용하여 방송에 접속

통화

통화 서비스에서 제공하는 Callback 메서드는 다음과 같습니다.

onConnect()

onConnect() Callback 메서드는 통화에서만 사용됩니다. 채널을 생성하여 통화를 요청하는 Caller와 해당 채널에 접속하여 요청에 응답하는 Callee의 동작이 다른 경우가 많기 때문에, 개발자는 Caller 또는 Callee 여부에 대한 상태를 관리에 주의해야 합니다.

  • Caller는 connect() 메서드를 통해 채널을 새로 만들고, 상대방의 입장을 기다립니다.
  • Callee는 connect() 메서드를 통해 이미 만들어진 채널에 Channel ID 정보를 가지고 접속합니다.
    • Callee가 정상적으로 채널에 연결되면 onConnect() 메서드가 호출되지만, 곧바로 발생하는 onComplete() 메서드를 사용하는 것을 권장합니다.

코드예제onConnect() Syntax

remonCall.onConnect { (channelId) in
    ...   // 서비스에 맞게 구현
}

remonCast.connect("{CHANNEL_ID}")

onConnect() Elements
구분 타입 필수 여부 설명
channelld String 선택 Caster가 생성한 통화의 고유 아이디
- Channel ID 생성 규칙에 따라 생성할 수 있으며, 미지정 시 자동 생성됨

onComplete()

onComplete() Callback 메서드는 통화에서만 사용되며, Caller와 Callee가 연결이 완료되어 미디어 전송이 가능한 상태가 되면 호출됩니다.

코드예제onComplete() Syntax

remonCall.onComplte {
    ...   // 서비스에 맞게 구현
}

Config

Kakao i Connect Live SDK는 RemonCall 또는 RemonCast 객체에 직접 설정 정보를 지정할 수 있습니다. 이러한 설정 정보를 별도의 객체에 생성해 두고, RemonCall 또는 RemonCast 객체를 생성할 때마다 해당 설정값을 사용하고자 하거나 또는 다른 화면에서 설정값을 방송 또는 통신 화면으로 전달해야하는 경우에 Config 값을 사용할 수 있습니다.

RemonCall 또는 RemonCast 객체의 connect() 메서드 호출 시에는 Config 정보와 함께 전달하며, RemonCall 또는 RemonCast 내부의 설정이 아닌 Config 설정을 사용해 연결이 이루어집니다. iOS의 경우에는 RemonConfig 객체를 사용합니다.

영상 사이즈 변경

영상 크기 값을 얻고 싶다면 onRemoteVideoSizeChanged와 onLocalVideoSizeChanged를 구현합니다.

코드예제onRemoteVideoSizeChanged 이벤트

let remonCall = RemonCall()
remonCall.onRemoteVideoSizeChanged {(view, size) in 
    let raito = size.height / size.width
    let oldSize = view.frame.size
    let newFrame = 
    CGRect(x: 0.0, y: 0.0, width: oldSize.width, height: oldSize.width * raito)
    view.frame = newFram
}

안내
RemonCall 또는 RemonCast에서는 사이즈에 대한 정보만 제공하고, 실제 뷰의 비율을 조정하지 않습니다. 특정 비율로 영상을 보여주기 위해서는 LayoutConstraint 등을 사용하여 원하는 크기로 조정해야 합니다.

Meta 데이터 등록

사용자의 UID(User ID) 또는 프로퍼티 등 서비스에 필요한 메타 데이터를 설정할 수 있습니다. iOS는 String 데이터만 지원합니다.

코드예제Meta 데이터

let config:RemonConfig = RemonConfig()
config.userMeta = "string"

Media

음성 방송/통화 설정

비디오를 사용하지 않고, 음성 방송 또는 음성 통화 서비스를 만들 수 있습니다.

코드예제음성 방송/통화 설정

// 비디오를 사용하지 않고 음성만 사용 시
remonCall.onlyAudio = true   // true로 설정 시 비디오를 사용하지 않음

// 비디오와 오디오를 모두 사용 시
remonCall.onlyAudio = false  // 기본 설정

비디오 옵션 설정

WebRTC는 기본적으로 네트워크나 단말의 상태에 따라 해상도와 Frame Rate 등을 유연하게 변화시키면서 품질을 유지합니다. 따라서 해상도를 특정값으로 설정하더라도 설정된 해상도가 정확하게 유지되지 않을 수 있습니다. 이러한 경우에는 코덱 등의 옵션을 변경하여 해상도를 최적으로 설정할 수 있습니다.

코드예제비디오 옵션 설정

remonCall.videoWidth = 640
remonCall.videoHeight = 480
remonCall.videoFps = 24
remonCall.videoCodec = "H264"
remonCall.useFrontCamera = true // 기본 설정은 true이며, false 설정 시 후면 카메라를 사용

// 로컬 비디오 전송 준비가 완료되면 자동으로 로컬 비디오 캡처를 시작
// false로 설정 시, onComplete() 호출한 후에 startLocalVideoCapture() 호출 필요
remonCall.autoCaptureStart = true     // 기본 설정은 true

오디오 타입 설정

오디오 출력 시 주변 소음을 제거하는 기능과 관련한 작동 유형을 설정할 수 있습니다. iOS는 동적으로 해당 기능을 제공하지 않으므로, 자신의 프로젝트에 RemonSettings.plist 파일을 추가하고, AudioType을 원하는 모드로 변경해야 합니다.

오디오 타입 설정 Elements
Key 타입 필수 여부 설명
AudioType String 선택 오디오 타입 설정
music: 모든 소리를 가공없이 전달
- 방송(RemonCast)에서는 기본값으로 설정
voice: 주변 소음을 제거하고 음성을 전달
- 통화(RemonCall)에서는 기본값으로 설정

외부 Capturer 설정

2.4.43 버전부터 기본 RTCCameraCapturer가 아닌 외부 Capturer를 이용할 수 있도록 지원하고 있습니다. 해당 기능을 사용하기 위해서는 RemonController의 useExternalCapturer 값을 true로 설정하고, RemonController의 localExternalCaptureDelegator에게 외부 Capturer로부터 얻어온 프레임을 등록합니다.

코드예제External Capturer

remonCast.useExternalCapturer = true

remonCast.onCreate { (chid) in
    self.startCapter()
}

func startCapture() {
    YourExCapturer.captureBlock { (pixelBuffer, comTime) in
        if let rtcCaptureDelegate = 
            remonCall.localExternalCaptureDelegator {
                rtcCaptureDelegate.didCaptureFrame(
                    pixelBuffer: pixelBuffer,
                    timeStamp: cmTime, 
                    videoRetation: ._0)
        }
    }
}

오디오 설정

Session Category, Mode

서비스에 따라 AVAudioSession.Category.playback과 AVAudioSession.Category.playAndRecord 등을 사용할 수 있으므로, iOS에서는 Audio Session Category, Mode 설정에 따라 스피커 출력, 음소거 스위치의 작동, 이어폰 연결 작동, 블루투스 등이 상이하게 작동할 수 있습니다.
WebRTC의 기본값은 playAndRecord이며, 대부분 방송 또는 통화에 대해서는 기본값을 권장합니다. 다만 통화, 방송 송출, 방송 시청 등 서비스의 필요에 따라 AVAudioSession.Category를 변경하여 사용하실 수 있습니다. 소리 출력 디바이스는 기본적으로 이어피스(Earpiece)로 나오며, 스피커로 나오게 하려면 설정을 변경해야 합니다. 이 경우에는 RemonCall 또는 RemonCast 생성 전에 호출하면 해당 설정이 유지되므로, viewDidLoad() 메서드에서 원하는 카테고리와 모드를 설정해야합니다. 구버전과 최신버전 간의 사용 API가 다르므로 코드 예제를 참고하시기 바랍니다.

코드예제오디오 세션

// AVAudioSession.Mode.voiceChat : 수화기 사용
// AVAudioSession.Mode.videoChat : 스피커 사용
RemonClient.setAudioSessionConfiguration(
              category: AVAudioSession.Category.playAndRecord,
              mode: AVAudioSession.Mode.videoChat,
              options: [] );

do {
    // 오디오세션 카테고리 설정
    if #available(iOS 10.0, *) {
        try AVAudioSession.sharedInstance().setCategory(AVAudioSession.Category.playback, mode: AVAudioSession.Mode.default)
    }else {
        AVAudioSession.sharedInstance().perform(NSSelectorFromString("setCategory:error:"), with: AVAudioSession.Category.playback)
    }
    try AVAudioSession.sharedInstance().setActive(true, options: [])
    try AVAudioSession.sharedInstance().overrideOutputAudioPort(.speaker)
} catch {
    print(error)
}

안내
자세한 Audio Session에 대한 모드와 일반적인 사용 방법은 Audio Session Categories and Modes 문서를 참고하시기 바랍니다.

Volume Ratio

RemonCast 또는 RemonCall을 뮤직 모드로 이용할 경우 출력 볼륨(Output Volume)이 크게 느껴질 수 있습니다. 이 경우에는 volumeRatio값을 조정하여 AudioSession outputVolume과의 출력 비율을 조정할 수 있습니다. 예를 들어, outputVolume이 1.0(최대값) 일 때 volumeRatio를 0.8로 설정한다면 RemonCast 또는 RemonCall은 출력 볼륨의 80%로 출력됩니다.

코드예제Volume Ratio

self.remonCall.volumeRatio = 0.8

Mixing Sound

WebRTC가 동작을 시작하면 WebRTC는 AVAudioSession을 점유하며, AVAudioSession을 이용한 효과음 재생에 문제가 발생할 수 있습니다. 이 문제를 해결하기 위하여 OpenAL과 같은 저수준 효과음 재생 라이브러리의 사용을 권장하며, OpenAL을 좀 더 쉽게 사용할 수 있게 만들어진 ObjectAL 같은 라이브러리의 사용도 가능합니다.

코드예제ObjectAL

#import "ObjectAL.h"
#define SHOOT_SOUND @"shoot.caf"

[[OALSimpleAudio sharedInstance] playEffect:SHOOT_SOUND];

안내
자세한 설명은 ObjectAL 문서를 참고하시기 바랍니다.

Background Policy

백그라운드(Background)에서 지속적인 SDK와의 연결은 Project > Targets > Capabilities > Background Modes에서 설정해야 합니다. 백그라운드 설정을 안 할 경우에는 애플리케이션이 백그라운드로 진입 시에 Connect Live와의 연결이 종료되고, 방송과 통화도 종료됩니다.

안내
Xcode 버전별 VOIP 설정에 대한 자세한 설명은 Apple Developers > Configuring Background Execution Modes 문서를 참고하시기 바랍니다.

다음은 백그라운드에서 SDK와 지속적으로 연결이 되어있을 때의 작동이며, 백그라운드 옵션을 사용하지 않으면 모든 경우에서 백그라운드의 영상, 음성 송출, 수신이 중단됩니다. 다음은 Audio Session Category가 AVAudioSessionCategoryPlayback일 경우의 동작입니다.

AVAudioSessionCategoryPlayback 동작
상황 미디어 내용
송출 백그라운드 영상 Callee에게는 정지 화면(마지막 프레임, FPS 0)이지만, 음성은 들림
송출 백그라운드 음성 Callee에게 음성이 들림
수신 백그라운드 영상 음성은 들을 수 있으며 개발을 통해 백그라운드에서 음성을 켜거나 끌 수 있음
수신 백그라운드 음성 음성을 들을 수 있으며 개발을 통해 백그라운드에서 음성을 켜거나 끌 수 있음

Debug

Debug(디버그) 레벨을 설정하여 WebRTC의 세부적인 로그를 출력할 수 있습니다. 해당 레벨 모드는 RemonConfig를 사용하여 통화 또는 방송을 생성하는 경우에만 가능합니다. VERBOSE 로그 레벨로 갈수록 더욱 자세한 내용을 확인할 수 있습니다.

코드예제Debug Syntax

remonConfig.debugMode = true
remonConfig.debugLevel = .error  // NONE, ERROR, WARNING, INFO, VERBOSE 순으로 로그 레벨을 설정 

디버그 레벨
구분 설정
none 로그를 출력하지 않음
error 오류를 일으킨 문제뿐만 아니라 더 낮은 레벨의 메시지도 목록에 출력
warning 아직 오류는 아니지만 발생할 수 있는 경고성 로그와 더 낮은 레벨(ERROR)의 메시지도 목록에 출력
info 예상할 수 있는 진행사항 또는 상태 정보 이상의 로그와 더 낮은 레벨(WARNING, ERROR)의 메시지도 목록에 출력
verbose 모든 로그의 메시지 출력
이 문서가 만족스러운 이유를 알려주세요.
이 문서에 아쉬운 점을 알려주세요.
평가해주셔서 감사합니다.

더 자세한 의견은 documentation@kakaoenterprise.com 으로 제보해주세요.