প্লেয়ার ইন্টারফেস

প্লেয়ার হলো আপনার অ্যাপের সেই অংশ যা মিডিয়া আইটেম প্লেব্যাক করতে সাহায্য করে। মিডিয়া৩ Player ইন্টারফেসটি সাধারণত একটি প্লেয়ার দ্বারা পরিচালিত কার্যকারিতার জন্য একটি রূপরেখা তৈরি করে। এর মধ্যে অন্তর্ভুক্ত রয়েছে:

  • প্লে করা, থামানো এবং খোঁজার মতো প্লেব্যাক নিয়ন্ত্রণকে প্রভাবিত করে।
  • বর্তমানে প্লে হওয়া মিডিয়ার বৈশিষ্ট্য, যেমন প্লেব্যাক পজিশন, সম্পর্কে জিজ্ঞাসা করা।
  • মিডিয়া আইটেমের প্লেলিস্ট/কিউ পরিচালনা করা
  • প্লেব্যাকের বৈশিষ্ট্য, যেমন শাফলিং, রিপিটিং, গতি এবং ভলিউম নির্ধারণ করা।
  • স্ক্রিনে ভিডিও রেন্ডার করা

Media3 Player ইন্টারফেসের একটি বাস্তবায়নও প্রদান করে, যার নাম ExoPlayer

উপাদানগুলির মধ্যে একটি সাধারণ ইন্টারফেস

Media3-এর বেশ কিছু কম্পোনেন্ট প্লেয়ার ইন্টারফেসটি বাস্তবায়ন করে, উদাহরণস্বরূপ:

উপাদান বর্ণনা ও আচরণের নোট
ExoPlayer একটি মিডিয়া প্লেয়ার এপিআই, এবং Player ইন্টারফেসের ডিফল্ট বাস্তবায়ন।
MediaController প্লেব্যাক কমান্ড পাঠানোর জন্য একটি MediaSession সাথে যোগাযোগ করে। যদি আপনার Player এবং MediaSession , সেই Activity বা Fragment থেকে আলাদা কোনো Service এ থাকে যেখানে আপনার প্লেয়ারের UI থাকে, তাহলে আপনি আপনার MediaController PlayerView বা Player Composable-এর মতো UI কম্পোনেন্টের জন্য প্লেয়ার হিসেবে নির্ধারণ করতে পারেন। প্লেব্যাক এবং প্লেলিস্ট মেথড কলগুলো আপনার MediaSession মাধ্যমে আপনার Player পাঠানো হয়।
MediaBrowser MediaController এর প্রদত্ত কার্যকারিতার পাশাপাশি, এটি উপলব্ধ মিডিয়া কন্টেন্ট ব্রাউজ করার জন্য একটি MediaLibrarySession সাথে ইন্টারঅ্যাক্ট করে।
SimpleBasePlayer একটি Player ইমপ্লিমেন্টেশন যা ইমপ্লিমেন্ট করার জন্য মেথডের সংখ্যা ন্যূনতম পর্যায়ে কমিয়ে আনে। কাস্টম প্লেয়ার ব্যবহার করার সময় এটি সহায়ক, বিশেষ করে যখন আপনি সেটিকে একটি MediaSession সাথে সংযুক্ত করতে চান।
ForwardingSimpleBasePlayer SimpleBasePlayer একটি সাবক্লাস, যা অন্য একটি Player প্লেব্যাক অপারেশন ফরওয়ার্ড করার জন্য ডিজাইন করা হয়েছে এবং একই সাথে SimpleBasePlayer মতো সামঞ্জস্যপূর্ণ আচরণগত কাস্টমাইজেশনের সুযোগ দেয়। নির্দিষ্ট প্লেব্যাক অপারেশন দমন বা পরিবর্তন করতে এই ক্লাসটি ব্যবহার করুন।
RemoteCastPlayer একটি রিমোট কাস্ট রিসিভার অ্যাপে প্লেব্যাক নিয়ন্ত্রণের জন্য একটি Player বাস্তবায়ন।
CastPlayer স্থানীয় এবং দূরবর্তী উভয় কাস্ট প্লেব্যাক নিয়ন্ত্রণের জন্য একটি Player বাস্তবায়ন।

যদিও একটি MediaSession , Player ইন্টারফেসটি ইমপ্লিমেন্ট করে না, তবুও এটি তৈরি করার সময় একটি Player প্রয়োজন হয়। এর উদ্দেশ্য হলো অন্যান্য প্রসেস বা থ্রেড থেকে Player টিতে অ্যাক্সেস প্রদান করা।

মিডিয়া৩ প্লেব্যাক আর্কিটেকচার

