Media3 ExoPlayer ব্যবহার করে একটি মৌলিক মিডিয়া প্লেয়ার অ্যাপ তৈরি করুন

Jetpack Media3 একটি Player ইন্টারফেস সংজ্ঞায়িত করে যা ভিডিও এবং অডিও ফাইলগুলির প্লেব্যাকের জন্য মৌলিক কার্যকারিতা রূপরেখা দেয়। ExoPlayer হল Media3 এ এই ইন্টারফেসের ডিফল্ট বাস্তবায়ন। আমরা ExoPlayer ব্যবহার করার পরামর্শ দিই, কারণ এটি বৈশিষ্ট্যগুলির একটি বিস্তৃত সেট প্রদান করে যা বেশিরভাগ প্লেব্যাক ব্যবহারের ক্ষেত্রে কভার করে এবং আপনার কাছে থাকা অতিরিক্ত ব্যবহার-কেসগুলি পরিচালনা করার জন্য কাস্টমাইজযোগ্য। ExoPlayer ডিভাইস এবং OS ফ্র্যাগমেন্টেশনকেও অ্যাবস্ট্রাক্ট করে যাতে আপনার কোড পুরো অ্যান্ড্রয়েড ইকোসিস্টেম জুড়ে ধারাবাহিকভাবে কাজ করে। ExoPlayer অন্তর্ভুক্ত:

এই পৃষ্ঠাটি আপনাকে একটি প্লেব্যাক অ্যাপ তৈরির কিছু মূল পদক্ষেপের মধ্য দিয়ে নিয়ে যায় এবং আরও বিশদ বিবরণের জন্য আপনি Media3 ExoPlayer- এ আমাদের সম্পূর্ণ নির্দেশিকাগুলিতে যেতে পারেন।

শুরু হচ্ছে

শুরু করতে, ExoPlayer, UI, এবং Jetpack Media3 এর সাধারণ মডিউলগুলির উপর নির্ভরতা যোগ করুন:

implementation "androidx.media3:media3-exoplayer:1.4.1"
implementation "androidx.media3:media3-ui:1.4.1"
implementation "androidx.media3:media3-common:1.4.1"

আপনার ব্যবহারের ক্ষেত্রে নির্ভর করে, DASH ফরম্যাটে স্ট্রীম চালানোর জন্য আপনার মিডিয়া3 থেকে অতিরিক্ত মডিউলের প্রয়োজন হতে পারে, যেমন exoplayer-dash

লাইব্রেরির আপনার পছন্দের সংস্করণের সাথে 1.4.1 প্রতিস্থাপন করা নিশ্চিত করুন। সর্বশেষ সংস্করণ দেখতে আপনি রিলিজ নোট উল্লেখ করতে পারেন.

একটি মিডিয়া প্লেয়ার তৈরি করা

Media3 এর সাথে, আপনি হয় Player ইন্টারফেসের অন্তর্ভুক্ত বাস্তবায়ন ব্যবহার করতে পারেন, ExoPlayer , অথবা আপনি আপনার নিজস্ব কাস্টম বাস্তবায়ন তৈরি করতে পারেন।

একটি ExoPlayer তৈরি করা

একটি ExoPlayer উদাহরণ তৈরি করার সবচেয়ে সহজ উপায় নিম্নরূপ:

কোটলিন

val player = ExoPlayer.Builder(context).build()

জাভা

ExoPlayer player = new ExoPlayer.Builder(context).build();

আপনি আপনার মিডিয়া প্লেয়ারটি Activity , Fragment বা Service onCreate() লাইফসাইকেল পদ্ধতিতে তৈরি করতে পারেন যেখানে এটি বাস করে।

Builder আপনার আগ্রহী হতে পারে এমন কাস্টমাইজেশন বিকল্পগুলির একটি পরিসীমা অন্তর্ভুক্ত করে, যেমন:

Media3 একটি PlayerView UI উপাদান প্রদান করে যা আপনি আপনার অ্যাপের লেআউট ফাইলে অন্তর্ভুক্ত করতে পারেন। এই উপাদানটি প্লেব্যাক নিয়ন্ত্রণের জন্য একটি PlayerControlView , সাবটাইটেল প্রদর্শনের জন্য SubtitleView এবং ভিডিও রেন্ডার করার জন্য Surface এনক্যাপসুলেট করে।

খেলোয়াড়কে প্রস্তুত করা হচ্ছে

