ट्रांसपोर्ट कंट्रोल इस्तेमाल करें

Compose की मदद से बेहतर ऐप्लिकेशन बनाना
Android TV OS के लिए Jetpack Compose का इस्तेमाल करके, कम से कम कोड में शानदार यूज़र इंटरफ़ेस (यूआई) बनाएं.

Leanback यूज़र इंटरफ़ेस (यूआई) टूलकिट में, प्लेबैक कंट्रोल की सुविधा है. इससे उपयोगकर्ता को बेहतर अनुभव मिलता है. वीडियो ऐप्लिकेशन के लिए, ट्रांसपोर्ट कंट्रोल की मदद से वीडियो को आगे-पीछे किया जा सकता है. वीडियो को आगे-पीछे करने पर, थंबनेल दिखते हैं. इससे वीडियो में नेविगेट करने में मदद मिलती है.

इस लाइब्रेरी में, ऐब्स्ट्रैक्ट क्लास के साथ-साथ, पहले से बने और आउट-ऑफ़-द-बॉक्स लागू करने की सुविधाएं भी शामिल हैं. इससे डेवलपर को ज़्यादा कंट्रोल मिलता है. पहले से बने लागू करने की सुविधाओं का इस्तेमाल करके, बिना ज़्यादा कोडिंग किए, सुविधाओं से भरा ऐप्लिकेशन बनाया जा सकता है. अगर आपको ज़्यादा बदलाव करने हैं, तो लाइब्रेरी के पहले से बने किसी भी कॉम्पोनेंट को बढ़ाया जा सकता है.

कंट्रोल और प्लेयर

Leanback यूज़र इंटरफ़ेस (यूआई) टूलकिट, ट्रांसपोर्ट कंट्रोल के यूज़र इंटरफ़ेस (यूआई) को वीडियो चलाने वाले प्लेयर से अलग करता है. यह काम दो कॉम्पोनेंट की मदद से किया जाता है: पहला, ट्रांसपोर्ट कंट्रोल (और ज़रूरत पड़ने पर वीडियो) दिखाने के लिए प्लेबैक सपोर्ट फ़्रैगमेंट. दूसरा, मीडिया प्लेयर को एनकैप्सुलेट करने के लिए प्लेयर अडैप्टर.

प्लेबैक फ़्रैगमेंट

आपके ऐप्लिकेशन के यूज़र इंटरफ़ेस (यूआई) की गतिविधि के लिए, PlaybackSupportFragment या VideoSupportFragment का इस्तेमाल किया जाना चाहिए. इन दोनों में, Leanback ट्रांसपोर्ट कंट्रोल शामिल होते हैं:

  • PlaybackSupportFragment, ज़रूरत के हिसाब से ट्रांसपोर्ट कंट्रोल को छिपाने/दिखाने के लिए, उनमें ऐनिमेशन जोड़ता है.
  • VideoSupportFragment, PlaybackSupportFragment का एक्सटेंशन है. इसमें वीडियो रेंडर करने के लिए, SurfaceView होता है.

यूज़र इंटरफ़ेस (यूआई) को बेहतर बनाने के लिए, फ़्रैगमेंट के ObjectAdapter को पसंद के मुताबिक बनाया जा सकता है. उदाहरण के लिए, "मिलते-जुलते वीडियो" वाली लाइन जोड़ने के लिए, setAdapter() का इस्तेमाल करें.

PlayerAdapter

PlayerAdapter एक ऐब्स्ट्रैक्ट क्लास है, जो मीडिया प्लेयर को कंट्रोल करती है. डेवलपर, पहले से बने MediaPlayerAdapter को लागू करने का विकल्प चुन सकते हैं या इस क्लास को लागू करने के लिए अपना कोड लिख सकते हैं.

अलग-अलग कॉम्पोनेंट को एक साथ जोड़ना

