2. 스트리밍 재생
JWT URL을 사용하여 KollusPlayerView를 생성하고 콘텐츠를 디바이스에 직접 실시간 스트리밍 재생하는 방법을 설명합니다.
로컬에 다운로드된 콘텐츠 재생과 달리, 스트리밍 시에는 매 재생 시점마다 고객사 서버에서 새로 발급받은 일회성(One-time) URL을 사용합니다.
이 문서의 모든 예제 코드는 공식 샘플 앱인 kollus_player_ios를 바탕으로 작성되었습니다.
콘텐츠 전달 방식
Kollus 서비스는 채널 설정에 따라 세 가지 전달 방식 중 하나로 콘텐츠를 제공합니다.
애플리케이션 클라이언트 레이어에서는 동일한 JWT URL을 전달받아 KollusPlayerView(contentURL:) 인스턴스를 빌드하므로 별도의 코드 분기를 구현하지 않아도 됩니다.
다만, 전달 방식에 따라 가변 비트레이트(ABR) 작동 방식이나 DRM 검증 및 라이선스 발급 흐름, AirPlay 호환성 정책이 달라지므로 인프라 채널 구성을 파악하고 있으면 디버깅과 최적화에 도움이 됩니다.
| 전달 방식 | 기본값 | 설명 | 채널 설정 |
|---|---|---|---|
| MP4 Progressive Download | ◯ | 단일 MP4 파일을 실시간으로 내려받으며 동시 재생합니다. 가변 비트레이트(ABR)를 지원하지 않는 단일 품질 방식입니다. | 별도 설정 없음 (기본 채널) |
| HLS 스트리밍 | - | 매니페스트(.m3u8)와 세그먼트 파일로 구성됩니다. iOS AVKit 시스템에 최적화되어 있으며 네트워크 대역폭 변화에 맞춰 실시간으로 품질이 자동 전환(ABR)됩니다. | 콘솔 채널 설정 내 HLS 출력 활성화 |
| Multi-DRM (FairPlay) | - | HLS 미디어 구조에 FairPlay 보안 라이선스 발급 흐름이 결합된 형태입니다. 내부적으로 PallyConFPSSDK 컴포넌트가 연동되어 동작합니다. | 콘솔 채널 설정 내 DRM 정책 등록 |
애플리케이션 소스 코드에서는 KollusPlayerView(contentURL: jwtUrl) 생성자를 호출하는 것만으로 세 가지 방 식을 모두 재생할 수 있습니다.
실제 스트리밍 전달 방식은 Kollus 서버 측에서 채널 설정에 따라 결정되어 클라이언트로 전달됩니다.
전달 방식 상세 비교
| 비교 영역 | MP4 Progressive Download | HLS 스트리밍 | Multi-DRM |
|---|---|---|---|
| ABR 옵션 제어 | 대역폭 설정 영향 없음 | 적용됨 (iOS AVKit 기본 정책 준수) | 적용됨 (iOS AVKit 기본 정책 준수) |
| 탐색(Seek) 동작 | HTTP Byte-Range 요청 기반 제어 | 세그먼트 단위의 위치 탐색 | 세그먼트 단위의 위치 탐색 |
| 추가 프레임워크 통합 | 외부 의존성 없음 | 외부 의존성 없음 | PallyConFPSSDK.framework 라이브러리 빌드 포함 필수 |
| 라이선스 발급 흐름 | 라이선스 연동 없음 | 라이선스 연동 없음 | FairPlay 인증서 및 SPC 데이터 추출 후 CKC 교환 단계 수행 |
| AirPlay / 외부 출력 | 외부 화면 출력 허용 | 외부 화면 출력 허용 | 콘텐츠 DRM 정책에 따라 출력 차단 제어 연동 |
대부분의 고객사는 서비스 초기 단계에서 MP4 Progressive 방식으로 시작하여, 트래픽이 증가하거나 가변 비트레이트(ABR) 환경이 필요한 시점에 HLS 스트리밍으로 전환합니다. 이후 저작권 보호 및 DRM 보안이 필수적인 콘텐츠에 한해 Multi-DRM (FairPlay) 채널을 추가로 분리하여 운영하는 패턴이 일반적입니다.
기본 스트리밍 재생
KollusPlayer SDK의 KollusPlayerView에 실시간으로 재생할 인프라 환경과 델리게이트 객체들을 매칭한 후, 프로젝트 UIView 계층에 추가하여 실시간 스트리밍 재생을 시작합니다.
class PlayerViewController: UIViewController {
var playerView: KollusPlayerView!
// 1. 데이터 소스 지정 (JWT URL)
func play(streamingURL: String) {
DispatchQueue.main.async { [weak self] in
self?.playerView = KollusPlayerView(contentURL: streamingURL)
DispatchQueue.global().async {
self?.initPlayerView()
}
}
}
func initPlayerView() {
// 2. 인스턴스 내부 환경 설정 및 전용 델리게이트 수신 객체 연결
playerView.debug = false
playerView.storage = StorageManager.shared.storage // KollusStorage 연결
playerView.delegate = self // KollusPlayerDelegate (재생 라이프사이클)
playerView.DRMDelegate = self // KollusPlayerDRMDelegate (Multi-DRM)
playerView.LMSDelegate = self // KollusPlayerLMSDelegate (시청 통계)
playerView.bookmarkDelegate = self // KollusPlayerBookmarkDelegate (북마크 감지)
playerView.scalingMode = .scaleAspectFit
playerView.proxyPort = LICENSE_KEY_PROXY_PORT // 라이선스 키 발급 시 전달받은 포트
// 3. UIView 계층에 추가
view.addSubview(playerView)
playerView.frame = view.bounds
// 4. 재생 준비
// prepareToPlayWithError: 사용 권장 ([재생 준비 완료 검증] 참고)
}
}
KollusPlayerView 초기화 옵션
| 초기화 생성자 | 용도 |
|---|---|
KollusPlayerView(contentURL: String) | 스트리밍 재생 (JWT URL) |
KollusPlayerView(mediaContentKey: String) | 오프라인 재생 (다운로드된 콘텐츠) |
스트리밍/오프라인 모드는 인스턴스 생성 시점에 결정됩니다. 같은 인스턴스로 두 모드를 전환할 수 없으므로, 콘텐츠 변경 시에는 새 KollusPlayerView를 생성해 attach하는 패턴이 일반적입니다.
proxyPort 지정
playerView.proxyPort 속성은 SDK가 내부 통신을 처리하기 위해 사용하는 포트입니다.
키 발급 시 함께 전달받은 프록시 포트 번호를 그대로 지정하세요. 임의의 값으로 설정하면 정상적인 스트리밍 재생이 이루어지지 않습니다.