setMediaItem() এবং addMediaItem() মত পদ্ধতি সহ প্লেব্যাকের জন্য একটি প্লেলিস্টে মিডিয়া আইটেম যোগ করুন। তারপর, মিডিয়া লোড করা শুরু করতে এবং প্রয়োজনীয় সংস্থানগুলি অর্জন করতে prepare() কল করুন।

অ্যাপটি অগ্রভাগে আসার আগে আপনার এই পদক্ষেপগুলি সম্পাদন করা উচিত নয়৷ আপনার প্লেয়ার যদি কোনো Activity বা Fragment থাকে, তাহলে এর মানে হল API লেভেল 24 এবং তার বেশির উপর onStart() লাইফসাইকেল পদ্ধতিতে অথবা API লেভেল 23 এবং তার নিচের onResume() লাইফসাইকেল পদ্ধতিতে প্লেয়ারকে প্রস্তুত করা। Service থাকা একজন খেলোয়াড়ের জন্য, আপনি এটি onCreate() এ প্রস্তুত করতে পারেন।

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

প্লেয়ার প্রস্তুত হওয়ার পরে, আপনি প্লেয়ারের উপর কল করার পদ্ধতি যেমন: প্লেব্যাক নিয়ন্ত্রণ করতে পারেন:

  • play() এবং pause() প্লেব্যাক শুরু এবং পজ করতে
  • seekTo() বর্তমান মিডিয়া আইটেমের মধ্যে একটি অবস্থান খোঁজার জন্য
  • প্লেলিস্টে নেভিগেট করতে seekToNextMediaItem() এবং seekToPreviousMediaItem()

PlayerView বা PlayerControlView মতো UI উপাদানগুলি প্লেয়ারের সাথে আবদ্ধ হলে সেই অনুযায়ী আপডেট হবে।

প্লেয়ারকে ছেড়ে দিন

প্লেব্যাকের জন্য সীমিত সরবরাহে থাকা সংস্থানগুলির প্রয়োজন হতে পারে, যেমন ভিডিও ডিকোডার, তাই যখন প্লেয়ারটির আর প্রয়োজন হয় না তখন সংস্থানগুলি খালি করতে আপনার প্লেয়ারে release() কল করা গুরুত্বপূর্ণ৷

আপনার প্লেয়ার যদি কোনো Activity বা Fragment থাকে, তাহলে প্লেয়ারটিকে API লেভেল 24 এবং উচ্চতর লাইফসাইকেল পদ্ধতিতে অথবা API লেভেল 23 এবং নীচের onPause() onStop() ছেড়ে দিন। Service থাকা একজন খেলোয়াড়ের জন্য, আপনি এটিকে onDestroy() এ প্রকাশ করতে পারেন।

একটি মিডিয়া সেশনের সাথে প্লেব্যাক পরিচালনা করা

অ্যান্ড্রয়েডে, মিডিয়া সেশনগুলি প্রক্রিয়ার সীমানা পেরিয়ে মিডিয়া প্লেয়ারের সাথে ইন্টারঅ্যাক্ট করার একটি প্রমিত উপায় প্রদান করে। আপনার প্লেয়ারের সাথে একটি মিডিয়া সেশন সংযুক্ত করা আপনাকে বাহ্যিকভাবে আপনার মিডিয়া প্লেব্যাকের বিজ্ঞাপন দিতে এবং বাহ্যিক উত্স থেকে প্লেব্যাক কমান্ডগুলি গ্রহণ করতে দেয়, উদাহরণস্বরূপ মোবাইল এবং বড় স্ক্রীন ডিভাইসগুলিতে সিস্টেম মিডিয়া নিয়ন্ত্রণগুলির সাথে একীভূত করা৷

মিডিয়া সেশন ব্যবহার করতে, Media3 সেশন মডিউলে নির্ভরতা যোগ করুন:

implementation "androidx.media3:media3-session:1.4.1"

একটি মিডিয়া সেশন তৈরি করুন

আপনি নিম্নলিখিত হিসাবে একটি প্লেয়ার শুরু করার পরে একটি MediaSession তৈরি করতে পারেন:

কোটলিন

val player = ExoPlayer.Builder(context).build()
val mediaSession = MediaSession.Builder(context, player).build()

জাভা

ExoPlayer player = new ExoPlayer.Builder(context).build();
MediaSession mediaSession = new MediaSession.Builder(context, player).build();

Media3 স্বয়ংক্রিয়ভাবে Player অবস্থাকে MediaSession এর অবস্থার সাথে সিঙ্ক করে। এটি ExoPlayer , CastPlayer , বা একটি কাস্টম বাস্তবায়ন সহ যেকোনো Player বাস্তবায়নের সাথে কাজ করে৷