प्लेबैक फ़्रैगमेंट को प्लेयर से कनेक्ट करने के लिए, "कंट्रोल ग्लू" का इस्तेमाल करना ज़रूरी है. Leanback लाइब्रेरी में दो तरह के ग्लू उपलब्ध हैं:

  • PlaybackBannerControlGlue , प्लेबैक फ़्रैगमेंट में ट्रांसपोर्ट कंट्रोल को "पुराने स्टाइल" में दिखाता है. इसके लिए, उन्हें अपारदर्शी बैकग्राउंड में रखा जाता है. (PlaybackBannerControlGlue, PlaybackControlGlue की जगह लेता है. इसे बंद कर दिया गया है.)
  • PlaybackTransportControlGlue , पारदर्शी बैकग्राउंड के साथ "नए स्टाइल" के कंट्रोल का इस्तेमाल करता है.

leanback transport control glue

अगर आपको अपने ऐप्लिकेशन में वीडियो को आगे-पीछे करने की सुविधा देनी है, तो PlaybackTransportControlGlue का इस्तेमाल करना होगा.

आपको एक "ग्लू होस्ट" भी तय करना होगा. यह ग्लू को प्लेबैक फ़्रैगमेंट से बाइंड करता है, यूज़र इंटरफ़ेस (यूआई) में ट्रांसपोर्ट कंट्रोल दिखाता है और उनकी स्थिति बनाए रखता है. साथ ही, ट्रांसपोर्ट कंट्रोल के इवेंट को ग्लू पर वापस भेजता है. होस्ट, प्लेबैक फ़्रैगमेंट के टाइप से मेल खाना चाहिए. PlaybackFragment के साथ PlaybackSupportFragmentGlueHost और VideoFragment के साथ VideoSupportFragmentGlueHost का इस्तेमाल करें.

यहां एक उदाहरण दिया गया है, जिसमें दिखाया गया है कि Leanback ट्रांसपोर्ट कंट्रोल के कॉम्पोनेंट एक साथ कैसे काम करते हैं:

leanback transport control glue

आपके ऐप्लिकेशन को एक साथ जोड़ने वाला कोड, यूज़र इंटरफ़ेस (यूआई) को तय करने वाले PlaybackSupportFragment या VideoSupportFragment में होना चाहिए.

यहां दिए गए उदाहरण में, ऐप्लिकेशन PlaybackTransportControlGlue का एक इंस्टेंस बनाता है. इसे playerGlue नाम देता है, और इसके VideoSupportFragment को, नए बनाए गए MediaPlayerAdapter से कनेक्ट करता है. यह VideoSupportFragment है. इसलिए, सेटअप कोड, playerGlue से VideoSupportFragmentGlueHost को अटैच करने के लिए, setHost() को कॉल करता है. यह कोड, VideoSupportFragment को बढ़ाने वाली क्लास में शामिल होता है.

Kotlin

class MyVideoFragment : VideoSupportFragment() {

  fun onCreate(savedInstanceState: Bundle) {
      super.onCreate(savedInstanceState)
      val playerGlue = PlaybackTransportControlGlue(getActivity(),
          MediaPlayerAdapter(getActivity()))
      playerGlue.setHost(VideoSupportFragmentGlueHost(this))
      playerGlue.addPlayerCallback(object : PlaybackGlue.PlayerCallback() {
          override fun onPreparedStateChanged(glue: PlaybackGlue) {
              if (glue.isPrepared()) {
                  playerGlue.seekProvider = MySeekProvider()
                  playerGlue.play()
              }
          }
      })
      playerGlue.setSubtitle("Leanback artist")
      playerGlue.setTitle("Leanback team at work")
      val uriPath = "android.resource://com.example.android.leanback/raw/video"
      playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath))
  }
}

Java

public class MyVideoFragment extends VideoSupportFragment {

  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      final PlaybackTransportControlGlue<MediaPlayerAdapter> playerGlue =
              new PlaybackTransportControlGlue(getActivity(),
                      new MediaPlayerAdapter(getActivity()));
      playerGlue.setHost(new VideoSupportFragmentGlueHost(this));
      playerGlue.addPlayerCallback(new PlaybackGlue.PlayerCallback() {
          @Override
          public void onPreparedStateChanged(PlaybackGlue glue) {
              if (glue.isPrepared()) {
                  playerGlue.setSeekProvider(new MySeekProvider());
                  playerGlue.play();
              }
          }
      });
      playerGlue.setSubtitle("Leanback artist");
      playerGlue.setTitle("Leanback team at work");
      String uriPath = "android.resource://com.example.android.leanback/raw/video";
      playerGlue.getPlayerAdapter().setDataSource(Uri.parse(uriPath));
  }
}

