광고 삽입

ExoPlayer는 클라이언트 측 광고 삽입과 서버 측 광고 삽입에 모두 사용할 수 있습니다.

클라이언트 측 광고 삽입

클라이언트 측 광고 삽입에서 플레이어는 서로 다른 URL로 전환될 때 발생합니다. 정보 미디어(예: XML VAST 또는 VMAP 광고 태그입니다. 여기에는 콘텐츠, 실제 광고 미디어 URI, 메타데이터, 예를 들어 특정 광고가 건너뛸 수 있음.

클라이언트 측 광고 삽입에 ExoPlayer의 AdsMediaSource를 사용하면 플레이어는 는 재생될 광고에 대한 정보를 가지고 있습니다. 이렇게 하면 다음과 같은 몇 가지 장점이 있습니다.

  • 플레이어는 API를 사용하여 광고와 관련된 메타데이터 및 기능을 노출할 수 있습니다.
  • ExoPlayer UI 구성요소는 광고 위치 마커를 자동으로 표시할 수 있습니다. 광고가 재생 중인지 여부에 따라 동작을 변경할 수 있습니다.
  • 내부적으로 플레이어는 다음 전환 간에 일관된 버퍼를 유지할 수 있습니다. 있습니다.

이 설정에서는 플레이어가 광고와 콘텐츠 간의 전환을 처리합니다. 앱이 여러 개의 개별 포드를 제어하고 백그라운드/포그라운드 플레이어를 사용할 수 있게 해 줍니다.

클라이언트 측 광고 삽입에 사용할 콘텐츠 동영상과 광고 태그를 준비할 때 광고는 페이지의 동기화 샘플 (키프레임)에 플레이어가 콘텐츠 재생을 원활하게 재개할 수 있습니다.

선언적 광고 지원

광고 태그 URI는 MediaItem를 빌드할 때 지정할 수 있습니다.

Kotlin

val mediaItem =
  MediaItem.Builder()
    .setUri(videoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).build())
    .build()

자바

MediaItem mediaItem =
    new MediaItem.Builder()
        .setUri(videoUri)
        .setAdsConfiguration(
            new MediaItem.AdsConfiguration.Builder(adTagUri).build())
        .build();

광고 태그를 지정하는 미디어 항목에 대해 플레이어 지원을 사용 설정하려면 다음과 같이 구성된 DefaultMediaSourceFactory를 빌드하고 삽입합니다. 플레이어를 만들 때 AdsLoader.ProviderAdViewProvider를 발생시킵니다.

Kotlin

val mediaSourceFactory: MediaSource.Factory =
  DefaultMediaSourceFactory(context).setLocalAdInsertionComponents(adsLoaderProvider, playerView)
val player = ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build()

자바

MediaSource.Factory mediaSourceFactory =
    new DefaultMediaSourceFactory(context)
        .setLocalAdInsertionComponents(adsLoaderProvider, /* adViewProvider= */ playerView);
ExoPlayer player =
    new ExoPlayer.Builder(context).setMediaSourceFactory(mediaSourceFactory).build();

내부적으로 DefaultMediaSourceFactory는 콘텐츠 미디어 소스를 AdsMediaSource입니다. AdsMediaSourceAdsLoader AdsLoader.Provider: 미디어 항목의 광고에서 정의한 대로 광고를 삽입하는 데 사용합니다. 태그 사이에 있어야 합니다.

ExoPlayer의 PlayerViewAdViewProvider를 구현합니다. ExoPlayer IMA 라이브러리는 아래에 설명된 대로 사용하기 쉬운 AdsLoader를 제공합니다.

광고가 있는 재생목록

