প্লেলিস্ট

প্লেলিস্ট API Player ইন্টারফেস দ্বারা সংজ্ঞায়িত করা হয়, যা সমস্ত ExoPlayer বাস্তবায়ন দ্বারা প্রয়োগ করা হয়। প্লেলিস্টগুলি একাধিক মিডিয়া আইটেমের ক্রমিক প্লেব্যাক সক্ষম করে৷ নিম্নলিখিত উদাহরণ দেখায় কিভাবে দুটি ভিডিও সমন্বিত একটি প্লেলিস্টের প্লেব্যাক শুরু করতে হয়:

কোটলিন

// Build the media items.
val firstItem = MediaItem.fromUri(firstVideoUri)
val secondItem = MediaItem.fromUri(secondVideoUri)
// Add the media items to be played.
player.addMediaItem(firstItem)
player.addMediaItem(secondItem)
// Prepare the player.
player.prepare()
// Start the playback.
player.play()

জাভা

// Build the media items.
MediaItem firstItem = MediaItem.fromUri(firstVideoUri);
MediaItem secondItem = MediaItem.fromUri(secondVideoUri);
// Add the media items to be played.
player.addMediaItem(firstItem);
player.addMediaItem(secondItem);
// Prepare the player.
player.prepare();
// Start the playback.
player.play();

একটি প্লেলিস্টের আইটেমগুলির মধ্যে পরিবর্তনগুলি বিরামহীন৷ সেগুলি একই ফর্ম্যাটের হওয়ার কোনও প্রয়োজন নেই (উদাহরণস্বরূপ, একটি প্লেলিস্টের জন্য H264 এবং VP9 উভয় ভিডিও থাকা ভাল)৷ এগুলি এমনকি বিভিন্ন ধরণের হতে পারে (অর্থাৎ, একটি প্লেলিস্টে ভিডিও, চিত্র এবং অডিও কেবল স্ট্রিম থাকা ভাল)৷ আপনি একটি প্লেলিস্টের মধ্যে একই MediaItem একাধিকবার ব্যবহার করতে পারেন।

প্লেলিস্ট পরিবর্তন করা হচ্ছে

মিডিয়া আইটেম যোগ, সরানো, অপসারণ বা প্রতিস্থাপন করে আপনি গতিশীলভাবে একটি প্লেলিস্ট পরিবর্তন করতে পারেন। এটি সংশ্লিষ্ট প্লেলিস্ট API পদ্ধতিতে কল করে প্লেব্যাকের আগে এবং সময় উভয়ই করা যেতে পারে:

কোটলিন

// Adds a media item at position 1 in the playlist.
player.addMediaItem(/* index= */ 1, MediaItem.fromUri(thirdUri))
// Moves the third media item from position 2 to the start of the playlist.
player.moveMediaItem(/* currentIndex= */ 2, /* newIndex= */ 0)
// Removes the first item from the playlist.
player.removeMediaItem(/* index= */ 0)
// Replace the second item in the playlist.
player.replaceMediaItem(/* index= */ 1, MediaItem.fromUri(newUri))

জাভা

// Adds a media item at position 1 in the playlist.
player.addMediaItem(/* index= */ 1, MediaItem.fromUri(thirdUri));
// Moves the third media item from position 2 to the start of the playlist.
player.moveMediaItem(/* currentIndex= */ 2, /* newIndex= */ 0);
// Removes the first item from the playlist.
player.removeMediaItem(/* index= */ 0);
// Replace the second item in the playlist.
player.replaceMediaItem(/* index= */ 1, MediaItem.fromUri(newUri));

সম্পূর্ণ প্লেলিস্ট প্রতিস্থাপন এবং সাফ করাও সমর্থিত:

কোটলিন

// Replaces the playlist with a new one.
val newItems: List<MediaItem> = listOf(MediaItem.fromUri(fourthUri), MediaItem.fromUri(fifthUri))
player.setMediaItems(newItems, /* resetPosition= */ true)
// Clears the playlist. If prepared, the player transitions to the ended state.
player.clearMediaItems()