ध्यान दें कि सेटअप कोड, मीडिया प्लेयर से इवेंट को हैंडल करने के लिए, PlayerAdapter.Callback भी तय करता है.

यूज़र इंटरफ़ेस (यूआई) ग्लू को पसंद के मुताबिक बनाना

PlaybackControlsRow में बदलाव करने के लिए, PlaybackBannerControlGlue और PlaybackTransportControlGlue को पसंद के मुताबिक बनाया जा सकता है.

टाइटल और ब्यौरे को पसंद के मुताबिक बनाना

प्लेबैक कंट्रोल में सबसे ऊपर दिखने वाले टाइटल और ब्यौरे को पसंद के मुताबिक बनाने के लिए, onCreateRowPresenter() को ओवरराइड करें:

Kotlin

override fun onCreateRowPresenter(): PlaybackRowPresenter {
    return super.onCreateRowPresenter().apply {
        (this as? PlaybackTransportRowPresenter)
                ?.setDescriptionPresenter(MyCustomDescriptionPresenter())
    }
}

Java

@Override
protected PlaybackRowPresenter onCreateRowPresenter() {
  PlaybackTransportRowPresenter presenter = (PlaybackTransportRowPresenter) super.onCreateRowPresenter();
  presenter.setDescriptionPresenter(new MyCustomDescriptionPresenter());
  return presenter;
}

कंट्रोल जोड़ना

कंट्रोल ग्लू, PlaybackControlsRow में कार्रवाइयों के लिए कंट्रोल दिखाता है.

PlaybackControlsRow में मौजूद कार्रवाइयों को दो ग्रुप में असाइन किया जाता है: प्राइमरी कार्रवाइयां और सेकंडरी कार्रवाइयां. प्राइमरी ग्रुप के कंट्रोल, सीक बार के ऊपर दिखते हैं. वहीं, सेकंडरी ग्रुप के कंट्रोल, सीक बार के नीचे दिखते हैं. शुरुआत में, प्ले/पॉज़ बटन के लिए सिर्फ़ एक प्राइमरी कार्रवाई होती है. साथ ही, कोई सेकंडरी कार्रवाई नहीं होती.

onCreatePrimaryActions() और onCreateSecondaryActions() को ओवरराइड करके, प्राइमरी और सेकंडरी ग्रुप में कार्रवाइयां जोड़ी जा सकती हैं.

Kotlin

private lateinit var repeatAction: PlaybackControlsRow.RepeatAction
private lateinit var pipAction: PlaybackControlsRow.PictureInPictureAction
private lateinit var thumbsUpAction: PlaybackControlsRow.ThumbsUpAction
private lateinit var thumbsDownAction: PlaybackControlsRow.ThumbsDownAction
private lateinit var skipPreviousAction: PlaybackControlsRow.SkipPreviousAction
private lateinit var skipNextAction: PlaybackControlsRow.SkipNextAction
private lateinit var fastForwardAction: PlaybackControlsRow.FastForwardAction
private lateinit var rewindAction: PlaybackControlsRow.RewindAction

override fun onCreatePrimaryActions(primaryActionsAdapter: ArrayObjectAdapter) {
    // Order matters, super.onCreatePrimaryActions() will create the play / pause action.
    // Will display as follows:
    // play/pause, previous, rewind, fast forward, next
    //   > /||      |<        <<        >>         >|
    super.onCreatePrimaryActions(primaryActionsAdapter)
    primaryActionsAdapter.apply {
        add(skipPreviousAction)
        add(rewindAction)
        add(fastForwardAction)
        add(skipNextAction)
    }
}

