In the live TV experience the user changes channels and is presented with channel and program information briefly before the information disappears. Other types of information, such as messages ("DO NOT ATTEMPT AT HOME"), subtitles, or ads may need to persist. As with any TV app, such information should not interfere with the program content playing on the screen.
> Your TV input must render video onto a Surface
object, which is passed by theTvInputService.Session.onSetSurface()
method. Here's an example of how to use a MediaPlayer
instance for playing content in the Surface
object:
@Override public boolean onSetSurface(Surface surface) { if (mPlayer != null) { mPlayer.setSurface(surface); } mSurface = surface; return true; } @Override public void onSetStreamVolume(float volume) { if (mPlayer != null) { mPlayer.setVolume(volume, volume); } mVolume = volume; }
Similarly, here's how to do it using ExoPlayer:
@Override public boolean onSetSurface(Surface surface) { if (mPlayer != null) { mPlayer.sendMessage(mVideoRenderer, MediaCodecVideoTrackRenderer.MSG_SET_SURFACE, surface); } mSurface = surface; return true; } @Override public void onSetStreamVolume(float volume) { if (mPlayer != null) { mPlayer.sendMessage(mAudioRenderer, MediaCodecAudioTrackRenderer.MSG_SET_VOLUME, volume); } mVolume = volume; }
> Use an overlay to display subtitles, messages, ads or MHEG-5 data broadcasts. By default, the overlay is disabled. You can enable it when you create the session by callingTvInputService.Session.setOverlayViewEnabled(true)
, as in the following example:
@Override public final Session onCreateSession(String inputId) { BaseTvInputSessionImpl session = onCreateSessionInternal(inputId); session.setOverlayViewEnabled(true); mSessions.add(session); return session; }
Use a View
object for the overlay, returned from TvInputService.Session.onCreateOverlayView()
, as shown here:
@Override public View onCreateOverlayView() { LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); View view = inflater.inflate(R.layout.overlayview, null); mSubtitleView = (SubtitleView) view.findViewById(R.id.subtitles); // Configure the subtitle view. CaptionStyleCompat captionStyle; float captionTextSize = getCaptionFontSize(); captionStyle = CaptionStyleCompat.createFromCaptionStyle( mCaptioningManager.getUserStyle()); captionTextSize *= mCaptioningManager.getFontScale(); mSubtitleView.setStyle(captionStyle); mSubtitleView.setTextSize(captionTextSize); return view; }
.> When you call TvInputService.Session.onTune()
, you can prevent the video from being presented by calling TvInputService.Session.notifyVideoUnavailable()
and passing the VIDEO_UNAVAILABLE_REASON_TUNING
constant, as shown in the following example.
@Override public boolean onTune(Uri channelUri) { if (mSubtitleView != null) { mSubtitleView.setVisibility(View.INVISIBLE); } notifyVideoUnavailable(TvInputManager.VIDEO_UNAVAILABLE_REASON_TUNING); mUnblockedRatingSet.clear(); mDbHandler.removeCallbacks(mPlayCurrentProgramRunnable); mPlayCurrentProgramRunnable = new PlayCurrentProgramRunnable(channelUri); mDbHandler.post(mPlayCurrentProgramRunnable); return true; }
Then, when the content is rendered to the Surface
, you callTvInputService.Session.notifyVideoAvailable()
to allow the video to display, like so:
@Override public void onDrawnToSurface(Surface surface) { mFirstFrameDrawn = true; notifyVideoAvailable(); }