আপনার যদি কোনো Player ব্যবহারের সুযোগ থাকে, তবে প্লেব্যাক কমান্ড দেওয়ার জন্য সরাসরি এর মেথডগুলো কল করা উচিত। একটি MediaSession ইমপ্লিমেন্ট করার মাধ্যমে আপনি আপনার প্লেব্যাকের প্রচার করতে পারেন এবং বাহ্যিক উৎসগুলোকে প্লেব্যাক নিয়ন্ত্রণের অনুমতি দিতে পারেন। এই বাহ্যিক উৎসগুলো একটি MediaController ইমপ্লিমেন্ট করে, যা একটি মিডিয়া সেশনে সংযোগ স্থাপন এবং প্লেব্যাক কমান্ডের অনুরোধ জানানোর সুবিধা প্রদান করে।

ব্যাকগ্রাউন্ডে মিডিয়া চালানোর সময়, আপনার মিডিয়া সেশন এবং প্লেয়ারকে একটি MediaSessionService বা MediaLibraryService মধ্যে রাখতে হবে, যা একটি ফোরগ্রাউন্ড সার্ভিস হিসেবে চলে। এমনটা করলে, আপনি আপনার অ্যাপের সেই অ্যাক্টিভিটি থেকে প্লেয়ারটিকে আলাদা রাখতে পারবেন, যেটিতে প্লেব্যাক নিয়ন্ত্রণের জন্য UI থাকে। এর জন্য আপনাকে একটি মিডিয়া কন্ট্রোলার ব্যবহার করতে হতে পারে।

একটি ডায়াগ্রাম যা দেখায় কিভাবে Media3 প্লেব্যাক কম্পোনেন্টগুলো একটি মিডিয়া অ্যাপ আর্কিটেকচারে খাপ খায়।
চিত্র ১ : মিডিয়া৩-এর স্থাপত্যে Player ইন্টারফেস একটি গুরুত্বপূর্ণ ভূমিকা পালন করে।

খেলোয়াড়ের অবস্থা

Player ইন্টারফেস বাস্তবায়নকারী একটি মিডিয়া প্লেয়ারের অবস্থা প্রধানত ৪ শ্রেণীর তথ্য নিয়ে গঠিত:

  1. প্লেব্যাক অবস্থা
  2. মিডিয়া আইটেমের প্লেলিস্ট
    • প্লেব্যাকের জন্য MediaItem ইনস্ট্যান্সগুলোর একটি অনুক্রম।
    • getCurrentTimeline() ব্যবহার করে পুনরুদ্ধার করুন
    • Player ইনস্ট্যান্সগুলো প্লেলিস্ট পরিচালনার মেথড, যেমন একটি MediaItem যোগ করা বা সরানো , এবং getCurrentMediaItem() এর মতো সুবিধাজনক মেথড প্রদান করতে পারে।
  3. প্লে/পজ বৈশিষ্ট্য, যেমন:
    • playWhenReady : ব্যবহারকারী মিডিয়াটি সম্ভব হলে প্লে করতে চান নাকি পজ করে রাখতে চান, তার একটি নির্দেশক।
    • প্লেব্যাক দমন করার কারণ : প্রযোজ্য ক্ষেত্রে, playWhenReady true হলেও কেন প্লেব্যাক দমন করা হচ্ছে তার একটি ইঙ্গিত।
    • isPlaying : প্লেয়ারটি বর্তমানে চলছে কিনা তার একটি নির্দেশক, যা কেবল তখনই true হবে যখন প্লেব্যাক স্টেট STATE_READY হবে, playWhenReady true হবে এবং প্লেব্যাক সাপ্রেসড থাকবে না।
  4. প্লেব্যাক পজিশন, যার মধ্যে অন্তর্ভুক্ত:

এছাড়াও, Player ইন্টারফেসের মাধ্যমে উপলব্ধ ট্র্যাক , মিডিয়া মেটাডেটা , প্লেব্যাকের গতি , ভলিউম এবং প্লেব্যাকের অন্যান্য সহায়ক বৈশিষ্ট্যগুলো অ্যাক্সেস করা যায়।

পরিবর্তনের জন্য শুনুন

একটি Player পরিবর্তন শোনার জন্য Player.Listener ব্যবহার করুন। কীভাবে একটি লিসেনার তৈরি ও ব্যবহার করতে হয়, সে সম্পর্কে বিস্তারিত জানতে ExoPlayer-এর প্লেয়ার ইভেন্ট সংক্রান্ত ডকুমেন্টেশন দেখুন।

উল্লেখ্য যে, লিসেনার ইন্টারফেসে সাধারণ প্লেব্যাকের অগ্রগতি ট্র্যাক করার জন্য কোনো কলব্যাক অন্তর্ভুক্ত নেই। প্লেব্যাকের অগ্রগতি ক্রমাগত নিরীক্ষণ করতে, যেমন একটি প্রোগ্রেস বার UI সেট আপ করার জন্য, আপনাকে উপযুক্ত বিরতিতে বর্তমান অবস্থানটি কোয়েরি করতে হবে।

