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가 내부 통신을 처리하기 위해 사용하는 포트입니다.
키 발급 시 함께 전달받은 프록시 포트 번호를 그대로 지정하세요. 임의의 값으로 설정하면 정상적인 스트리밍 재생이 이루어지지 않습니다.
재생 준비 완료 검증
KollusPlayerView의 재생 준비 상태 추적은 단순 prepareToPlay 호출 대신, 델리게이트 콜백 메서드인 prepareToPlayWithError:를 통해 처리하는 방식을 권장합니다.
단순 호출로는 플레이어 초기화 단계에서 유발되는 정밀한 내부 오류를 포착하기 어렵지만, prepareToPlayWithError: 방식을 사용하면 준비 완료 혹은 실패 시점에 구체적인 NSError 객체가 함께 수신되므로 구체적인 대응이 가능합니다.
func kollusPlayerView(_ playerView: KollusPlayerView,
prepareToPlayWithError error: Error?) {
if let error = error {
// 초기화 실패 — 에러 코드에 따라 사용자 안내
let nsError = error as NSError
UIApplication.presentErrorViewController(
title: "재생 준비 실패 (\(nsError.code))",
errorDescription: nil,
errorReason: error.localizedDescription)
return
}
// 재생 준비 완료 — 제어 메서드를 연동하여 자동 재생을 실행하거나 사용자 입력을 대기합니다.
}
플레이어 주요 속성
재생 제어
다음 속성들은 값을 직접 설정(set)하여 재생을 제어합니다.
| 속성 | 타입 | 설명 |
|---|---|---|
contentURL | NSString | 스트리밍 재생 URL (초기화 시 지정) |
currentPlaybackTime | NSTimeInterval | 현재 재생 위치 (set으로 탐색 실행) |
currentPlaybackRate | float | 배속 (1.0, 1.25, 1.5, 2.0 등) |
scalingMode | KollusPlayerContentMode | 화면 출력 모드 |
repeatMode | KollusPlayerRepeatMode | 재생 구간 반복 모드 |
playerContentFrame | CGRect | 플레이어 화면 영역 |
AIRateEnable | BOOL | AI배속 지원 여부 |
최대 10배속까지 설정 가능하지만, currentPlaybackRate 값이 2.0을 초과하면 오디오-비디오의 싱크가 어긋나는 현상이나 일시적인 품질 저하가 발생할 수 있습니다.
탐색(Seek) 및 재생 제어 예시
// 탐색(Seek)
playerView.currentPlaybackTime = 60.0 // 60초 시점으로 재생 위치 이동
// 재생속도(배속)
playerView.currentPlaybackRate = 1.5 // 1.5배속으로 재생
// 구간 반복
playerView.repeatMode = .all // 전체 반복 (.none: 해제, .one: 단일 콘텐츠 반복)
상태 정보 조회
다음 속성들은 읽기 전용으로, 현재 플레이어 상태를 조회하는 데 사용합니다.
| 속성 | 설명 |
|---|---|
isPreparedToPlay | 재생 준비 완료 여부 |
isPlaying | 실시간 재생 중 여부 |
isBuffering | 버퍼링 진행 중 여부 |
isSeeking | 탐색(Seek) 중 여부 |
isScrolling | 화면 이동(Scroll) 중 여부 |
isAudioOnly | 오디오 전용 콘텐츠 여부 |
naturalSize | 원본 영상 크기 (CGSize) |
screenConnectEnabled | 외부 디스플레이 출력 허용 여부 |