여러 미디어 항목이 포함된 재생목록을 재생할 때 기본 동작은 다음과 같습니다. 각 미디어 ID에 대해 한 번씩 광고 태그를 요청하고 광고 재생 상태를 저장합니다. 콘텐츠 URI, 광고 태그 URI 조합입니다. 즉, 사용자가 모든 미디어 항목에 고유한 미디어 ID 또는 콘텐츠 URI가 있는 광고가 광고 태그 URI가 일치하는지 확인합니다 미디어 항목이 반복되면 사용자에게 해당 광고는 한 번만 표시됩니다 (광고 재생 상태는 광고가 재생되므로 첫 번째 재생 후에 건너뜁니다.

불투명 광고 식별자를 전달하여 이 동작을 맞춤설정할 수 있습니다. 객체에 따라 지정된 미디어 항목의 광고 재생 상태가 평등입니다. 다음은 광고 재생 상태가 광고 태그에 연결된 예입니다. 미디어 ID와 광고 태그 URI의 조합이 아닌 URI만 광고 태그 URI를 광고 식별자로 전달합니다. 이렇게 하면 광고가 자동으로 사용자가 동영상을 재생할 때 두 번째 항목에서는 광고가 전체 재생목록의 전체 동영상을 볼 수 있습니다.

Kotlin

// Build the media items, passing the same ads identifier for both items,
// which means they share ad playback state so ads play only once.
val firstItem =
  MediaItem.Builder()
    .setUri(firstVideoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
    .build()
val secondItem =
  MediaItem.Builder()
    .setUri(secondVideoUri)
    .setAdsConfiguration(MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
    .build()
player.addMediaItem(firstItem)
player.addMediaItem(secondItem)

자바

// Build the media items, passing the same ads identifier for both items,
// which means they share ad playback state so ads play only once.
MediaItem firstItem =
    new MediaItem.Builder()
        .setUri(firstVideoUri)
        .setAdsConfiguration(
            new MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
        .build();
MediaItem secondItem =
    new MediaItem.Builder()
        .setUri(secondVideoUri)
        .setAdsConfiguration(
            new MediaItem.AdsConfiguration.Builder(adTagUri).setAdsId(adTagUri).build())
        .build();
player.addMediaItem(firstItem);
player.addMediaItem(secondItem);

ExoPlayer IMA 라이브러리

ExoPlayer IMA 라이브러리ImaAdsLoader를 제공하므로 앱에 클라이언트 측 광고 삽입을 통합할 수 있습니다. Kubernetes는 클라이언트 측 IMA SDK가 있어야 합니다. 대상 백그라운드 처리 방법 등 라이브러리 사용 방법에 관한 안내 재생을 다시 시작하려면 리드미를 참고하세요.

데모 애플리케이션은 IMA 라이브러리를 사용하며, 여기에는 몇 가지 샘플이 포함되어 있습니다. 샘플 목록에 있는 VAST/VMAP 광고 태그입니다.

UI 고려사항

PlayerView는 광고가 재생되는 동안 기본값이지만 앱에서 setControllerHideDuringAds입니다. IMA SDK는 광고가 재생되는 동안 플레이어 (예: '추가 정보' 링크와 건너뛰기 버튼)를 (해당하는 경우)

IMA SDK에서 애플리케이션이 제공한 보기로 광고가 가려지는지 여부를 보고할 수 있습니다. 플레이어 위에 렌더링됩니다. 다음과 같은 뷰를 오버레이해야 하는 앱 재생 제어에 꼭 필요한 경우 IMA SDK에 등록해야 합니다. 조회가능성 계산에서 생략될 수 있습니다. PlayerView를 다음 용도로 사용하는 경우 AdViewProvider를 사용하면 자동으로 컨트롤 오버레이를 등록합니다. 앱 맞춤 플레이어 UI를 사용하는 경우 오버레이 뷰를 AdViewProvider.getAdOverlayInfos

오버레이 뷰에 관한 자세한 내용은 다음을 참고하세요. IMA SDK의 Open Measurement.

컴패니언 광고

일부 광고 태그에는 '슬롯'에 표시될 수 있는 추가 컴패니언 광고가 포함되어 있습니다. , 있습니다. 이러한 슬롯은 ImaAdsLoader.Builder.setCompanionAdSlots(slots) 자세한 내용은 컴패니언 광고 추가를 참조하세요.

독립형 광고

IMA SDK는 재생이 아닌 미디어 콘텐츠에 광고를 삽입하기 위한 것입니다. 사용할 수 있습니다. 따라서 독립형 광고의 재생이 지원되지 않습니다. 지정할 수 있습니다. 대신 Google 모바일 광고 SDK를 사용하는 것이 좋습니다. 살펴보겠습니다

서드 파티 광고 SDK 사용

서드 파티 광고 SDK를 통해 광고를 로드해야 하는 경우 이미 ExoPlayer 통합을 제공하고 있습니다 그렇지 않은 경우 맞춤 서드 파티 광고 SDK를 래핑하는 AdsLoader를 사용하는 것이 좋습니다. 위에서 설명한 AdsMediaSource의 이점을 제공하기 때문입니다. ImaAdsLoader는 구현 예시 역할을 합니다.

또는 ExoPlayer의 재생목록 지원을 사용하여 시퀀스를 빌드할 수 있습니다. 광고 및 콘텐츠 클립:

Kotlin

// A pre-roll ad.
val preRollAd = MediaItem.fromUri(preRollAdUri)
// The start of the content.
val contentStart =
  MediaItem.Builder()
    .setUri(contentUri)
    .setClippingConfiguration(ClippingConfiguration.Builder().setEndPositionMs(120000).build())
    .build()
// A mid-roll ad.
val midRollAd = MediaItem.fromUri(midRollAdUri)
// The rest of the content
val contentEnd =
  MediaItem.Builder()
    .setUri(contentUri)
    .setClippingConfiguration(ClippingConfiguration.Builder().setStartPositionMs(120000).build())
    .build()

// Build the playlist.
player.addMediaItem(preRollAd)
player.addMediaItem(contentStart)
player.addMediaItem(midRollAd)
player.addMediaItem(contentEnd)

자바

// A pre-roll ad.
MediaItem preRollAd = MediaItem.fromUri(preRollAdUri);
// The start of the content.
MediaItem contentStart =
    new MediaItem.Builder()
        .setUri(contentUri)
        .setClippingConfiguration(
            new ClippingConfiguration.Builder().setEndPositionMs(120_000).build())
        .build();
// A mid-roll ad.
MediaItem midRollAd = MediaItem.fromUri(midRollAdUri);
// The rest of the content
MediaItem contentEnd =
    new MediaItem.Builder()
        .setUri(contentUri)
        .setClippingConfiguration(
            new ClippingConfiguration.Builder().setStartPositionMs(120_000).build())
        .build();

// Build the playlist.
player.addMediaItem(preRollAd);
player.addMediaItem(contentStart);
player.addMediaItem(midRollAd);
player.addMediaItem(contentEnd);

서버 측 광고 삽입

서버 측 광고 삽입 (동적 광고 삽입 또는 DAI라고도 함)에서는 미디어 스트림에는 광고와 콘텐츠가 모두 포함됩니다. DASH 매니페스트는 두 가지를 모두 가리킬 수 있음 개별적인 기간으로 설정할 수 있습니다 HLS에 대한 자세한 내용은 재생목록에 광고 통합하기 문서를 참조하세요.

서버 측 광고 삽입을 사용할 때 클라이언트는 미디어를 해결해야 할 수 있습니다. 연결된 스트림을 가져오기 위해 동적으로 URL을 가져오는 경우 광고 오버레이를 표시해야 할 수 있습니다. 광고 SDK 또는 광고 서버에 이벤트를 보고해야 할 수도 있습니다.

ExoPlayer의 DefaultMediaSourceFactory는 이러한 모든 작업을 ssai:// 스키마를 사용하는 URI의 서버 측 광고 삽입 MediaSource:

Kotlin

val player =
  ExoPlayer.Builder(context)
    .setMediaSourceFactory(
      DefaultMediaSourceFactory(context).setServerSideAdInsertionMediaSourceFactory(ssaiFactory)
    )
    .build()

자바

Player player =
    new ExoPlayer.Builder(context)
        .setMediaSourceFactory(
            new DefaultMediaSourceFactory(context)
                .setServerSideAdInsertionMediaSourceFactory(ssaiFactory))
        .build();

ExoPlayer IMA 라이브러리

ExoPlayer IMA 라이브러리ImaServerSideAdInsertionMediaSource, 동영상에 IMA의 서버 측에서 삽입된 광고 스트림과 있습니다. 이 SDK는 Android용 IMA DAI SDK의 기능을 래핑하며 제공된 광고 메타데이터를 플레이어에 통합합니다. 예를 들어, Player.isPlayingAd()와 같은 메서드를 사용하고 콘텐츠 광고 전환을 수신 대기합니다. 플레이어가 이미 재생된 광고 건너뛰기와 같은 광고 재생 로직을 처리하도록 할 수 있습니다.

이 클래스를 사용하려면 ImaServerSideAdInsertionMediaSource.AdsLoaderImaServerSideAdInsertionMediaSource.Factory하고 플레이어에 연결합니다.

Kotlin

// MediaSource.Factory to load the actual media stream.
val defaultMediaSourceFactory = DefaultMediaSourceFactory(context)
// AdsLoader that can be reused for multiple playbacks.
val adsLoader =
  ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider).build()
// MediaSource.Factory to create the ad sources for the current player.
val adsMediaSourceFactory =
  ImaServerSideAdInsertionMediaSource.Factory(adsLoader, defaultMediaSourceFactory)
// Configure DefaultMediaSourceFactory to create both IMA DAI sources and
// regular media sources. If you just play IMA DAI streams, you can also use
// adsMediaSourceFactory directly.
defaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory)
// Set the MediaSource.Factory on the Player.
val player = ExoPlayer.Builder(context).setMediaSourceFactory(defaultMediaSourceFactory).build()
// Set the player on the AdsLoader
adsLoader.setPlayer(player)

자바

// MediaSource.Factory to load the actual media stream.
DefaultMediaSourceFactory defaultMediaSourceFactory = new DefaultMediaSourceFactory(context);
// AdsLoader that can be reused for multiple playbacks.
ImaServerSideAdInsertionMediaSource.AdsLoader adsLoader =
    new ImaServerSideAdInsertionMediaSource.AdsLoader.Builder(context, adViewProvider).build();
// MediaSource.Factory to create the ad sources for the current player.
ImaServerSideAdInsertionMediaSource.Factory adsMediaSourceFactory =
    new ImaServerSideAdInsertionMediaSource.Factory(adsLoader, defaultMediaSourceFactory);
// Configure DefaultMediaSourceFactory to create both IMA DAI sources and
// regular media sources. If you just play IMA DAI streams, you can also use
// adsMediaSourceFactory directly.
defaultMediaSourceFactory.setServerSideAdInsertionMediaSourceFactory(adsMediaSourceFactory);
// Set the MediaSource.Factory on the Player.
Player player =
    new ExoPlayer.Builder(context).setMediaSourceFactory(defaultMediaSourceFactory).build();
// Set the player on the AdsLoader
adsLoader.setPlayer(player);

URL을 작성하여 IMA 애셋 키 또는 콘텐츠 소스 ID 및 동영상 ID를 로드합니다. ImaServerSideAdInsertionUriBuilder로 다음 명령어를 실행합니다.

Kotlin

val ssaiUri =
  ImaServerSideAdInsertionUriBuilder()
    .setAssetKey(assetKey)
    .setFormat(C.CONTENT_TYPE_HLS)
    .build()
player.setMediaItem(MediaItem.fromUri(ssaiUri))

자바

Uri ssaiUri =
    new ImaServerSideAdInsertionUriBuilder()
        .setAssetKey(assetKey)
        .setFormat(C.CONTENT_TYPE_HLS)
        .build();
player.setMediaItem(MediaItem.fromUri(ssaiUri));

마지막으로, 더 이상 사용되지 않는 광고 로더를 해제합니다.

Kotlin

adsLoader.release()

자바

adsLoader.release();

UI 고려사항

클라이언트 측 광고 삽입과 동일한 UI 고려사항이 적용됩니다. 서버 측 광고 삽입에도 사용할 수 있습니다.

컴패니언 광고

일부 광고 태그에는 '슬롯'에 표시될 수 있는 추가 컴패니언 광고가 포함되어 있습니다. , 있습니다. 이러한 슬롯은 ImaServerSideAdInsertionMediaSource.AdsLoader.Builder.setCompanionAdSlots(slots) 자세한 내용은 컴패니언 광고 추가를 참조하세요.

서드 파티 광고 SDK 사용

서드 파티 광고 SDK를 사용하여 광고를 로드해야 하는 경우 이미 ExoPlayer 통합을 제공하고 있습니다 그렇지 않은 경우 ssai:// 스키마가 있는 URI를 허용하는 커스텀 MediaSource를 제공합니다. ImaServerSideAdInsertionMediaSource와 유사합니다.

광고 구조를 만드는 실제 로직은 스트림 MediaSource를 래핑하는 ServerSideAdInsertionMediaSource 목적 사용자가 광고를 나타내는 AdPlaybackState를 설정 및 업데이트할 수 있게 합니다. 메타데이터로 변환할 수 있습니다.

서버 측에서 삽입된 광고 스트림에는 플레이어에 알리는 시간이 지정된 이벤트가 포함되는 경우가 많습니다. 광고 메타데이터 정보 어떤 형식이 지원되는지 자세히 알아보려면 지원되는 형식을 시간이 지정된 메타데이터 형식은 ExoPlayer에서 지원됩니다. 맞춤 광고 SDK MediaSource 구현은 다음을 사용하여 플레이어의 시간이 지정된 메타데이터 이벤트를 수신 대기할 수 있습니다. Player.Listener.onMetadata입니다.