override fun onCreateSecondaryActions(adapter: ArrayObjectAdapter?) {
    super.onCreateSecondaryActions(adapter)
    adapter?.apply {
        add(thumbsDownAction)
        add(thumbsUpAction)
    }
}

Java

private PlaybackControlsRow.RepeatAction repeatAction;
private PlaybackControlsRow.PictureInPictureAction pipAction;
private PlaybackControlsRow.ThumbsUpAction thumbsUpAction;
private PlaybackControlsRow.ThumbsDownAction thumbsDownAction;
private PlaybackControlsRow.SkipPreviousAction skipPreviousAction;
private PlaybackControlsRow.SkipNextAction skipNextAction;
private PlaybackControlsRow.FastForwardAction fastForwardAction;
private PlaybackControlsRow.RewindAction rewindAction;

@Override
protected void onCreatePrimaryActions(ArrayObjectAdapter primaryActionsAdapter) {
    // Order matters, super.onCreatePrimaryActions() will create the play / pause action.
    // Will display as follows:
    // play/pause, previous, rewind, fast forward, next
    //   > /||      |<        <<        >>         >|
    super.onCreatePrimaryActions(primaryActionsAdapter);
    primaryActionsAdapter.add(skipPreviousAction);
    primaryActionsAdapter.add(rewindAction);
    primaryActionsAdapter.add(fastForwardAction);
    primaryActionsAdapter.add(skipNextAction);
}

@Override
protected void onCreateSecondaryActions(ArrayObjectAdapter adapter) {
    super.onCreateSecondaryActions(adapter);
    adapter.add(thumbsDownAction);
    adapter.add(thumbsUpAction);
}

नई कार्रवाइयों को हैंडल करने के लिए, onActionClicked() को ओवरराइड करना ज़रूरी है.

Kotlin

override fun onActionClicked(action: Action) {
    when(action) {
        rewindAction -> {
            // Handle Rewind
        }
        fastForwardAction -> {
            // Handle FastForward
        }
        thumbsDownAction -> {
            // Handle ThumbsDown
        }
        thumbsUpAction -> {
            // Handle ThumbsUp
        }
        else ->
            // The superclass handles play/pause and delegates next/previous actions to abstract methods,
            // so those two methods should be overridden rather than handling the actions here.
            super.onActionClicked(action)
    }
}

override fun next() {
    // Skip to next item in playlist.
}

override fun previous() {
    // Skip to previous item in playlist.
}

Java

@Override
public void onActionClicked(Action action) {
    if (action == rewindAction) {
        // Handle Rewind
    } else if (action == fastForwardAction ) {
        // Handle FastForward
    } else if (action == thumbsDownAction) {
        // Handle ThumbsDown
    } else if (action == thumbsUpAction) {
        // Handle ThumbsUp
    } else {
        // The superclass handles play/pause and delegates next/previous actions to abstract methods,
        // so those two methods should be overridden rather than handling the actions here.
        super.onActionClicked(action);
    }
}

@Override
public void next() {
    // Skip to next item in playlist.
}

@Override
public void previous() {
    // Skip to previous item in playlist.
}

खास मामलों में, हो सकता है कि आपको कस्टम कंट्रोल रेंडर करने और PlaybackSeekUi का इस्तेमाल करके, सीक ऐक्शन का जवाब देने के लिए, अपना PlaybackTransportRowPresenter लागू करना पड़े.

वीडियो को आगे-पीछे करना

अगर आपका ऐप्लिकेशन, VideoSupportFragment का इस्तेमाल करता है और आपको वीडियो को आगे-पीछे करने की सुविधा देनी है.

बरतन अभी धोने हैं

आपको PlaybackSeekDataProvider को लागू करना होगा. यह कॉम्पोनेंट, स्क्रोल करने पर दिखने वाले वीडियो के थंबनेल उपलब्ध कराता है. PlaybackSeekDataProvider को बढ़ाकर, आपको अपना प्रोवाइडर लागू करना होगा. उदाहरण के लिए, Leanback Showcase ऐप्लिकेशन देखें. .