웹 수신기에 Ad Breaks API 지원 추가

1. 개요

Google Cast 로고

이 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 수신기가 빌드됩니다.

학습할 내용

  • 전송 콘텐츠에 VMAP 및 VAST 시점을 포함하는 방법
  • 휴식 시간 클립 건너뛰는 방법
  • 탐색 시 기본 나누기 동작을 맞춤설정하는 방법

필요한 항목

  • 최신 Chrome 브라우저
  • HTTPS 호스팅 서비스(예: Firebase 호스팅 또는 ngrok)
  • Chromecast 또는 Android TV와 같이 인터넷에 액세스할 수 있도록 설정된 Google Cast 기기
  • HDMI 입력이 지원되는 TV나 모니터 또는 Google Home Hub

환경

이 Codelab을 계속 진행하기 전에 다음과 같은 환경을 갖추고 있는지 확인하세요.

  • 일반적인 웹 개발 지식
  • Cast 웹 수신기 애플리케이션 빌드

본 가이드를 어떻게 사용하실 계획인가요?

읽기만 할 계획입니다 읽은 다음 연습 활동을 완료할 계획입니다

본인의 웹 앱 빌드 경험을 평가해 주세요.

초급 중급 고급

2. 샘플 코드 가져오기

컴퓨터에 모든 샘플 코드 다운로드...

그런 다음 다운로드한 ZIP 파일의 압축을 풉니다.

3. 로컬에서 수신기 배포

Cast 기기에서 웹 수신기를 사용하려면 Cast 기기에서 웹 수신기를 연결할 수 있는 위치에서 호스팅되어야 합니다. https를 지원하는 서버가 이미 있는 경우 다음 안내를 건너뛰고 URL을 기록해 두세요. 다음 섹션에서 필요합니다.

사용할 수 있는 서버가 없으면 Firebase 호스팅 또는 ngrok를 사용할 수 있습니다.

서버 실행

원하는 서비스를 설정했다면 app-start로 이동하여 서버를 시작합니다.

호스팅된 수신자의 URL을 기록해 둡니다. 다음 섹션에서 사용합니다.

4. Cast Play Console에 애플리케이션 등록

이 Codelab에 내장된 맞춤 수신기를 Chromecast 기기에서 실행하려면 애플리케이션을 등록해야 합니다. 애플리케이션을 등록하면 Web Receiver 애플리케이션을 실행하려면 발신자 애플리케이션을 구성해야 하는 애플리케이션 ID가 생성됩니다.

'새 애플리케이션 추가' 버튼이 강조표시된 Google Cast SDK 개발자 콘솔의 이미지

'새 애플리케이션 추가'를 클릭합니다.

'Custom Receiver' 옵션이 강조표시된 'New Receiver Application' 화면의 이미지

만들고자 하는 '맞춤 수신기'를 선택합니다.

'수신자 애플리케이션 URL' 입력란에 사용자가 입력하는 URL을 보여주는 '새 맞춤 수신자' 화면의 이미지

새 수신기의 세부정보를 입력합니다. Web Receiver 애플리케이션을 호스팅하려는 위치를 가리키는 URL을 사용해야 합니다. 애플리케이션을 등록하면 콘솔에서 생성된 애플리케이션 ID를 기록합니다. 이후 섹션에서 발신자 애플리케이션이 해당 식별자를 사용하도록 구성됩니다.

또한 게시하기 전에 수신기 애플리케이션에 액세스할 수 있도록 Google Cast 기기를 등록해야 합니다. 수신기 애플리케이션을 게시하면 모든 Google Cast 기기에서 사용할 수 있습니다. 이 Codelab에서는 게시되지 않은 수신기 애플리케이션으로 작업하는 것이 좋습니다.

'새 기기 추가' 버튼이 강조표시된 Google Cast SDK 개발자 콘솔의 이미지

'새 기기 추가'를 클릭합니다.

'Cast 수신기 기기 추가' 대화상자 이미지

Cast 기기 뒷면에 인쇄된 일련번호를 입력하고 설명이 포함된 이름을 지정합니다. Google Cast SDK 개발자 콘솔에 액세스할 때 Chrome에서 화면을 전송하여 일련번호를 확인할 수도 있습니다.

수신기와 기기를 테스트할 준비가 되기까지 5~15분이 걸립니다. 5~15분 정도 기다린 후 Cast 기기를 재부팅해야 합니다.

5. 시작 프로젝트 준비

이 Codelab을 시작하기 전에 광고 시점 API의 개요를 제공하는 광고 개발자 가이드를 검토하는 것이 좋습니다.