জাভা

// Replaces the playlist with a new one.
ImmutableList<MediaItem> newItems =
    ImmutableList.of(MediaItem.fromUri(fourthUri), MediaItem.fromUri(fifthUri));
player.setMediaItems(newItems, /* resetPosition= */ true);
// Clears the playlist. If prepared, the player transitions to the ended state.
player.clearMediaItems();

প্লেয়ার সঠিক উপায়ে প্লেব্যাকের সময় পরিবর্তনগুলি স্বয়ংক্রিয়ভাবে পরিচালনা করে:

  • বর্তমানে বাজানো MediaItem সরানো হলে, প্লেব্যাক বাধাগ্রস্ত হবে না এবং এর নতুন উত্তরসূরিটি সম্পূর্ণ হওয়ার পরে চালানো হবে।
  • যদি বর্তমানে প্লে করা MediaItem সরানো হয়, তাহলে প্লেয়ারটি স্বয়ংক্রিয়ভাবে প্রথম অবশিষ্ট উত্তরসূরি বাজাবে, অথবা যদি এই ধরনের কোনো উত্তরসূরি বিদ্যমান না থাকে তাহলে শেষ অবস্থায় স্থানান্তরিত হবে।
  • বর্তমানে বাজানো MediaItem প্রতিস্থাপিত হলে, প্লেব্যাকের জন্য প্রাসঙ্গিক MediaItem এর কোনো বৈশিষ্ট্য পরিবর্তিত না হলে প্লেব্যাক ব্যাহত হয় না। উদাহরণস্বরূপ, প্লেব্যাককে প্রভাবিত না করেই বেশিরভাগ ক্ষেত্রে MediaItem.MediaMetadata ক্ষেত্র আপডেট করা সম্ভব।

প্লেলিস্ট জিজ্ঞাসা করা হচ্ছে

Player.getMediaItemCount এবং Player.getMediaItemAt ব্যবহার করে প্লেলিস্টটি জিজ্ঞাসা করা যেতে পারে। Player.getCurrentMediaItem কল করে বর্তমানে প্লে করা মিডিয়া আইটেমটি জিজ্ঞাসা করা যেতে পারে। প্লেলিস্টে নেভিগেশন সহজ করার জন্য Player.hasNextMediaItem বা Player.getNextMediaItemIndex এর মতো অন্যান্য সুবিধার পদ্ধতিও রয়েছে।

পুনরাবৃত্তি মোড

প্লেয়ারটি 3টি পুনরাবৃত্তি মোড সমর্থন করে যা Player.setRepeatMode এর সাথে যেকোনো সময় সেট করা যেতে পারে:

  • Player.REPEAT_MODE_OFF : প্লেলিস্টের পুনরাবৃত্তি হয় না এবং প্লেয়ার Player.STATE_ENDED স্থানান্তরিত হবে৷ প্লেলিস্টের শেষ আইটেমটি একবার প্লে হয়ে গেলে STATE_ENDED৷
  • Player.REPEAT_MODE_ONE : বর্তমান আইটেমটি একটি অন্তহীন লুপে পুনরাবৃত্তি হয়৷ Player.seekToNextMediaItem এর মতো পদ্ধতিগুলি এটিকে উপেক্ষা করবে এবং তালিকার পরবর্তী আইটেমটি খুঁজবে, যা তারপরে একটি অন্তহীন লুপে পুনরাবৃত্তি হবে৷
  • Player.REPEAT_MODE_ALL : সম্পূর্ণ প্লেলিস্ট একটি অন্তহীন লুপে পুনরাবৃত্তি হয়৷

শাফেল মোড

