Player ইন্টারফেসের মাধ্যমে প্লেলিস্ট API সংজ্ঞায়িত করা হয়, যা
সব ExoPlayer প্রয়োগের মাধ্যমে প্রয়োগ করা হয়। প্লেলিস্টে একাধিক মিডিয়া আইটেম
ক্রম অনুযায়ী চালানো যায়। নিচের উদাহরণে দেখানো হয়েছে যে কীভাবে দুটি ভিডিও সহ একটি
প্লেলিস্টের
প্লেব্যাক শুরু করতে হয়:
Kotlin
// 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 পদ্ধতি কল করে প্লেব্যাকের আগে ও চলাকালীন, দু'টি সময়েই এটি করা যেতে পারে:
Kotlin
// 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));
এছাড়াও, সম্পূর্ণ প্লেলিস্ট পরিবর্তন ও মুছে দেওয়ার সুবিধা কাজ করে:
Kotlin
// 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-এর মতো অন্যান্য সহজ
পদ্ধতিও রয়েছে।
রিপিট মোড
প্লেয়ারে ৩টি রিপিট মোড কাজ করে যা যেকোনও সময়
Player.setRepeatMode-এর মাধ্যমে সেট করা যায়:
Player.REPEAT_MODE_OFF: প্লেলিস্ট রিপিট করা হয় না এবং প্লেলিস্টের শেষ আইটেমটি চালানো হয়ে গেলে প্লেয়ারPlayer.STATE_ENDED-এ ট্রানজিট করবে।Player.REPEAT_MODE_ONE: বর্তমান আইটেমটি একটি অন্তহীন লুপে রিপিট হচ্ছে।Player.seekToNextMediaItem-এর মতো পদ্ধতি এটি উপেক্ষা করবে এবং তালিকার পরবর্তী আইটেমটি খুঁজবে, যা তারপরে একটি অন্তহীন লুপে পুনরাবৃত্তি করা হবে।Player.REPEAT_MODE_ALL: পুরো প্লেলিস্টটি একটি অন্তহীন লুপে রিপিট করা হয়।
শাফেল মোড
Player.setShuffleModeEnabled-এর মাধ্যমে যেকোনও সময় শাফেল মোড চালু বা বন্ধ করা যেতে পারে।
শাফেল মোডে থাকলে, প্লেয়ারটি আগে থেকে কম্পিউট করা, র্যান্ডমাইজ করা ক্রমে প্লেলিস্ট চালাবে। সব আইটেম একবার করে চালানো হবে এবং
শাফেল মোডকে Player.REPEAT_MODE_ALL-এর সাথে একত্রিত করে একই র্যান্ডমাইজ করা ক্রমকে
অনন্ত লুপে রিপিট করা যাবে। শাফেল মোড বন্ধ করা থাকলে,
প্লেলিস্টে বর্তমান আইটেমটি যেখানে আছে সেখান থেকেই
প্লেব্যাক চলতে থাকে।
মনে রাখবেন যে
Player.getCurrentMediaItemIndex-এর মতো পদ্ধতি দ্বারা রিটার্ন করা ইন্ডেক্স সবসময় আসল, আনশাফেল করা
ক্রমকে বোঝায়। একইভাবে, Player.seekToNextMediaItem আইটেমটি
player.getCurrentMediaItemIndex() + 1-এ চালাবে না, তবে
শাফেল অর্ডার অনুযায়ী পরের আইটেমটি চালাবে। প্লেলিস্টে নতুন আইটেম যোগ করা বা আইটেম সরিয়ে দেওয়া হলে, যতটা সম্ভব আগে থেকে থাকা
শাফেল করা ক্রম অপরিবর্তিত রাখা হবে।
কাস্টম শাফেল অর্ডার সেট করা
ডিফল্ট হিসেবে, প্লেয়ার DefaultShuffleOrder ব্যবহার করে অডিও ও ভিডিও শাফেল করার সুবিধা দেয়।
কাস্টম শাফেল অর্ডার প্রয়োগ করে অথবা DefaultShuffleOrder কনস্ট্রাক্টরে কাস্টম অর্ডার সেট করে এটি কাস্টমাইজ করা যেতে পারে:
Kotlin
// 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 সেট করা যেতে পারে:
Kotlin
// 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-এর স্ট্রিং রেপ্রেজেন্টেশন ব্যবহার করা হয়।
প্লেলিস্ট আইটেমের সাথে অ্যাপ ডেটা অ্যাসোসিয়েট করা
আইডি ছাড়াও, প্রতিটি মিডিয়া আইটেমকে কাস্টম ট্যাগ দিয়েও কনফিগার করা যেতে পারে, যা অ্যাপের দেওয়া যেকোনও অবজেক্ট হতে পারে। কাস্টম ট্যাগের একটি ব্যবহার হল প্রতিটি মিডিয়া আইটেমের সাথে মেটাডেটা অ্যাটাচ করা:
Kotlin
// 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 আপডেট করা:
Kotlin
override fun onMediaItemTransition( mediaItem: MediaItem?, @MediaItemTransitionReason reason: Int, ) { updateUiForPlayingMediaItem(mediaItem) }
জাভা
@Override public void onMediaItemTransition( @Nullable MediaItem mediaItem, @MediaItemTransitionReason int reason) { updateUiForPlayingMediaItem(mediaItem); }
UI আপডেট করার জন্য প্রয়োজনীয় মেটাডেটা কাস্টম ট্যাগ ব্যবহার করে প্রতিটি মিডিয়া আইটেমের সাথে অ্যাটাচ করা থাকলে, ইমপ্লিমেন্টেশনটি এইরকম হতে পারে:
Kotlin
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-এর সাথে
অবিলম্বে কল করা হয়। প্লেয়ার এখনও প্রস্তুত না হলেও এই কলব্যাক
কল করা হয়।
Kotlin
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 কল করা
হবে। টাইমলাইন আপডেট হওয়ার অন্যান্য কারণের মধ্যে
এগুলি অন্তর্ভুক্ত:
- অ্যাডাপ্টিভ মিডিয়া আইটেম তৈরি করার পরে ম্যানিফেস্ট উপলভ্য হওয়া।
- লাইভ স্ট্রিম প্লেব্যাক চলাকালীন একটি ম্যানিফেস্ট নির্দিষ্ট সময় অন্তর আপডেট করা হচ্ছে।