কোটলিন

fun checkPlaybackPosition(delayMs: Long): Boolean =
  handler.postDelayed(
    {
      val currentPosition = player.currentPosition
      // Update UI based on currentPosition
      checkPlaybackPosition(delayMs)
    },
    delayMs,
  )

জাভা

boolean checkPlaybackPosition(long delayMs) {
  return handler.postDelayed(
      () -> {
        long currentPosition = player.getCurrentPosition();
        // Update UI based on currentPosition
        checkPlaybackPosition(delayMs);
      },
      delayMs);
}

প্লেব্যাক নিয়ন্ত্রণ করুন

Player ইন্টারফেসটি অবস্থা পরিবর্তন এবং প্লেব্যাক নিয়ন্ত্রণ করার বিভিন্ন উপায় প্রদান করে:

কাস্টম Player বাস্তবায়ন

একটি কাস্টম প্লেয়ার তৈরি করতে, আপনি Media3-এর অন্তর্ভুক্ত SimpleBasePlayer ক্লাসটি এক্সটেন্ড করতে পারেন। এই ক্লাসটি Player ইন্টারফেসের একটি বেস ইমপ্লিমেন্টেশন প্রদান করে, যার ফলে আপনার ইমপ্লিমেন্ট করার জন্য প্রয়োজনীয় মেথডের সংখ্যা ন্যূনতম পর্যায়ে নেমে আসে।

প্রথমে getState() মেথডটি ওভাররাইড করুন। এই মেথডটি কল করা হলে প্লেয়ারের বর্তমান স্টেট পূরণ করবে, যার মধ্যে অন্তর্ভুক্ত থাকবে:

  • উপলব্ধ কমান্ডের সেট
  • প্লেব্যাকের বৈশিষ্ট্যসমূহ, যেমন প্লেব্যাক অবস্থা STATE_READY হলে প্লেয়ারটি প্লে হওয়া শুরু করবে কিনা, বর্তমানে প্লে হওয়া মিডিয়া আইটেমের ইন্ডেক্স, এবং বর্তমান আইটেমের মধ্যে প্লেব্যাকের অবস্থান।

কোটলিন

class CustomPlayer(looper: Looper) : SimpleBasePlayer(looper) {
  override fun getState(): State {
    return State.Builder()
      .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle
      // Configure additional playback properties
      .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
      .setCurrentMediaItemIndex(0)
      .setContentPositionMs(0)
      .build()
  }
}

জাভা

private static final class CustomPlayer extends SimpleBasePlayer {
  public CustomPlayer(Looper looper) {
    super(looper);
  }

  @Override
  protected State getState() {
    return new State.Builder()
        .setAvailableCommands(Commands.EMPTY) // Set which playback commands the player can handle
        // Configure additional playback properties
        .setPlayWhenReady(true, PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST)
        .setCurrentMediaItemIndex(0)
        .setContentPositionMs(0)
        .build();
  }
}

SimpleBasePlayer নিশ্চিত করবে যে State স্টেট ভ্যালুগুলোর একটি বৈধ সমন্বয়ে তৈরি হয়েছে। এটি লিসেনারগুলোও পরিচালনা করবে এবং স্টেট পরিবর্তনের বিষয়ে লিসেনারদের অবহিত করবে। যদি আপনার ম্যানুয়ালি স্টেট আপডেট করার প্রয়োজন হয়, তাহলে invalidateState() কল করুন।

getState() মেথডটি ছাড়াও, আপনাকে শুধু সেই মেথডগুলোই ইমপ্লিমেন্ট করতে হবে যেগুলো আপনার প্লেয়ারের ঘোষিত কমান্ডগুলোর জন্য ব্যবহৃত হয়। আপনি যে কার্যকারিতাটি ইমপ্লিমেন্ট করতে চান, তার সাথে সঙ্গতিপূর্ণ ওভাররাইডযোগ্য হ্যান্ডলার মেথডটি খুঁজুন। উদাহরণস্বরূপ, COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM এবং COMMAND_SEEK_TO_NEXT_MEDIA_ITEM মতো অপারেশনগুলো সাপোর্ট করার জন্য handleSeek() মেথডটি ওভাররাইড করুন।

Player বাস্তবায়ন পরিবর্তন করুন

সম্পূর্ণ কাস্টম Player তৈরি করার পরিবর্তে, আপনি বিদ্যমান কোনো Player অবস্থা ও আচরণ পরিবর্তন করতে ForwardingSimpleBasePlayer ব্যবহার করতে পারেন। আরও বিস্তারিত জানতে কাস্টমাইজেশন পৃষ্ঠার নির্দেশিকা দেখুন।