Player.setShuffleModeEnabled এর মাধ্যমে শাফেল মোড যে কোনো সময় সক্ষম বা নিষ্ক্রিয় করা যেতে পারে। শাফেল মোডে থাকাকালীন, প্লেয়ার প্লেলিস্টটি একটি পূর্বনির্ধারিত, এলোমেলো ক্রমে খেলবে৷ সমস্ত আইটেম একবার বাজানো হবে এবং Player.REPEAT_MODE_ALL সাথে শাফেল মোডও মিলিত হতে পারে৷ একটি অবিরাম লুপে একই এলোমেলো ক্রম পুনরাবৃত্তি করতে REPEAT_MODE_ALL৷ শাফেল মোড বন্ধ থাকলে, প্লেলিস্টে বর্তমান আইটেম থেকে প্লেব্যাক তার আসল অবস্থানে চলতে থাকে।

মনে রাখবেন যে Player.getCurrentMediaItemIndex এর মত পদ্ধতির দ্বারা প্রত্যাবর্তিত সূচকগুলি সর্বদা আসল, আনশাফেল ক্রম নির্দেশ করে। একইভাবে, Player.seekToNextMediaItem player.getCurrentMediaItemIndex() + 1 এ আইটেমটি চালাবে না, তবে শাফেল ক্রম অনুসারে পরবর্তী আইটেমটি চালাবে। প্লেলিস্টে নতুন আইটেম সন্নিবেশ করানো বা আইটেমগুলি সরিয়ে ফেলার ফলে বিদ্যমান এলোমেলো ক্রম যতদূর সম্ভব অপরিবর্তিত থাকবে।

একটি কাস্টম শাফেল অর্ডার সেট করা হচ্ছে

ডিফল্টরূপে, প্লেয়ারটি DefaultShuffleOrder শাফলঅর্ডার ব্যবহার করে শাফলিং সমর্থন করে। এটি একটি কাস্টম শাফেল অর্ডার বাস্তবায়ন প্রদান করে বা DefaultShuffleOrder কনস্ট্রাক্টরে একটি কাস্টম অর্ডার সেট করে কাস্টমাইজ করা যেতে পারে:

কোটলিন

// Set a custom shuffle order for the 5 items currently in the playlist:
exoPlayer.setShuffleOrder(DefaultShuffleOrder(intArrayOf(3, 1, 0, 4, 2), randomSeed))
// Enable shuffle mode.
exoPlayer.shuffleModeEnabled = true

জাভা

// Set a custom shuffle order for the 5 items currently in the playlist:
exoPlayer.setShuffleOrder(new DefaultShuffleOrder(new int[] {3, 1, 0, 4, 2}, randomSeed));
// Enable shuffle mode.
exoPlayer.setShuffleModeEnabled(/* shuffleModeEnabled= */ true);

প্লেলিস্ট আইটেম সনাক্তকরণ

প্লেলিস্ট আইটেমগুলি সনাক্ত করতে, আইটেমটি তৈরি করার সময় MediaItem.mediaId সেট করা যেতে পারে:

কোটলিন

// Build a media item with a media ID.
val mediaItem = MediaItem.Builder().setUri(uri).setMediaId(mediaId).build()

জাভা

// Build a media item with a media ID.
MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setMediaId(mediaId).build();

যদি একটি অ্যাপ স্পষ্টভাবে একটি মিডিয়া আইটেমের জন্য একটি মিডিয়া আইডি সংজ্ঞায়িত না করে, তাহলে URI-এর স্ট্রিং উপস্থাপনা ব্যবহার করা হয়।

প্লেলিস্ট আইটেমগুলির সাথে অ্যাপ ডেটা সংযুক্ত করা

একটি আইডি ছাড়াও, প্রতিটি মিডিয়া আইটেম একটি কাস্টম ট্যাগ দিয়ে কনফিগার করা যেতে পারে, যা যেকোন অ্যাপ প্রদত্ত বস্তু হতে পারে। কাস্টম ট্যাগের একটি ব্যবহার হল প্রতিটি মিডিয়া আইটেমের সাথে মেটাডেটা সংযুক্ত করা:

কোটলিন

// Build a media item with a custom tag.
val mediaItem = MediaItem.Builder().setUri(uri).setTag(metadata).build()

জাভা

// Build a media item with a custom tag.
MediaItem mediaItem = new MediaItem.Builder().setUri(uri).setTag(metadata).build();

