پیش نمایش ویدیوها

یک ویدیوی پیش نمایش یک راه عالی برای تشویق کاربران به پیوند عمیق به برنامه تلویزیون شما است. پیش‌نمایش‌ها می‌تواند از کلیپ‌های کوتاه تا تریلرهای کامل فیلم متغیر باشد.

هنگام ایجاد پیش نمایش، این دستورالعمل ها را در نظر بگیرید:

  • تبلیغات را در پیش نمایش نشان ندهید. اگر تبلیغات را در سمت مشتری قرار می دهید، آنها را در ویدیوهای پیش نمایش قرار ندهید. اگر تبلیغات را در سمت سرور قرار می دهید، یک ویدیوی بدون آگهی برای پیش نمایش ارائه دهید.
  • برای بهترین کیفیت، پیش نمایش فیلم ها باید 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 با فراخوانی onSetSurface() یک Surface را به سرویس شما ارسال می کند. برنامه شما مستقیماً روی این سطح از 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/