다운로드한 시작 앱에 Google Cast 지원을 추가해야 합니다. 다음은 이 Codelab에서 사용되는 Google Cast 용어입니다.

  • 발신기 앱은 휴대기기 또는 노트북에서 실행됩니다.
  • 수신기 앱은 Google Cast 기기에서 실행됩니다.

이제 선호하는 텍스트 편집기를 사용하여 시작 프로젝트 위에 빌드할 준비가 되었습니다.

  1. 샘플 코드 다운로드에서 폴더 아이콘app-start 디렉터리를 선택합니다.
  2. js/receiver.js 및 index.html을 엽니다.

이 Codelab을 진행하는 동안 선택한 웹 호스팅 솔루션이 변경사항으로 업데이트되어야 합니다. 검증 및 테스트를 계속할 때는 변경사항을 호스트 사이트에 적용해야 합니다.

앱 디자인

앞서 언급했듯이 이 Codelab에서는 전송자 애플리케이션을 사용하여 Cast 세션을 시작하고, 광고 시점 API를 사용하도록 수정되는 수신기 애플리케이션을 활용합니다.

이 Codelab에서는 전송 및 명령어 도구가 Web Sender 역할을 하여 수신기 앱을 실행합니다. 시작하려면 Chrome 브라우저에서 도구를 엽니다. Cast SDK 개발자 콘솔에서 제공된 수신기 앱 ID를 입력하고 설정을 클릭하여 테스트를 위해 발신기 앱을 구성합니다.

참고: 전송 아이콘이 표시되지 않는 경우 웹 수신기 및 전송 기기가 Cast Play Console에 올바르게 등록되어 있는지 확인하세요. 아직 전원을 껐다 켜지 않았다면 방금 등록한 Cast 기기의 전원을 껐다 켭니다.

수신기 앱은 이 Codelab에서 중점적으로 다루며 index.html에 정의된 기본 뷰 하나와 js/receiver.js라는 JavaScript 파일 하나로 구성됩니다. 자세한 내용은 아래에 설명되어 있습니다.

index.html

이 html 파일에는 cast-media-player 요소에서 제공하는 수신기 앱의 UI가 포함되어 있습니다. 또한 CAF SDK 및 Cast 디버그 로거 라이브러리를 로드합니다.

receiver.js

이 스크립트는 수신기 앱의 모든 로직을 관리합니다. 현재 전송 컨텍스트를 초기화하고 초기화 시 동영상 애셋을 로드하는 기본 CAF 수신기가 포함되어 있습니다. Cast 및 명령어 도구에 다시 로깅을 제공할 수 있도록 일부 디버거 로거 기능도 추가되었습니다.

6. 콘텐츠에 VMAP 추가

Cast 웹 수신기 SDK는 디지털 동영상 다중 광고 재생목록(VMAP이라고도 함)을 통해 지정된 광고를 지원합니다. XML 구조는 미디어의 광고 시점 및 연결된 광고 시점 클립 메타데이터를 지정합니다. 이러한 광고를 삽입하기 위해 SDK는 MediaInformation 객체에 vmapAdsRequest 속성을 제공합니다.

js/receiver.js 파일에서 VastAdsRequest 객체를 만듭니다. LOAD 요청 인터셉터 함수를 찾아 아래 코드로 바꿉니다. 여기에는 DoubleClick의 샘플 VMAP 태그 URL이 포함되어 있으며, 동일한 URL에 대한 후속 요청에서 아직 시청하지 않은 광고 시간이 포함된 XML 템플릿을 생성할 수 있도록 임의의 correlator 값을 제공합니다.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
      castDebugLogger.info('MyAPP.LOG', 'Intercepting LOAD request');

      // Create the VMAP Ads request data and append it to the MediaInformation.
      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));
      let vmapRequest = new cast.framework.messages.VastAdsRequest();
      vmapRequest.adTagUrl = vmapUrl;
      loadRequestData.media.vmapAdsRequest = vmapRequest;

      castDebugLogger.warn(
          'MyAPP.LOG', 'Playable URL: ' + loadRequestData.media.contentId);

      return loadRequestData;
    });

변경사항을 js/receiver.js에 저장하고 파일을 웹 서버에 업로드합니다. 전송 아이콘을 클릭하여 전송 및 명령어 도구에서 전송 세션을 시작합니다. VMAP 광고가 재생된 후 기본 콘텐츠가 재생되어야 합니다.

7. 콘텐츠에 VAST 추가