প্লেব্যাক যখন অন্য মিডিয়া আইটেমে স্থানান্তরিত হয় তা সনাক্ত করা

যখন প্লেব্যাক অন্য মিডিয়া আইটেমে রূপান্তরিত হয়, বা একই মিডিয়া আইটেমের পুনরাবৃত্তি শুরু করে, Listener.onMediaItemTransition(MediaItem, @MediaItemTransitionReason) বলা হয়। এই কলব্যাকটি একটি @MediaItemTransitionReason সহ নতুন মিডিয়া আইটেমটি গ্রহণ করে যে কেন রূপান্তর ঘটেছে। onMediaItemTransition এর একটি সাধারণ ব্যবহারের ক্ষেত্রে হল নতুন মিডিয়া আইটেমের জন্য অ্যাপের UI আপডেট করা:

কোটলিন

override fun onMediaItemTransition(
  mediaItem: MediaItem?,
  @MediaItemTransitionReason reason: Int,
) {
  updateUiForPlayingMediaItem(mediaItem)
}

জাভা

@Override
public void onMediaItemTransition(
    @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) {
  updateUiForPlayingMediaItem(mediaItem);
}

UI আপডেট করার জন্য প্রয়োজনীয় মেটাডেটা যদি কাস্টম ট্যাগ ব্যবহার করে প্রতিটি মিডিয়া আইটেমের সাথে সংযুক্ত থাকে, তাহলে একটি বাস্তবায়ন দেখতে এরকম হতে পারে:

কোটলিন

override fun onMediaItemTransition(
  mediaItem: MediaItem?,
  @MediaItemTransitionReason reason: Int,
) {
  var metadata: CustomMetadata? = null
  mediaItem?.localConfiguration?.let { localConfiguration ->
    metadata = localConfiguration.tag as? CustomMetadata
  }
  updateUiForPlayingMediaItem(metadata)
}

জাভা

@Override
public void onMediaItemTransition(
    @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) {
  @Nullable CustomMetadata metadata = null;
  if (mediaItem != null && mediaItem.localConfiguration != null) {
    metadata = (CustomMetadata) mediaItem.localConfiguration.tag;
  }
  updateUiForPlayingMediaItem(metadata);
}

প্লেলিস্ট পরিবর্তন হলে সনাক্ত করা

যখন একটি মিডিয়া আইটেম যোগ করা হয়, সরানো হয় বা সরানো হয়, Listener.onTimelineChanged(Timeline, @TimelineChangeReason) TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED এর সাথে অবিলম্বে কল করা হয়। এই কলব্যাক বলা হয় এমনকি যখন প্লেয়ার এখনও প্রস্তুত করা হয়নি।

কোটলিন

override fun onTimelineChanged(timeline: Timeline, @TimelineChangeReason reason: Int) {
  if (reason == Player.TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) {
    // Update the UI according to the modified playlist (add, move or remove).
    updateUiForPlaylist(timeline)
  }
}

জাভা

@Override
public void onTimelineChanged(Timeline timeline, @TimelineChangeReason int reason) {
  if (reason == TIMELINE_CHANGE_REASON_PLAYLIST_CHANGED) {
    // Update the UI according to the modified playlist (add, move or remove).
    updateUiForPlaylist(timeline);
  }
}

যখন প্লেলিস্টে একটি মিডিয়া আইটেমের সময়কালের মতো তথ্য উপলব্ধ হয়, তখন Timeline আপডেট করা হবে এবং TIMELINE_CHANGE_REASON_SOURCE_UPDATE এর সাথে onTimelineChanged কল করা হবে। টাইমলাইন আপডেটের কারণ হতে পারে এমন অন্যান্য কারণগুলির মধ্যে রয়েছে:

  • একটি অভিযোজিত মিডিয়া আইটেম প্রস্তুত করার পরে একটি ম্যানিফেস্ট উপলব্ধ হচ্ছে৷
  • একটি ম্যানিফেস্ট একটি লাইভ স্ট্রিম প্লেব্যাকের সময় পর্যায়ক্রমে আপডেট করা হচ্ছে৷