Предварительный просмотр видеоролика — отличный способ побудить пользователей перейти по ссылке на ваше ТВ-приложение. Превью могут варьироваться от коротких клипов до полных трейлеров к фильмам.
При создании предварительного просмотра учитывайте следующие рекомендации:
- Не показывать рекламу в предварительном просмотре. Если вы вшиваете рекламу на стороне клиента, не вставляйте ее в превью-ролики. Если вы размещаете рекламу на стороне сервера, предоставьте для предварительного просмотра видео без рекламы.
- Для наилучшего качества видео предварительного просмотра должно быть 16:9 или 4:3. Рекомендуемые размеры видео для предварительного просмотра см. в разделе «Атрибуты видеопрограммы» .
- Если видео предварительного просмотра и плакат имеют разные соотношения сторон, перед воспроизведением предварительного просмотра главный экран изменяет размер изображения постера в соответствии с соотношением сторон видео. Видео не в почтовом ящике. Например, если соотношение сторон постера —
ASPECT_RATIO_MOVIE_POSTER
(1:1,441), а соотношение видео — 16:9, вид постера преобразуется в область 16:9. - Когда вы создаете предварительный просмотр, его содержимое может быть общедоступным или защищено DRM. В каждом случае применяются разные процедуры. На этой странице описаны оба.
Воспроизведение предварительного просмотра на главном экране
Если вы создаете предварительный просмотр, используя любой из типов видео, поддерживаемых ExoPlayer , и предварительный просмотр общедоступен, вы можете воспроизвести предварительный просмотр прямо на главном экране.
При создании PreviewProgram используйте setPreviewVideoUri()
с общедоступным URL-адресом HTTPS, как показано в примере ниже. Предварительный просмотр может быть видео или аудио .
val previewVideoUrl = Uri.parse("https://www.example.com/preview.mp4")
val builder = PreviewProgram.Builder()
builder.setChannelId(channelId)
// ...
.setPreviewVideoUri(previewVideoUrl)
Uri previewVideoUrl = Uri.parse("https://www.example.com/preview.mp4");
PreviewProgram.Builder builder = new PreviewProgram.Builder();
builder.setChannelId(channelId)
// ...
.setPreviewVideoUri(Uri.parse(previewVideoUrl));
Отрисовка предварительного просмотра на поверхности
Если ваше видео защищено DRM или имеет тип носителя, не поддерживаемый ExoPlayer , используйте TvInputService
. Главный экран Android TV передает Surface
в вашу службу, вызывая onSetSurface()
. Ваше приложение рисует видео прямо на этой поверхности из onTune()
.
Прямой рендеринг поверхности позволяет вашему приложению контролировать то, что и как визуализируется. Вы можете накладывать метаданные, такие как атрибуция канала.
Объявите свой TvInputService в манифесте.
Ваше приложение должно предоставлять реализацию TvInputService
, чтобы главный экран мог отображать ваш предварительный просмотр.
В декларацию службы включите фильтр намерений, который указывает TvInputService
в качестве действия, которое необходимо выполнить с намерением. Также объявите метаданные службы как отдельный ресурс XML. Объявление службы, фильтр намерений и объявление метаданных службы показаны в следующем примере:
<service android:name=".rich.PreviewInputService"
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. -->
<meta-data
android:name="android.media.tv.input"
android:resource="@xml/previewinputservice" />
</service>
Определите метаданные службы в отдельном XML-файле. Файл метаданных службы находится в каталоге ресурсов XML вашего приложения и должен соответствовать имени ресурса, объявленного вами в манифесте. Используя записи манифеста из предыдущего примера, вы создадите XML-файл по адресу res/xml/previewinputservice.xml
с пустым тегом tv-input
:
<?xml version="1.0" encoding="utf-8"?>
<tv-input/>
TV Input Framework должен иметь этот тег. Однако он используется только для настройки живых каналов. Поскольку вы визуализируете видео, тег должен быть пустым.
Создать URI видео
Чтобы указать, что видео предварительного просмотра должно отображаться в вашем приложении, а не на главном экране Android TV, необходимо создать URI видео для PreviewProgram
. URI должен заканчиваться идентификатором, который ваше приложение использует для контента, чтобы вы могли получить контент позже в TvInputService
.
Если ваш идентификатор типа Long
, используйте TvContractCompat.buildPreviewProgramUri() :
val id: Long = 1L // content identifier
val componentName = new ComponentName(context, PreviewVideoInputService.class)
val previewProgramVideoUri = TvContractCompat.buildPreviewProgramUri(id)
.buildUpon()
.appendQueryParameter("input", TvContractCompat.buildInputId(componentName))
.build()
Long id = 1L; // content identifier
ComponentName componentName = new ComponentName(context, PreviewVideoInputService.class);
previewProgramVideoUri = TvContractCompat.buildPreviewProgramUri(id)
.buildUpon()
.appendQueryParameter("input", TvContractCompat.buildInputId(componentName))
.build();
Если ваш идентификатор не типа Long
, создайте URI, используя Uri.withAppendedPath()
:
val previewProgramVideoUri = Uri.withAppendedPath(PreviewPrograms.CONTENT_URI, "content-identifier")
.buildUpon()
.appendQueryParameter("input", TvContractCompat.buildInputId(componentName))
.build()
previewProgramVideoUri = Uri.withAppendedPath(PreviewPrograms.CONTENT_URI, "content-identifier")
.buildUpon()
.appendQueryParameter("input", TvContractCompat.buildInputId(componentName))
.build();
Ваше приложение вызывает onTune(Uri videoUri)
чтобы Android TV начал предварительный просмотр видео.
Создать услугу
В следующем примере показано, как расширить TvInputService
для создания собственного PreviewInputService
. Обратите внимание, что служба использует MediaPlayer
для воспроизведения, но ваш код может использовать любой доступный видеоплеер.
import android.content.Context
import android.media.MediaPlayer
import android.media.tv.TvInputService
import android.net.Uri
import android.util.Log
import android.view.Surface
import java.io.IOException
class PreviewVideoInputService : TvInputService() {
override fun onCreateSession(inputId: String): TvInputService.Session? {
return PreviewSession(this)
}
private inner class PreviewSession(
internal var context: Context
) : TvInputService.Session(context) {
internal var mediaPlayer: MediaPlayer? = MediaPlayer()
override fun onRelease() {
mediaPlayer?.release()
mediaPlayer = null
}
override fun onTune(uri: Uri): Boolean {
// Let the TvInputService know that the video is being loaded.
notifyVideoUnavailable(VIDEO_UNAVAILABLE_REASON_TUNING)
// Fetch the stream url from the TV Provider database
// for content://android.media.tv/preview_program/
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 PreviewVideoInputService extends TvInputService {
private static final String TAG = "PreviewVideoInputService";
@Nullable
@Override
public Session onCreateSession(String inputId) {
return new PreviewSession(this);
}
private class PreviewSession extends TvInputService.Session {
private MediaPlayer mPlayer;
PreviewSession(Context context) {
super(context);
mPlayer = new MediaPlayer();
}
@Override
public boolean onTune(Uri channelUri) {
// Let the TvInputService know that the video is being loaded.
notifyVideoUnavailable(VIDEO_UNAVAILABLE_REASON_TUNING);
// Fetch the stream url from the TV Provider database
// for content://android.media.tv/preview_program/