앞서 언급했듯이 웹 수신기 SDK에서는 다양한 유형의 광고를 지원합니다. 이 섹션에서는 디지털 동영상 광고 게재 템플릿 광고(VAST)를 통합하는 데 사용할 수 있는 API에 대해 중점적으로 설명합니다. 이전 섹션에서 VMAP 코드를 구현한 경우 주석 처리합니다.

로드 요청 인터셉터 뒤에 다음을 js/receiver.js 파일에 복사합니다. 이 파일에는 DoubleClick의 VAST 광고 시간 클립 6개와 임의의 correlator 값이 포함되어 있습니다. 이러한 휴식 클립에는 5개의 휴식 시간이 할당됩니다. 각 광고 시점의 position은 프리롤 (position0으로 설정) 및 포스트롤 (position-1으로 설정됨) 광고 시점을 포함하여 기본 콘텐츠를 기준으로 한 초 단위의 시간으로 설정됩니다.

const addVASTBreaksToMedia = (mediaInformation) => {
  mediaInformation.breakClips = [
    {
      id: 'bc1',
      title: 'bc1 (Pre-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('preroll')
      }
    },
    {
      id: 'bc2',
      title: 'bc2 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc3',
      title: 'bc3 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc4',
      title: 'bc4 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc5',
      title: 'bc5 (Mid-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('midroll')
      }
    },
    {
      id: 'bc6',
      title: 'bc6 (Post-roll)',
      vastAdsRequest: {
        adTagUrl: generateVastUrl('postroll')
      }
    }
  ];

  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 메시지 인터셉터를 찾아 다음 코드로 바꿉니다. VMAP 작업은 VAST 유형 광고를 표시하기 위해 주석 처리됩니다.

playerManager.setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD, (loadRequestData) => {
      castDebugLogger.info('MyAPP.LOG', 'Intercepting LOAD request');

      // Create the VMAP Ads request data and append it to the MediaInformation.
      // 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));
      // let vmapRequest = new cast.framework.messages.VastAdsRequest();
      // vmapRequest.adTagUrl = vmapUrl;
      // loadRequestData.media.vmapAdsRequest = vmapRequest;

      // Append VAST ad breaks to the MediaInformation.
      addVASTBreaksToMedia(loadRequestData.media);

      castDebugLogger.warn(
          'MyAPP.LOG', 'Playable URL: ' + loadRequestData.media.contentId);

      return loadRequestData;
    });

변경사항을 js/receiver.js에 저장하고 파일을 웹 서버에 업로드합니다. 전송 아이콘을 클릭하여 전송 및 명령어 도구에서 전송 세션을 시작합니다. VAST 광고가 재생된 후 기본 콘텐츠가 재생되어야 합니다.

8. 광고 시점 건너뛰기

CAF에는 광고 동작에 대한 맞춤 비즈니스 규칙을 구현하는 데 도움이 되는 BreakManager라는 클래스가 있습니다. 이러한 기능 중 하나를 사용하면 애플리케이션이 일부 조건에 따라 프로그래매틱 방식으로 휴식 시간을 건너뛰고 클립을 끊을 수 있습니다. 이 예에서는 콘텐츠의 처음 30초 내에 위치가 있고 포스트롤 광고 시점이 아닌 광고 시점을 건너뛰는 방법을 보여줍니다. 이전 섹션에서 구성한 VAST 광고를 사용할 경우 프리롤 광고 시점 1개, 미드롤 시점 3개 (15, 60, 100초) 및 마지막으로 포스트롤 광고 1개 등 5개의 광고 시점이 정의됩니다. 단계를 완료하면 위치가 15초인 프리롤미드롤만 건너뜁니다.

이렇게 하려면 애플리케이션에서 BreakManager를 통해 사용 가능한 API를 호출하여 중단 로드용 인터셉터를 설정해야 합니다. js/receiver.js 파일에서 contextplayerManager 변수가 포함된 줄 뒤에 다음 줄을 복사하여 인스턴스 참조를 가져옵니다.

const breakManager = playerManager.getBreakManager();

애플리케이션은 포스트롤 시점을 염두에 두고 30초 전에 발생하는 모든 광고 시점을 무시하는 규칙으로 인터셉터를 설정해야 합니다 (position-1). 이 인터셉터는 PlayerManager의 로드 인터셉터와 유사하지만 이 인터셉터가 휴식 클립 로드에만 사용된다는 점이 다릅니다. LOAD 요청 인터셉터 뒤와 addVASTBreaksToMedia 함수 선언 앞에 설정합니다.

다음을 js/receiver.js 파일에 복사합니다.

