Media3 একটি ডিফল্ট PlayerView প্রদান করে যা কিছু কাস্টমাইজেশন বিকল্প প্রদান করে।
ড্রয়েবল ওভাররাইড করুন
প্লেব্যাক কন্ট্রোল এবং প্রোগ্রেস বার প্রদর্শনের জন্য PlayerView PlayerControlView ব্যবহার করে। PlayerControlView দ্বারা ব্যবহৃত ড্রয়েবলগুলি আপনার অ্যাপ্লিকেশনে সংজ্ঞায়িত একই নামের ড্রয়েবলগুলি দ্বারা ওভাররাইড করা যেতে পারে। ওভাররাইড করা যেতে পারে এমন কন্ট্রোল ড্রয়েবলগুলির তালিকার জন্য PlayerControlView ডকুমেন্টেশন দেখুন।
আরও যেকোনো কাস্টমাইজেশনের জন্য, অ্যাপ ডেভেলপারদের তাদের নিজস্ব UI উপাদান বাস্তবায়নের আশা করা হয়। তবে, এখানে কিছু সেরা অনুশীলন রয়েছে যা আপনাকে শুরু করতে সাহায্য করতে পারে।
সেরা অনুশীলন
Media3 Player (যেমন ExoPlayer , MediaController অথবা কাস্টম Player বাস্তবায়ন) এর সাথে সংযুক্ত একটি মিডিয়া UI বাস্তবায়ন করার সময়, অ্যাপগুলিকে সেরা UI অভিজ্ঞতার জন্য এই সেরা অনুশীলনগুলি অনুসরণ করার পরামর্শ দেওয়া হয়।
প্লে/পজ বোতাম
প্লে এবং পজ বোতামটি সরাসরি একটি একক প্লেয়ারের অবস্থার সাথে সঙ্গতিপূর্ণ নয়। উদাহরণস্বরূপ, প্লেয়ারটি পজ না করা থাকলেও, প্লেব্যাকটি শেষ হয়ে গেলে বা ব্যর্থ হওয়ার পরে একজন ব্যবহারকারী প্লেব্যাক পুনরায় চালু করতে সক্ষম হবেন।
বাস্তবায়ন সহজ করার জন্য, Media3 কোন বোতামটি দেখাবে তা নির্ধারণ করার জন্য util পদ্ধতি প্রদান করে ( Util.shouldShowPlayButton ) এবং বোতাম টিপলে ( Util.handlePlayPauseButtonAction ) পরিচালনা করতে:
কোটলিন
val shouldShowPlayButton: Boolean = Util.shouldShowPlayButton(player) playPauseButton.setImageDrawable(if (shouldShowPlayButton) playDrawable else pauseDrawable) playPauseButton.setOnClickListener { Util.handlePlayPauseButtonAction(player) }
জাভা
boolean shouldShowPlayButton = Util.shouldShowPlayButton(player); playPauseButton.setImageDrawable(shouldShowPlayButton ? playDrawable : pauseDrawable); playPauseButton.setOnClickListener(view -> Util.handlePlayPauseButtonAction(player));
রাজ্যের আপডেট শুনুন
UI কম্পোনেন্টে একটি Player.Listener যোগ করতে হবে যাতে সংশ্লিষ্ট UI আপডেটের প্রয়োজন হয় এমন অবস্থার পরিবর্তন সম্পর্কে অবহিত হতে পারে। বিস্তারিত জানার জন্য প্লেব্যাক ইভেন্ট শুনুন দেখুন।
UI রিফ্রেশ করা ব্যয়বহুল হতে পারে এবং একাধিক প্লেয়ার ইভেন্ট প্রায়শই একসাথে আসে। অল্প সময়ের মধ্যে UI খুব বেশি রিফ্রেশ না করার জন্য, সাধারণত onEvents শোনা এবং সেখান থেকে UI আপডেটগুলি ট্রিগার করা ভাল:
কোটলিন
player.addListener(object : Player.Listener{ override fun onEvents(player: Player, events: Player.Events){ if (events.containsAny( Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_PLAYBACK_STATE_CHANGED, Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) { updatePlayPauseButton() } if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) { updateRepeatModeButton() } } })
জাভা
player.addListener(new Player.Listener() { @Override public void onEvents(Player player, Player.Events events) { if (events.containsAny( Player.EVENT_PLAY_WHEN_READY_CHANGED, Player.EVENT_PLAYBACK_STATE_CHANGED, Player.EVENT_PLAYBACK_SUPPRESSION_REASON_CHANGED)) { updatePlayPauseButton(); } if (events.containsAny(Player.EVENT_REPEAT_MODE_CHANGED)) { updateRepeatModeButton(); } } });
উপলব্ধ কমান্ডগুলি পরিচালনা করুন
একটি সাধারণ UI কম্পোনেন্ট যা বিভিন্ন Player বাস্তবায়নের সাথে কাজ করতে পারে, তাদের বোতামগুলি দেখানো বা লুকানোর জন্য এবং অসমর্থিত পদ্ধতিগুলি কল করা এড়াতে উপলব্ধ প্লেয়ার কমান্ডগুলি পরীক্ষা করা উচিত:
কোটলিন
nextButton.isEnabled = player.isCommandAvailable(COMMAND_SEEK_TO_NEXT)
জাভা
nextButton.setEnabled(player.isCommandAvailable(COMMAND_SEEK_TO_NEXT));
প্রথম ফ্রেমের শাটার এবং চিত্র প্রদর্শন
যখন একটি UI কম্পোনেন্ট ভিডিও বা ছবি প্রদর্শন করে, তখন এটি সাধারণত একটি প্লেসহোল্ডার শাটার ভিউ ব্যবহার করে যতক্ষণ না আসল প্রথম ফ্রেম বা ছবি পাওয়া যায়। এছাড়াও, মিশ্র ভিডিও এবং ছবি প্লেব্যাকের জন্য উপযুক্ত সময়ে ছবির ভিউ লুকানো এবং দেখানো প্রয়োজন।
এই আপডেটগুলি পরিচালনা করার একটি সাধারণ প্যাটার্ন হল নির্বাচিত ট্র্যাকগুলিতে যেকোনো পরিবর্তনের জন্য Player.Listener.onEvents() শোনা ( EVENT_TRACKS_CHANGED ) এবং প্রথম ভিডিও ফ্রেম রেন্ডার হওয়ার সময় ( EVENT_RENDERED_FIRST_FRAME ), এবং নতুন ছবি উপলব্ধ হওয়ার সময় ImageOutput.onImageAvailable() :
কোটলিন
override fun onEvents(player: Player, events: Player.Events) { if (events.contains(Player.EVENT_TRACKS_CHANGED)) { // If no video or image track: show shutter, hide image view. // Otherwise: do nothing to wait for first frame or image. } if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) { // Hide shutter, hide image view. } } override fun onImageAvailable(presentationTimeUs: Long, bitmap: Bitmap) { // Show shutter, set image and show image view. }
জাভা
@Override public void onEvents(Player player, Events events) { if (events.contains(Player.EVENT_TRACKS_CHANGED)) { // If no video or image track: show shutter, hide image view. // Otherwise: do nothing to wait for first frame or image. } if (events.contains(Player.EVENT_RENDERED_FIRST_FRAME)) { // Hide shutter, hide image view. } } @Override public void onImageAvailable(long presentationTimeUs, Bitmap bitmap) { // Show shutter, set image and show image view. }