1. 개요
이 Codelab에서는 Cast Ad Breaks API를 사용하는 맞춤 웹 수신기 앱을 빌드하는 방법을 알아봅니다.
Google Cast란 무엇인가요?
사용자는 Google Cast를 사용하여 휴대기기의 콘텐츠를 TV로 전송할 수 있습니다. 그런 다음, 휴대기기를 리모컨으로 사용해 TV에서 재생 중인 미디어를 제어할 수 있습니다.
Google Cast SDK를 사용하면 앱을 확장하여 TV 또는 사운드 시스템을 제어할 수 있습니다. Cast SDK를 사용하면 Google Cast 디자인 체크리스트에 따라 필요한 UI 구성요소를 추가할 수 있습니다.
Google Cast 디자인 체크리스트는 지원되는 모든 플랫폼에서 Cast 사용자 환경을 간단하고 예측 가능하게 만들기 위해 제공됩니다.
무엇을 빌드하게 되나요?
이 Codelab을 완료하면 새로운 Break API를 활용하는 Cast 수신기를 빌드하게 됩니다.
학습할 내용
- Cast용 콘텐츠에 VMAP 및 VAST 중단을 포함하는 방법
- 브레이크 클립을 건너뛰는 방법
- 탐색 시 기본 광고 시간 동작을 맞춤설정하는 방법
필요한 항목
- 최신 Chrome 브라우저
- Firebase 호스팅 또는 ngrok와 같은 HTTPS 호스팅 서비스
- 인터넷에 액세스할 수 있도록 설정된 Chromecast 또는 Android TV와 같은 Google Cast 기기
- HDMI 입력이 지원되는 TV나 모니터 또는 Google Home Hub
환경
- 웹 개발에 관한 사전지식이 있어야 합니다.
- Cast 전송기 및 수신기 애플리케이션을 빌드한 이전 경험
본 가이드를 어떻게 사용하실 계획인가요?
웹 앱 빌드 경험을 평가해 주세요.
2. 샘플 코드 가져오기
모든 샘플 코드를 컴퓨터에 다운로드할 수 있습니다.
그런 다음 다운로드한 ZIP 파일의 압축을 풉니다.
3. 로컬에서 수신기 배포
Cast 기기에서 웹 수신기를 사용하려면 Cast 기기가 연결할 수 있는 위치에서 호스팅되어야 합니다. https를 지원하는 서버가 이미 있는 경우 다음 안내를 건너뛰고 URL을 기록해 두세요. 다음 섹션에서 필요합니다.
사용할 수 있는 서버가 없다면 Firebase 호스팅 또는 ngrok를 사용할 수 있습니다.
서버 실행
원하는 서비스를 설정한 후 app-start
로 이동하여 서버를 시작합니다.
호스팅된 수신자의 URL을 기록해 둡니다. 다음 섹션에서 사용합니다.
4. Cast 개발자 콘솔에 애플리케이션 등록
이 Codelab에 내장된 맞춤 수신기를 Chromecast 기기에서 실행하려면 애플리케이션을 등록해야 합니다. 애플리케이션을 등록하면 발신기 애플리케이션이 API 호출(예: 수신기 애플리케이션 실행)을 수행하는 데 사용해야 하는 애플리케이션 ID를 받게 됩니다.
'새 애플리케이션 추가'를 클릭합니다.
'Custom Receiver'를 선택합니다. 이는 우리가 만드는 화면입니다.
새 수신자의 세부정보를 입력합니다. 마지막으로 사용한 URL을 사용해야 합니다.
마지막 섹션에서 살펴보겠습니다 새 수신기에 할당된 애플리케이션 ID를 기록해 둡니다.
게시하기 전에 수신기 애플리케이션에 액세스할 수 있도록 Google Cast 기기를 등록해야 합니다. 수신기 애플리케이션을 게시하면 모든 Google Cast 기기에서 사용할 수 있습니다. 이 Codelab에서는 게시되지 않은 수신기 애플리케이션으로 작업하는 것이 좋습니다.
'새 기기 추가'를 클릭합니다.
Cast 기기 뒷면에 인쇄된 일련번호를 입력하고 구체적인 이름을 지정합니다. Google Cast SDK 개발자 콘솔에 액세스할 때 Chrome에서 화면을 전송하여 일련번호를 확인할 수도 있습니다.
수신기와 기기를 테스트할 준비가 되려면 5~15분 정도 걸립니다. 5~15분 후에 Cast 기기를 재부팅해야 합니다.
5. 시작 프로젝트 준비
이 Codelab을 시작하기 전에 새 광고 기능에 대한 개요를 제공하는 광고 개발자 가이드를 참고하면 도움이 될 수 있습니다.
다운로드한 시작 앱에 Google Cast 지원 기능을 추가해야 합니다. 다음은 이 Codelab에서 사용할 Google Cast 용어입니다.
- 발신기 앱은 휴대기기 또는 노트북에서 실행됩니다.
- 수신기 앱은 Google Cast 기기에서 실행됩니다.
이제 좋아하는 텍스트 편집기를 사용하여 시작 프로젝트 위에 빌드할 준비가 되었습니다.
- 샘플 코드 다운로드에서
app-start
디렉터리를 선택합니다. js/receiver.js
및 index.html을 엽니다.
이 Codelab을 진행하는 동안 http-server
가 변경사항을 선택합니다. 표시되지 않으면 http-server
를 종료했다가 다시 시작해 보세요.
발신자의 경우 CAF 수신기 디버깅도 사용하여 전송 세션을 시작합니다. 수신기는 스트림 재생을 자동으로 시작하도록 설계되었습니다.
앱 디자인
수신기 앱은 전송 세션을 초기화하고 발신자의 LOAD 요청 (예: 미디어 재생 명령어)이 도착할 때까지 대기합니다.
앱은 index.html
에 정의된 기본 뷰 1개와 수신기가 작동하는 모든 로직을 포함하는 js/receiver.js
라는 자바스크립트 파일로 구성됩니다.
index.html
이 html 파일에는 수신기 앱의 모든 UI가 포함되어 있습니다. 지금은 기본적으로 비어 있습니다.
수신기.js
이 스크립트는 수신기 앱의 모든 로직을 관리합니다. 지금은 기본 CAF 수신기가 포함되어 있습니다.
6. 콘텐츠에 VMAP 추가
시작하려면 Chrome에서 웹 발신자를 엽니다. Cast SDK 개발자 콘솔에서 제공된 수신자 애플리케이션 ID를 입력하고'설정'을 클릭합니다.
수신기에서 콘텐츠에 광고를 포함하기 위한 로직을 추가해야 합니다.
다음 줄을 js/receiver.js
파일에 복사합니다. 여기에는 DoubleClick의 샘플 VMAP 태그 링크와 무작위 순서 지정이 포함되어 있습니다.
const vmapUrl = "https://pubads.g.doubleclick.net/gampad/ads?sz=640x480&iu=/124319096/external/ad_rule_samples&ciu_szs=300x250&ad_rule=1&impl=s&gdfp_req=1&env=vp&output=vmap&unviewed_position_start=1&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&cmsid=496&vid=short_onecue&correlator=" + Math.floor(Math.random() * Math.pow(10, 10));
js/receiver.js file
에서 playerManager.setMessageInterceptor
함수를 찾고 함수의 마지막 return request;
줄 앞에 다음을 추가합니다.
request.media.vmapAdsRequest = {
adTagUrl: vmapUrl,
};
참고: 위의 vmapAdsRequest
에 할당된 객체는 VastAdsRequest 객체의 약식 버전입니다.
js/receiver.js
에 변경사항을 저장하고 페이지의 아무 곳이나 마우스 오른쪽 버튼으로 클릭한 다음 '전송'을 선택하여 웹 발신자의 전송 세션을 시작하세요. 광고 스트림이 즉시 재생됩니다.
7. 콘텐츠에 VAST 추가
위의 VMAP 코드를 구현한 경우 주석으로 처리하세요. 콘텐츠에서 VAST 광고를 구현하는 방법을 알아보겠습니다.
다음을 js/receiver.js
파일에 복사합니다. DoubleClick의 VAST 브레이크 클립 6개와 무작위 순서 지정이 포함되어 있습니다. 이러한 브레이크 클립은 5개의 광고 시점에 할당됩니다. 각 광고 시점의 위치도 지정됩니다.
const addVASTBreaksToMedia = (mediaInformation) => {
mediaInformation.breakClips = [
{
id: "bc1",
title: "bc1 (Pre-roll)",
vastAdsRequest: {
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=preroll&pod=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
}
},
{
id: "bc2",
title: "bc2 (Mid-roll)",
vastAdsRequest: {
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
}
},
{
id: "bc3",
title: "bc3 (Mid-roll)",
vastAdsRequest: {
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
}
},
{
id: "bc4",
title: "bc4 (Mid-roll)",
vastAdsRequest: {
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
}
},
{
id: "bc5",
title: "bc5 (Mid-roll)",
vastAdsRequest: {
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&cue=15000&vad_type=linear&vpos=midroll&pod=2&mridx=1&rmridx=1&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
}
},
{
id: "bc6",
title: "bc6 (Post-roll)",
vastAdsRequest: {
adTagUrl: 'https://pubads.g.doubleclick.net/gampad/ads?slotname=/124319096/external/ad_rule_samples&sz=640x480&ciu_szs=300x250&cust_params=deployment%3Ddevsite%26sample_ar%3Dpremidpost&url=&unviewed_position_start=1&output=xml_vast3&impl=s&env=vp&gdfp_req=1&ad_rule=0&vad_type=linear&vpos=postroll&pod=3&ppos=1&lip=true&min_ad_duration=0&max_ad_duration=30000&vrid=6256&correlator=' + Math.floor(Math.random() * Math.pow(10, 10)) + '&video_doc_id=short_onecue&cmsid=496&kfa=0&tfcd=0'
}
}
];
mediaInformation.breaks = [
{
id: "b1",
breakClipIds: ["bc1"],
position: 0
},
{
id: "b2",
breakClipIds: ["bc2"],
position: 15
},
{
id: "b3",
breakClipIds: ["bc3","bc4"],
position: 60
},
{
id: "b4",
breakClipIds: ["bc5"],
position: 100
},
{
id: "b5",
breakClipIds: ["bc6"],
position: -1
}
];
};
참고: 중단의 breakClipIds
속성은 배열입니다. 즉, 각 브레이크에 여러 브레이크 클립을 할당할 수 있습니다.
js/receiver.js file
에서 LOAD 메시지 인터셉터 즉, playerManager.setMessageInterceptor
로 시작하는 줄을 찾아 함수의 마지막 return request;
줄 앞에 다음을 추가합니다.
addVASTBreaksToMedia(request.media);
js/receiver.js
에 변경사항을 저장하고 페이지의 아무 곳이나 마우스 오른쪽 버튼으로 클릭한 다음 '전송'을 선택하여 웹 발신자의 전송 세션을 시작하세요. 광고 스트림이 즉시 재생됩니다.
8. 광고 시점 건너뛰기
CAF에는 광고 동작에 대한 맞춤 비즈니스 규칙을 구현하는 데 도움이 되는 새로운 BreakManager 클래스가 있습니다. 고객이 일정 기간이 지난 후 광고를 건너뛸 수 있도록 유예 기간을 설정하려 한다고 가정해 보겠습니다.
이 예시의 발신자에게는 미디어 컨트롤이 없습니다. 스트림이 프리롤 이후, 첫 번째 미드롤 시점(15초)에 재생되도록 시작 오프셋 10초를 추가해 보겠습니다.
playerManager.setMessageInterceptor
를 찾아 return request
앞에 다음 줄을 추가합니다.
request.currentTime = 10;
receiver.js
파일을 저장하고 Cast 세션을 시작합니다. 콘텐츠가 10초 동안 로드되면 5초 후에 광고가 재생됩니다.
이제 15초 지점에서 미드롤을 건너뛰는 규칙을 추가해 보겠습니다.
광고 시점 로드를 위한 인터셉터를 설정하려면 BreakManager의 인스턴스가 필요합니다. context
및 playerManager
변수가 포함된 줄 뒤에 있는 js/receiver.js
파일의 다음 줄을 복사합니다.
const breakManager = playerManager.getBreakManager();
이제 30초 전에 발생하는 광고 시간을 무시하는 규칙을 사용하여 인터셉터를 설정해 보겠습니다. 이 인터셉터는 PlayerManager의 LOAD 인터셉터와 작동 방식이 비슷하지만 BreakClips를 로드하는 데만 사용됩니다.
다음을 js/receiver.js
파일에 복사합니다.
breakManager.setBreakClipLoadInterceptor((breakClip, breakCtx) => {
/** Below code will skip playback of break clips if the break position is less than 30 **/
let breakObj = breakCtx.break;
if(breakObj.position < 30)
return null;
else
return breakClip;
});
참고: 여기에서 건너뛰어야 하는 BreakClips에 대해 null을 반환합니다.
js/receiver.js
에 변경사항을 저장하고 페이지의 아무 곳이나 마우스 오른쪽 버튼으로 클릭한 다음 '전송'을 선택하여 웹 발신자의 전송 세션을 시작하세요.
스트림 재생이 시작되지만 15초 지점에 있던 광고 블록을 건너뜁니다.
9. 중단 탐색 동작 맞춤설정
사용자가 앞으로 탐색하면 콘텐츠 재생이 탐색 대상 위치에서 재생되기 전에 탐색에서 찾지 못한 마지막 중단이 재생됩니다. 사용자가 뒤로 탐색하면 휴식 시간이 재생되지 않습니다. 이는 기본 중단 동작입니다.
탐색 시 재생할 광고 시간을 맞춤설정하기 위해 BreakManager를 사용합니다. BreakManager의 setBreakSeekInterceptor를 사용하여 원하는 맞춤 동작을 지정합니다. 탐색 작업이 실행될 때마다 setBreakSeekInterceptor가 호출됩니다.
콜백 함수를 setBreakSeekInterceptor에 전달합니다. 찾기 함수 위치와 탐색 대상 위치 사이의 모든 줄바꿈이 포함된 객체가 콜백 함수에 전달됩니다.
이제 탐색 시작 위치와 탐색 위치 사이에 아직 관찰되지 않은 중단을 재생하는 규칙이 있는 인터셉터를 설정합니다.
다음을 js/receiver.js
파일에 복사합니다.
breakManager.setBreakSeekInterceptor(function(breakSeekData) {
/**
*
* Below code will play an unwatched break between seekFrom and seekTo position
* Note: If the position of a break is less than 30 then it will be skipped due to the setBreakClipLoadInterceptor code
*/
let breakToPlay;
for (let i = 0; i < breakSeekData.breaks.length; i++) {
if (!breakSeekData.breaks[i].isWatched) {
breakToPlay = breakSeekData.breaks[i];
}
}
if (breakToPlay){
breakSeekData.breaks = [breakToPlay];
return breakSeekData;
}
});
참고: 아무것도 반환하지 않거나 null이 반환되면 중단이 재생되지 않습니다. breakSeekData를 있는 그대로 반환하면 findFrom 사이의 탐색 중단이 모두 재생됩니다.
js/receiver.js
에 변경사항을 저장하고 페이지의 아무 곳이나 마우스 오른쪽 버튼으로 클릭한 다음 '전송'을 선택하여 웹 발신자의 전송 세션을 시작하세요. 광고 스트림이 즉시 재생됩니다.
10. 축하합니다
지금까지 최신 Cast 수신기 SDK를 사용하여 수신기 애플리케이션에 광고를 추가하는 방법을 알아보았습니다.
자세한 내용은 광고 시점 개발자 가이드를 참고하세요.