breakManager.setBreakClipLoadInterceptor((breakClip, breakContext) => {
  /**
   * The code will skip playback of break clips if the break position is within
   * the first 30 seconds.
   */
  let breakObj = breakContext.break;
  if (breakObj.position >= 0 && breakObj.position < 30) {
    castDebugLogger.debug(
        'MyAPP.LOG',
        'Break Clip Load Interceptor skipping break with ID: ' + breakObj.id);
    return null;
  } else {
    return breakClip;
  }
});

참고: 여기서 null를 반환하면 처리 중인 BreakClip를 건너뜁니다. Break에 정의된 광고 시점 클립이 없으면 광고 시점 자체를 건너뜁니다.

변경사항을 js/receiver.js에 저장하고 파일을 웹 서버에 업로드합니다. 전송 아이콘을 클릭하여 전송 및 명령어 도구에서 전송 세션을 시작합니다. VAST 광고가 처리되어야 합니다. 프리롤 및 첫 번째 미드롤 (position이 15초인 광고) 광고는 재생되지 않습니다.

9. 중단 탐색 동작 맞춤설정

지난 시점을 탐색할 때 기본 구현은 위치가 탐색 작업의 seekFromseekTo 값 사이에 있는 모든 Break 항목을 가져옵니다. 이 광고 시점 목록에서 SDK는 positionseekTo 값에 가장 가깝고 isWatched 속성이 false로 설정된 Break를 재생합니다. 그런 다음 이 시점의 isWatched 속성이 true로 설정되고 플레이어가 광고 시점 클립 재생을 시작합니다. 광고 시점이 시청되면 기본 콘텐츠는 seekTo 위치에서 재생을 다시 시작합니다. 이러한 광고 시점이 없으면 광고 시점이 재생되지 않으며 기본 콘텐츠는 seekTo 위치에서 다시 재생됩니다.

탐색 시 재생되는 시점을 맞춤설정할 수 있도록 Cast SDK는 BreakManager에서 setBreakSeekInterceptor API를 제공합니다. 애플리케이션이 해당 API를 통해 맞춤 로직을 제공하면 SDK는 탐색 작업이 하나 이상의 중단에 걸쳐 수행될 때마다 이를 호출합니다. 콜백 함수에는 seekFrom 위치와 seekTo 위치 사이의 모든 줄바꿈이 포함된 객체가 전달됩니다. 그런 다음 애플리케이션은 BreakSeekData를 수정하고 반환해야 합니다.

사용법을 보여주기 위해 아래 샘플은 탐색한 모든 휴식 시간을 취하고 타임라인에 표시되는 첫 번째 중단 부분만 재생하여 기본 동작을 재정의합니다.

다음을 정의 아래의 js/receiver.js 파일에 setBreakClipLoadInterceptor에 복사합니다.

breakManager.setBreakSeekInterceptor((breakSeekData) => {
  /**
   * The code will play an unwatched break between the 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.
   */
  castDebugLogger.debug(
      'MyAPP.LOG',
      'Break Seek Interceptor processing break ids ' +
          JSON.stringify(breakSeekData.breaks.map(adBreak => adBreak.id)));

  // Remove all other breaks except for the first one.
  breakSeekData.breaks.splice(1,breakSeekData.breaks.length);
  return breakSeekData;
});

참고: 함수가 값을 반환하지 않거나 null을 반환하면 브레이크가 재생되지 않습니다.

변경사항을 js/receiver.js에 저장하고 파일을 웹 서버에 업로드합니다. 전송 아이콘을 클릭하여 전송 및 명령어 도구에서 전송 세션을 시작합니다. VAST 광고가 처리되어야 합니다. 프리롤 및 첫 번째 미드롤 (position이 15초인 광고) 광고는 재생되지 않습니다.

재생 시간이 30초에 도달할 때까지 기다리면 중단 클립 로드 인터셉터가 건너뛰는 모든 중단 시간을 지나갑니다. 도달하면 미디어 제어 탭으로 이동하여 탐색 명령어를 전달합니다. Seek Into Media(미디어로 탐색) 입력을 300초로 채우고 TO 버튼을 클릭합니다. Break Seek Interceptor에 출력된 로그를 확인합니다. 이제 seekFrom 시간에 가까운 광고 시점이 재생되도록 기본 동작이 재정의됩니다.

10. 축하합니다

지금까지 최신 Cast 수신기 SDK를 사용하여 수신기 애플리케이션에 광고를 추가하는 방법을 알아보았습니다.

자세한 내용은 광고 시점 개발자 가이드를 참고하세요.