অন্যান্য ক্লায়েন্টদের নিয়ন্ত্রণ মঞ্জুর করুন

ক্লায়েন্ট অ্যাপগুলি আপনার মিডিয়া সেশনের প্লেব্যাক নিয়ন্ত্রণ করতে একটি মিডিয়া কন্ট্রোলার প্রয়োগ করতে পারে। এই অনুরোধগুলি পেতে, আপনার MediaSession তৈরি করার সময় একটি কলব্যাক অবজেক্ট সেট করুন।

যখন একটি নিয়ামক আপনার মিডিয়া সেশনের সাথে সংযোগ করতে চলেছে, তখন onConnect() পদ্ধতিটি বলা হয়। অনুরোধ গ্রহণ বা প্রত্যাখ্যান করার সিদ্ধান্ত নিতে আপনি প্রদত্ত ControllerInfo ব্যবহার করতে পারেন। Media3 সেশন ডেমো অ্যাপে এর একটি উদাহরণ দেখুন।

একবার সংযুক্ত হলে, একটি নিয়ামক সেশনে প্লেব্যাক কমান্ড পাঠাতে পারে। সেশন তারপর সেই কমান্ডগুলি প্লেয়ারের কাছে অর্পণ করে। Player ইন্টারফেসে সংজ্ঞায়িত প্লেব্যাক এবং প্লেলিস্ট কমান্ডগুলি সেশন দ্বারা স্বয়ংক্রিয়ভাবে পরিচালনা করা হয়।

অন্যান্য কলব্যাক পদ্ধতি আপনাকে পরিচালনা করতে দেয়, উদাহরণস্বরূপ, কাস্টম প্লেব্যাক কমান্ডের অনুরোধ এবং প্লেলিস্ট পরিবর্তন করা । এই কলব্যাকগুলিতে একইভাবে একটি ControllerInfo অবজেক্ট অন্তর্ভুক্ত থাকে যাতে আপনি অনুরোধ-দ্বারা-অনুরোধের ভিত্তিতে অ্যাক্সেস নিয়ন্ত্রণ নির্ধারণ করতে পারেন।

ব্যাকগ্রাউন্ডে মিডিয়া প্লে হচ্ছে

আপনার অ্যাপ ফোরগ্রাউন্ডে না থাকলে মিডিয়া চালানো চালিয়ে যেতে, উদাহরণস্বরূপ, ব্যবহারকারীর কাছে আপনার অ্যাপ খোলা না থাকলেও মিউজিক, অডিওবুক বা পডকাস্ট চালানোর জন্য, আপনার Player এবং MediaSession একটি ফোরগ্রাউন্ড পরিষেবাতে এনক্যাপসুলেট করা উচিত। Media3 এই উদ্দেশ্যে MediaSessionService ইন্টারফেস প্রদান করে।

একটি MediaSessionService বাস্তবায়ন করা

একটি ক্লাস তৈরি করুন যা MediaSessionService প্রসারিত করে এবং onCreate() লাইফসাইকেল পদ্ধতিতে আপনার MediaSession ইনস্ট্যান্টিয়েট করে।

কোটলিন

class PlaybackService : MediaSessionService() {
    private var mediaSession: MediaSession? = null

    // Create your Player and MediaSession in the onCreate lifecycle event
    override fun onCreate() {
        super.onCreate()
        val player = ExoPlayer.Builder(this).build()
        mediaSession = MediaSession.Builder(this, player).build()
    }

    // Remember to release the player and media session in onDestroy
    override fun onDestroy() {
        mediaSession?.run {
            player.release()
            release()
            mediaSession = null
        }
        super.onDestroy()
    }
}

জাভা

public class PlaybackService extends MediaSessionService {
    private MediaSession mediaSession = null;

    @Override
    public void onCreate() {
        super.onCreate();
        ExoPlayer player = new ExoPlayer.Builder(this).build();
        mediaSession = new MediaSession.Builder(this, player).build();
    }

    @Override
    public void onDestroy() {
        mediaSession.getPlayer().release();
        mediaSession.release();
        mediaSession = null;
        super.onDestroy();
    }
}

আপনার ম্যানিফেস্টে, একটি MediaSessionService অভিপ্রায় ফিল্টার সহ আপনার Service ক্লাস এবং একটি ফোরগ্রাউন্ড পরিষেবা চালানোর জন্য FOREGROUND_SERVICE অনুমতির অনুরোধ করুন:

<service
    android:name=".PlaybackService"
    android:foregroundServiceType="mediaPlayback"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaSessionService"/>
    </intent-filter>
</service>

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

অবশেষে, আপনার তৈরি করা ক্লাসে, আপনার মিডিয়া সেশনে ক্লায়েন্ট অ্যাক্সেস নিয়ন্ত্রণ করতে onGetSession() পদ্ধতিটি ওভাররাইড করুন। সংযোগের অনুরোধ গ্রহণ করতে একটি MediaSession ফেরত দিন, অথবা অনুরোধ প্রত্যাখ্যান করতে null ফেরত দিন।

কোটলিন

// This example always accepts the connection request
override fun onGetSession(
    controllerInfo: MediaSession.ControllerInfo
): MediaSession? = mediaSession

জাভা

@Override
public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) {
  // This example always accepts the connection request
  return mediaSession;
}

আপনার UI এর সাথে সংযোগ করা হচ্ছে

এখন যেহেতু আপনার মিডিয়া সেশন একটি Service রয়েছে যেখানে আপনার প্লেয়ার UI থাকে Activity বা Fragment থেকে আলাদা, আপনি তাদের একসাথে লিঙ্ক করতে একটি MediaController ব্যবহার করতে পারেন। আপনার UI এর সাথে Activity বা Fragment onStart() পদ্ধতিতে, আপনার MediaSession জন্য একটি SessionToken তৈরি করুন, তারপর একটি MediaController তৈরি করতে SessionToken ব্যবহার করুন। একটি MediaController তৈরি করা অ্যাসিঙ্ক্রোনাসভাবে ঘটে।

কোটলিন

override fun onStart() {
  val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java))
  val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync()
  controllerFuture.addListener(
    {
        // Call controllerFuture.get() to retrieve the MediaController.
        // MediaController implements the Player interface, so it can be
        // attached to the PlayerView UI component.
        playerView.setPlayer(controllerFuture.get())
      },
    MoreExecutors.directExecutor()
  )
}

জাভা

@Override
public void onStart() {
  SessionToken sessionToken =
    new SessionToken(this, new ComponentName(this, PlaybackService.class));
  ListenableFuture<MediaController> controllerFuture =
    new MediaController.Builder(this, sessionToken).buildAsync();
  controllerFuture.addListener(() -> {
    // Call controllerFuture.get() to retrieve the MediaController.
    // MediaController implements the Player interface, so it can be
    // attached to the PlayerView UI component.
    playerView.setPlayer(controllerFuture.get());
  }, MoreExecutors.directExecutor())
}

MediaController Player ইন্টারফেস প্রয়োগ করে, তাই আপনি প্লেব্যাক নিয়ন্ত্রণ করতে play() এবং pause() এর মতো একই পদ্ধতি ব্যবহার করতে পারেন। অন্যান্য উপাদানের মতো, MediaController রিলিজ করার কথা মনে রাখুন যখন এটির আর প্রয়োজন হয় না, যেমন onStop() একটি Activity লাইফসাইকেল পদ্ধতি, MediaController.releaseFuture() কল করে।

একটি বিজ্ঞপ্তি প্রকাশ করা হচ্ছে

ফোরগ্রাউন্ড পরিষেবাগুলি সক্রিয় থাকাকালীন একটি বিজ্ঞপ্তি প্রকাশ করতে হবে৷ একটি MediaSessionService স্বয়ংক্রিয়ভাবে একটি MediaNotification আকারে আপনার জন্য একটি MediaStyle বিজ্ঞপ্তি তৈরি করবে। একটি কাস্টম বিজ্ঞপ্তি প্রদান করতে, একটি MediaNotification.Provider তৈরি করুন DefaultMediaNotificationProvider.Builder সহ বা প্রদানকারী ইন্টারফেসের একটি কাস্টম বাস্তবায়ন তৈরি করে৷ setMediaNotificationProvider এর মাধ্যমে আপনার MediaSession এ আপনার প্রদানকারীকে যোগ করুন।

আপনার বিষয়বস্তু লাইব্রেরি বিজ্ঞাপন

একটি MediaLibraryService একটি MediaSessionService তৈরি করে ক্লায়েন্ট অ্যাপগুলিকে আপনার অ্যাপ দ্বারা প্রদত্ত মিডিয়া সামগ্রী ব্রাউজ করার অনুমতি দিয়ে। ক্লায়েন্ট অ্যাপগুলি আপনার MediaLibraryService এর সাথে ইন্টারঅ্যাক্ট করতে একটি MediaBrowser প্রয়োগ করে।

