Google Cloud Video Stitcher API에 등록된 라이브 스트림 재생
이 가이드에서는 CAF 웹 수신기용 IMA DAI SDK를 사용하여 Google Cloud Video Stitcher API에 등록된 이벤트의 라이브 스트림을 요청하고 재생하는 방법과 재생 중에 광고 시점을 삽입하는 방법을 설명합니다.
이 가이드에서는 전체 서비스 DAI의 기본 예시를 바탕으로 Google Cloud Video Stitcher API에 등록된 스트림에 대한 지원을 추가하는 방법을 설명합니다.
계속하기 전에 CAF 웹 수신기에서 스트리밍 형식을 지원하는지 확인합니다.
다른 플랫폼과 통합하거나 IMA 클라이언트 측 SDK를 사용하는 방법에 대한 자세한 내용은 양방향 미디어 광고 SDK를 참조하세요.
배경
이 가이드를 사용하기 전에 Chromecast 애플리케이션 프레임워크의 웹 수신기 프로토콜에 익숙해야 합니다.
이 가이드에서는 메시지 인터셉터, MediaInformation
객체와 같은 CAF 수신기 개념에 대한 기본 수준의 지식이 있고 전송 명령어와 제어 도구를 사용하여 CAF 발신기를 에뮬레이션한다고 가정합니다.
앱 구성요소 및 아키텍처
IMA CAF DAI SDK와 함께 Google Cloud Video Stitcher API를 사용하여 라이브 스트림 재생을 구현하려면 이 가이드의 설명대로 두 가지 주요 구성요소가 필요합니다.
VideoStitcherLiveStreamRequest
: Google 서버에 대한 스트림 요청을 정의하는 객체입니다. 이 요청은 Cloud Video Stitcher API 인스턴스, 라이브 구성 ID, 기타 선택적 매개변수를 지정합니다.StreamManager
: 동영상 스트림과 IMA DAI SDK 간의 통신(예: 추적 핑 실행 및 스트림 이벤트를 게시자에게 전달)을 처리하는 객체입니다.
기본 요건
IMA SDK에는 다음 변수가 필요합니다.
라이브 구성 ID: Video Stitcher API 라이브 구성을 만들 때 지정한 라이브 구성 ID입니다.
LIVE_CONFIG_ID
위치: 라이브 구성이 생성된 Google Cloud 리전입니다.
LOCATION
프로젝트 번호: Video Stitcher API를 사용하는 Google Cloud 프로젝트 번호입니다.
PROJECT_NUMBER
OAuth 토큰: Video Stitcher 사용자 역할이 있는 서비스 계정의 단기 OAuth 토큰입니다. 서비스 계정의 단기 사용자 인증 정보 만들기에 대해 자세히 알아보세요.
OAUTH_TOKEN
네트워크 코드: 광고 요청에 사용되는 Google Ad Manager 네트워크 코드입니다.
NETWORK_CODE
커스텀 애셋 키: Video Stitcher API를 사용하여 라이브 스트림 이벤트 구성을 만드는 과정에서 생성된 Google Ad Manager 커스텀 애셋 키입니다.
CUSTOM_ASSET_KEY
커스텀 전송 수신기에는 다음이 필요합니다.
허용 목록에 테스트 기기가 있는 전송 개발자 콘솔 계정
전송 개발자 콘솔에 등록되었으며 이 가이드에서 제공하는 코드를 호스팅하도록 수정할 수 있는 호스팅된 웹 수신기 앱
웹 수신기 앱을 사용하도록 구성된 전송 앱. 이 예시를 위해 이 가이드에서는 전송 명령어 및 제어 도구를 발신기로 사용합니다.
스트림 데이터를 수신기에 전달할 발신기 준비
먼저 플랫폼의 MediaInformation
객체에 다음 필드를 포함하여 웹 수신기에 로드 요청을 보내는 발신기 앱을 구성합니다.
필드 | 목차 | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
contentId
|
전송 참고 문서에서 정의된 이 미디어 항목의 고유 식별자입니다. 이 ID를 같은 미디어 큐의 여러 항목에 재사용하면 안 됩니다.
|
||||||||||||||
contentUrl
|
DAI 스트림이 로드할 수 없는 경우 재생할 선택적 백업 스트림 URL입니다.
|
||||||||||||||
contentType
|
DAI 스트림이 로드할 수 없는 경우 재생할 백업 스트림 URL의 선택적 Mimetype입니다.
|
||||||||||||||
streamType
|
이 값에 사용되는 문자열 리터럴이나 상수는 발신기 플랫폼에 따라 다릅니다.
|
||||||||||||||
customData
|
|
다음은 시작하는 데 도움이 되는 몇 가지 코드 샘플입니다.
웹
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 MediaInfo
객체를 만든 후 로드 요청 웹 수신기에 보냅니다.
// Create mediaInfo object
const mediaInfo = new chrome.cast.media.MediaInfo("CONTENT_ID");
mediaInfo.contentUrl = "BACKUP_STREAM_URL";
mediaInfo.contentType = "BACKUP_STREAM_MIMETYPE";
mediaInfo.streamType = chrome.cast.media.StreamType.LIVE;
mediaInfo.customData = {
liveConfigID: "LIVE_CONFIG_ID",
region: "LOCATION",
projectNumber: "PROJECT_NUMBER",
oAuthToken: "OAUTH_TOKEN",
networkCode: "NETWORK_CODE",
customAssetKey: "CUSTOM_ASSET_KEY"
};
// Make load request to cast web receiver
const castSession = cast.framework.CastContext.getInstance().getCurrentSession();
const request = new chrome.cast.media.LoadRequest(mediaInfo);
castSession.loadMedia(request).then(
() => { console.log('Load succeed'); },
(errorCode) => { console.log('Error code: ' + errorCode); });
Android
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 MediaInfo
객체를 만든 후 로드 요청 웹 수신기에 보냅니다.
JSONObject customData = new JSONObject()
.put("liveConfigID", "LIVE_CONFIG_ID")
.put("region", "LOCATION")
.put("projectNumber", "PROJECT_NUMBER")
.put("oAuthToken", "OAUTH_TOKEN")
.put("networkCode", "NETWORK_CODE")
.put("customAssetKey", "CUSTOM_ASSET_KEY");
MediaInfo mediaInfo = MediaInfo.Builder("CONTENT_ID")
.setContentUrl("BACKUP_STREAM_URL")
.setContentType("BACKUP_STREAM_MIMETYPE")
.setStreamType(MediaInfo.STREAM_TYPE_LIVE)
.setCustomData(customData)
.build();
RemoteMediaClient remoteMediaClient = mCastSession.getRemoteMediaClient();
remoteMediaClient.load(new MediaLoadRequestData.Builder().setMediaInfo(mediaInfo).build());
iOS(Obj-C)
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 GCKMediaInformation
객체를 만든 후 로드 요청 웹 수신기에 보냅니다.
NSURL url = [NSURL URLWithString:@"BACKUP_STREAM_URL"];
NSDictionary *customData = @{
@"liveConfigID": @"LIVE_CONFIG_ID",
@"region": @"LOCATION",
@"projectNumber": @"PROJECT_NUMBER",
@"oAuthToken": @"OAUTH_TOKEN",
@"networkCode": @"NETWORK_CODE",
@"customAssetKey": @"CUSTOM_ASSET_KEY"
};
GCKMediaInformationBuilder *mediaInfoBuilder =
[[GCKMediaInformationBuilder alloc] initWithContentID: @"CONTENT_ID"];
mediaInfoBuilder.contentURL = url;
mediaInfoBuilder.contentType = @"BACKUP_STREAM_MIMETYPE";
mediaInfoBuilder.streamType = GCKMediaStreamTypeLive;
mediaInfoBuilder.customData = customData;
self.mediaInformation = [mediaInfoBuilder build];
GCKRequest *request = [self.sessionManager.currentSession.remoteMediaClient loadMedia:self.mediaInformation];
if (request != nil) {
request.delegate = self;
}
iOS(Swift)
전송 웹 발신기에서 이러한 값을 구성하려면 먼저 필수 데이터가 있는 GCKMediaInformation
객체를 만든 후 로드 요청 웹 수신기에 보냅니다.
let url = URL.init(string: "BACKUP_STREAM_URL")
guard let mediaURL = url else {
print("invalid mediaURL")
return
}
let customData = [
"liveConfigID": "LIVE_CONFIG_ID",
"region": "LOCATION",
"projectNumber": "PROJECT_NUMBER",
"oAuthToken": "OAUTH_TOKEN",
"networkCode": "NETWORK_CODE",
"customAssetKey": "CUSTOM_ASSET_KEY"
]
let mediaInfoBuilder = GCKMediaInformationBuilder.init(contentId: "CONTENT_ID")
mediaInfoBuilder.contentURL = mediaUrl
mediaInfoBuilder.contentType = "BACKUP_STREAM_MIMETYPE"
mediaInfoBuilder.streamType = GCKMediaStreamType.Live
mediaInfoBuilder.customData = customData
mediaInformation = mediaInfoBuilder.build()
guard let mediaInfo = mediaInformation else {
print("invalid mediaInformation")
return
}
if let request = sessionManager.currentSession?.remoteMediaClient?.loadMedia(mediaInfo) {
request.delegate = self
}
CAC 도구
전송 명령어 및 제어 도구에서 이러한 값을 구성하려면 미디어 로드 탭을 클릭하고 커스텀 로드 요청 유형을 LOAD로 설정합니다. 그런 다음 텍스트 영역의 JSON 데이터를 다음 JSON으로 바꿉니다.
{
"media": {
"contentId": "CONTENT_ID",
"contentUrl": "BACKUP_STREAM_URL",
"contentType": "BACKUP_STREAM_MIMETYPE",
"streamType": "LIVE",
"customData": {
"liveConfigID": "LIVE_CONFIG_ID",
"region": "LOCATION",
"projectNumber": "PROJECT_NUMBER",
"oAuthToken": "OAUTH_TOKEN",
"networkCode": "NETWORK_CODE",
"customAssetKey": "CUSTOM_ASSET_KEY"
}
}
}
이 커스텀 부하 요청을 수신기에게 전송하여 나머지 단계를 테스트할 수 있습니다.
커스텀 CAF 웹 수신기 만들기
CAF SDK 커스텀 웹 수신기 가이드와 같이 커스텀 웹 수신기를 만듭니다.
수신기 코드는 다음과 같이 표시됩니다.
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js">
</script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance()
castContext.start();
</script>
</body>
</html>
IMA DAI SDK 가져오기 및 플레이어 관리자 가져오기
스크립트에서 CAF를 로드한 직후에 스크립트 태그를 추가하여 CAF용 IMA DAI SDK를 웹 수신기로 가져옵니다. 그런 다음 수신기를 시작하기 전에 뒤에 오는 스크립트 태그에 수신기 컨텍스트와 플레이어 관리자를 상수로 저장합니다.
<html>
<head>
<script
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
castContext.start();
</script>
</body>
</html>
IMA 스트림 관리자 초기화
IMA 스트림 관리자를 초기화합니다.
<html>
<head>
<script type="text/javascript"
src="//www.gstatic.com/cast/sdk/libs/caf_receiver/v3/cast_receiver_framework.js"></script>
<script src="//imasdk.googleapis.com/js/sdkloader/cast_dai.js"></script>
</head>
<body>
<cast-media-player></cast-media-player>
<script>
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
castContext.start();
</script>
</body>
</html>
스트림 관리자 로드 인터셉터 만들기
미디어 항목이 CAF로 전달되기 전에 LOAD 메시지 인터셉터에서 스트림 요청을 만듭니다.
const castContext = cast.framework.CastReceiverContext.getInstance();
const playerManager = castContext.getPlayerManager();
const streamManager = new google.ima.cast.dai.api.StreamManager();
/**
* Creates a livestream request object for the Video Stitcher API.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => { /* ... */};
/**
* Initates a DAI stream request for the final stream manifest.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {Promise<LoadRequestData>} a promise that resolves to an updated castRequest, containing the DAI stream manifest
*/
const createDAICastRequest = (castRequest) => {
return streamManager.requestStream(castRequest, createStreamRequest(castRequest))
.then((castRequestWithStreamData) => {
console.log('Successfully made DAI stream request.');
return castRequestWithStreamData;
})
.catch((error) => {
console.log('Failed to make DAI stream request.');
// CAF will automatically fallback to the content URL
// that it can read from the castRequest object.
return castRequest;
});
};
playerManager.setMessageInterceptor(
cast.framework.messages.MessageType.LOAD, createDAICastRequest);
castContext.start();
스트림 요청 만들기
createStreamRequest
함수를 완료하여 CAF 로드 요청에 따라 Video Stitcher API 라이브 스트림 요청을 만듭니다.
/**
* Creates a livestream request object for the Video Stitcher API.
* @param {!LoadRequestData} castRequest The request object from the cast sender
* @return {StreamRequest} an IMA stream request
*/
const createStreamRequest = (castRequest) => {
const streamRequest = new google.ima.cast.dai.api.VideoStitcherLiveStreamRequest();
const customData = castRequest.media.customData;
streamRequest.liveStreamEventId = customData.liveConfigID;
streamRequest.region = customData.region;
streamRequest.projectNumber = customData.projectNumber;
streamRequest.oAuthToken = customData.oAuthToken;
streamRequest.networkCode = customData.networkCode;
streamRequest.customAssetKey = customData.customAssetKey;
return streamRequest;
};
(선택사항) 스트리밍 세션 옵션 추가
VideoStitcherLiveStreamRequest.videoStitcherSessionOptions
를 사용하여 기본 Cloud Video Stitcher API 구성을 재정의하는 세션 옵션을 추가해 스트림 요청을 맞춤설정합니다.
인식할 수 없는 옵션을 제공하면 Cloud Video Stitcher API에서 HTTP 400 오류로 응답합니다. 도움이 필요하면 문제 해결 가이드를 참조하세요.
예를 들어 다음 코드 스니펫으로 매니페스트 옵션을 재정의할 수 있으며 이 옵션에서는 가장 낮은 비트 전송률에서 가장 높은 비트 전송률 순으로 변환되는 스트림 매니페스트 2개를 요청합니다.
...
// The following session options are examples. Use session options
// that are compatible with your video stream.
streamRequest.videoStitcherSessionOptions = {
"manifestOptions": {
"bitrateOrder": "ascending"
}
};
streamManager.requestStream(streamRequest);