Langsung ke konten

Paling sering dikunjungi

Terakhir dikunjungi

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
       }
   }
}
Situs ini menggunakan cookies untuk menyimpan preferensi Anda tentang bahasa di situs tertentu dan opsi tampilan.

Dapatkan berita dan tips terbaru dari developer Android yang akan membantu Anda mencapai kesuksesan di Google Play.

* Wajib Diisi

Hore!

Ikuti Google Developers di WeChat

Buka situs ini dalam bahasa ?

Anda meminta halaman dalam bahasa , namun preferensi bahasa untuk situs ini adalah .

Ingin mengubah preferensi bahasa dan mengakses situs ini dalam bahasa ? Jika nanti Anda ingin mengubah preferensi bahasa, gunakan menu bahasa di bagian bawah setiap halaman.

Kelas ini memerlukan tingkat API atau yang lebih tinggi

Dokumen ini tersembunyi karena level API yang Anda pilih untuk dokumentasi ini adalah . Anda dapat mengubah level API dokumentasi dengan pemilih di atas menu navigasi sebelah kiri.

Untuk informasi lebih lanjut tentang menentukan level API yang diperlukan aplikasi Anda, baca Mendukung Versi Platform Yang Berbeda.

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