コンテンツに移動

よくアクセスするページ

最近アクセスしたページ

navigation

Render Video Directly on a Surface

Direct surface rendering lets your app control what is rendered and how it is rendered. You can overlay metadata such as channel attribution. You can also render secured content for protected playback.

To implement direct rendering, you must build your own TvInputService. The Android TV home screen passes a Surface to your service by calling onSetSurface(). Your app draws video directly on this surface from onTune().

This page explains how to build a TvInputService and configure your app to render preview material by itself, rather than relying on the Android TV home screen.

Declare your TvInputService in the manifest

Your app must provide a TvInputService-compatible service that the system uses to access your app.

In your service declaration, include an intent filter that specifies TvInputService as the action to perform with the intent. Also declare the service metadata as a separate XML resource. The service declaration, intent filter, and service metadata declaration are shown in the following example:

<service android:name=".rich.PreviewInputService"
    android:label="@string/rich_input_label"
    android:permission="android.permission.BIND_TV_INPUT">
    <!-- Required filter used by the system to launch our account service. -->
    <intent-filter>
        <action android:name="android.media.tv.TvInputService" />
    </intent-filter>
    <!-- An XML file which describes this input. This provides pointers to
    the PreviewInputSetupActivity to the system/TV app. -->
    <meta-data
        android:name="android.media.tv.input"
        android:resource="@xml/previewinputservice" />
</service>

Define the service metadata in a separate XML file. The service metadata file is located in the XML resources directory for your app and must match the name of the resource you declared in the manifest. Using the manifest entries from the previous example, you would create the XML file at res/xml/previewinputservice.xml, with the following contents:

<?xml version="1.0" encoding="utf-8"?>
<tv-input/>

Create a video URI

To indicate that your preview video should be rendered by your app, rather than the Android TV home screen, create a video URI for a PreviewProgram:

componentName = new ComponentName(context, PreviewInputService.class.getName());
Uri videoUri = TvContractCompat.buildPreviewProgramUri(previewProgramId)
        .buildUpon()
        .appendQueryParameter("input", TvContractCompat.buildInputId(componentName));

Use the videoUri to update a preview program of a launcher channel. Specify the videoUri in the PreviewProgram.Builder with setPreviewVideoUri when updating a preview program:

PreviewProgram.Builder builder = new PreviewProgram.Builder(previewProgram);
builder.setChannelId(channelId)
       .setType(TvContractCompat.PreviewPrograms.TYPE_CLIP)
       .setTitle("Title")
       .setDescription("Program description")
       .setPosterArtUri(uri)
       .setIntentUri(uri)
       .setInternalProviderId(appProgramId)
       .setPreviewVideoUri(videoUri);

context.getContentResolver().update(
    TvContractCompat.buildPreviewProgramUri(programId),
    previewProgramBuilder.build().toContentValues(),
    null,
    null);

Your app calls onTune(Uri videoUri) to make Android TV start the preview video.

Create a service

The following example shows how to extend TvInputService to create your own PreviewInputService. Note that the service uses a MediaPlayer for playback, but your code can use any available video player.

import android.content.Context;
import android.media.MediaPlayer;
import android.media.tv.TvInputService;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.Surface;

import java.io.IOException;

public class PreviewInputService extends TvInputService {
   @Nullable
   @Override
   public Session onCreateSession(String s) {
       Log.d("PreviewInputService", s);
       return new PreviewSession(this);
   }

   private class PreviewSession extends Session {
       MediaPlayer mMediaPlayer = null;
       Context mContext;

       public PreviewSession(Context context) {
           super(context);
           mContext = context;
           mMediaPlayer = new MediaPlayer();
       }

       @Override
       public void onRelease() {
           if(mMediaPlayer != null) {
               mMediaPlayer.release();
               mMediaPlayer = null;
           }
       }

       @Override
       public boolean onTune(Uri uri) {
          // fetch the stream url from the TV Provider database
          // for content://android.media.tv/preview_program/14
          Uri videoUri = fetchStreamUrlFromTvProviderDatabase(uri);
          try {
              mMediaPlayer.setDataSource(videoUri.toString());
              mMediaPlayer.prepare();
              mMediaPlayer.start();
              notifyVideoAvailable();
          } catch (IOException e) {
              Log.e("PreviewInputService", "Could not prepare media player", e);
              return false;
          }
          return true;
        }

       @Override
       public boolean onSetSurface(@Nullable Surface surface) {
           mMediaPlayer.setSurface(surface);
           return true;
       }

       @Override
       public void onSetStreamVolume(float v) {
           // set stream volume here
       }

       @Override
       public void onSetCaptionEnabled(boolean b) {
           // enable/disable captions here
       }
   }
}
このサイトでは、ユーザーが選択したサイトの言語と表示設定を保存する目的で Cookie を使用しています。

Android デベロッパー向けの最新情報やヒントを入手して、Google Play での成功を手に入れましょう。

* 必須

送信しました

WeChat で Google Developers をフォローする

このサイトをで表示しますか?

ページの表示言語としてを選択しましたが、このサイトの言語はに設定されています。

言語設定を変更してこのサイトをで表示しますか?言語設定を変更する場合は、各ページの下にある言語メニューを使用してください。

このクラスには、API レベル 以上が必要です。

API レベル が選択されているため、このドキュメントは非表示になっています。左のナビゲーションの上にあるセレクタを使って、ドキュメントの API レベルを変更できます。

アプリに必要な API レベルを指定する方法について、詳しくは異なるプラットフォーム バージョンのサポートをご覧ください。

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)