একটি MediaLibraryService বাস্তবায়ন করা একটি MediaSessionService বাস্তবায়নের অনুরূপ, শুধুমাত্র onGetSession() এ আপনাকে একটি MediaSession এর পরিবর্তে একটি MediaLibrarySession ফেরত দিতে হবে। একটি MediaSession.Callback এর তুলনায়, MediaLibrarySession.Callback অতিরিক্ত পদ্ধতি রয়েছে যা একটি ব্রাউজার ক্লায়েন্টকে আপনার লাইব্রেরি পরিষেবা দ্বারা অফার করা সামগ্রী নেভিগেট করার অনুমতি দেয়৷

MediaSessionService এর মতো, আপনার ম্যানিফেস্টে MediaLibraryService ঘোষণা করুন এবং একটি ফোরগ্রাউন্ড পরিষেবা চালানোর জন্য FOREGROUND_SERVICE অনুমতির অনুরোধ করুন:

<service
    android:name=".PlaybackService"
    android:foregroundServiceType="mediaPlayback"
    android:exported="true">
    <intent-filter>
        <action android:name="androidx.media3.session.MediaLibraryService"/>
        <action android:name="android.media.browse.MediaBrowserService"/>
    </intent-filter>
</service>

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

উপরের উদাহরণে MediaLibraryService এবং পশ্চাদগামী সামঞ্জস্যের জন্য, উত্তরাধিকার MediaBrowserService উভয়ের জন্য একটি অভিপ্রায় ফিল্টার অন্তর্ভুক্ত রয়েছে। অতিরিক্ত অভিপ্রায় ফিল্টার আপনার Service চিনতে MediaBrowserCompat API ব্যবহার করে ক্লায়েন্ট অ্যাপগুলিকে সক্ষম করে৷

একটি MediaLibrarySession আপনাকে আপনার বিষয়বস্তু লাইব্রেরিটিকে একটি গাছের কাঠামোতে পরিবেশন করতে দেয়, একটি একক রুট MediaItem সহ। গাছের প্রতিটি MediaItem এ যেকোনো সংখ্যক শিশু MediaItem নোড থাকতে পারে। ক্লায়েন্ট অ্যাপের অনুরোধের ভিত্তিতে আপনি একটি ভিন্ন রুট বা একটি ভিন্ন গাছ পরিবেশন করতে পারেন। উদাহরণস্বরূপ, প্রস্তাবিত মিডিয়া আইটেমগুলির একটি তালিকা খুঁজছেন এমন একটি ক্লায়েন্টের কাছে আপনি যে গাছটি ফেরত পাঠান তাতে শুধুমাত্র রুট MediaItem এবং একটি একক স্তরের শিশু MediaItem নোড থাকতে পারে, যেখানে আপনি একটি ভিন্ন ক্লায়েন্ট অ্যাপে যে গাছটি ফেরত পাঠান সেটি আরও সম্পূর্ণ লাইব্রেরির প্রতিনিধিত্ব করতে পারে বিষয়বস্তু

একটি MediaLibrarySession তৈরি করা

একটি MediaLibrarySession কন্টেন্ট ব্রাউজিং API যোগ করতে MediaSession API-কে প্রসারিত করে। MediaSession কলব্যাকের তুলনায়, MediaLibrarySession কলব্যাক পদ্ধতি যোগ করে যেমন:

  • onGetLibraryRoot() যখন কোনো ক্লায়েন্ট কোনো কন্টেন্ট ট্রির রুট MediaItem অনুরোধ করে
  • onGetChildren() যখন কোনো ক্লায়েন্ট কন্টেন্ট ট্রিতে একটি MediaItem এর বাচ্চাদের অনুরোধ করে
  • onGetSearchResult() যখন একটি ক্লায়েন্ট একটি প্রদত্ত প্রশ্নের জন্য বিষয়বস্তু গাছ থেকে অনুসন্ধান ফলাফলের অনুরোধ করে

প্রাসঙ্গিক কলব্যাক পদ্ধতিতে একটি LibraryParams অবজেক্ট অন্তর্ভুক্ত থাকবে যাতে একটি ক্লায়েন্ট অ্যাপ আগ্রহী এমন বিষয়বস্তু গাছের ধরন সম্পর্কে অতিরিক্ত সংকেত দেয়।