Jetpack Media3 একটি Player ইন্টারফেসকে সংজ্ঞায়িত করে যা ভিডিও এবং অডিও ফাইলের প্লেব্যাকের জন্য প্রাথমিক কার্যকারিতাকে
আউটলাইন করে। Media3-তে এই ইন্টারফেসের ডিফল্ট ইমপ্লিমেন্টেশন
হল ExoPlayer। আমরা ExoPlayer ব্যবহার করার সাজেশন দিই, কারণ এটি
ফিচারের একটি বিস্তৃত সেট প্রদান করে যা বেশিরভাগ প্লেব্যাক ব্যবহারের ক্ষেত্রে কভার করে এবং
আপনার কাছে থাকা যেকোনও অতিরিক্ত ব্যবহারের ক্ষেত্রে কাস্টমাইজ করা যায়। ExoPlayer ডিভাইস এবং OS ফ্র্যাগমেন্টেশনকেও
অ্যাবস্ট্র্যাক্ট করে যাতে আপনার কোড সমগ্র Android ইকোসিস্টেম জুড়ে
একইভাবে কাজ করে। ExoPlayer-এ এগুলি অন্তর্ভুক্ত:
- প্লেলিস্ট সংক্রান্ত সহায়তা
- বিভিন্ন ধরনের প্রোগ্রেসিভ ও অ্যাডাপ্টিভ স্ট্রিমিং ফর্ম্যাট কাজ করে
- ক্লায়েন্ট-সাইড ও সার্ভার-সাইড বিজ্ঞাপন ইনসার্ট করার সুবিধা
- DRM-সুরক্ষিত প্লেব্যাক-এর জন্য সহায়তা
এই পৃষ্ঠায় প্লেব্যাক অ্যাপ তৈরি করার কিছু গুরুত্বপূর্ণ ধাপের ব্যাপারে আপনাকে গাইড করা হয়েছে, এবং আরও বিবরণের জন্য আপনি Media3 ExoPlayer-এ আমাদের সম্পূর্ণ গাইড দেখতে পারেন।
শুরু করা
শুরু করতে, Jetpack Media3-এর ExoPlayer, UI এবং কমন মডিউলে ডিপেন্ডেন্সি যোগ করুন:
Kotlin
implementation("androidx.media3:media3-exoplayer:1.11.1")
implementation("androidx.media3:media3-ui:1.11.1")
implementation("androidx.media3:media3-common:1.11.1")
গ্ৰুভি
implementation "androidx.media3:media3-exoplayer:1.11.1"
implementation "androidx.media3:media3-ui:1.11.1"
implementation "androidx.media3:media3-common:1.11.1"
আপনার ব্যবহারের উপর নির্ভর করে, Media3 থেকে অতিরিক্ত মডিউলেরও প্রয়োজন হতে পারে,
যেমন DASH ফর্ম্যাটে স্ট্রিম চালানোর জন্য exoplayer-dash।
লাইব্রেরির আপনার পছন্দের ভার্সন দিয়ে 1.11.1 পরিবর্তন করতে ভুলবেন না। লেটেস্ট ভার্সন দেখতে আপনি রিলিজ নোট দেখতে পারেন।
মিডিয়া প্লেয়ার তৈরি করা
Media3-এর সাহায্যে, আপনি Player
ইন্টারফেসের অন্তর্ভুক্ত ইমপ্লিমেন্টেশন ব্যবহার করতে পারেন, ExoPlayer, অথবা আপনি নিজের কাস্টম ইমপ্লিমেন্টেশন তৈরি করতে পারেন।
ExoPlayer তৈরি করা
ExoPlayer ইনস্ট্যান্স তৈরি করার সবচেয়ে সহজ উপায় হল:
Kotlin
val player = ExoPlayer.Builder(context).build()
জাভা
ExoPlayer player = new ExoPlayer.Builder(context).build();
আপনি Activity, Fragment বা Service-এর onCreate() লাইফসাইকেল পদ্ধতিতে আপনার মিডিয়া প্লেয়ার তৈরি করতে পারবেন।
Builder-এ কাস্টমাইজেশনের বিভিন্ন বিকল্প রয়েছে, যেগুলি আপনার পছন্দ হতে পারে,
যেমন:
- অডিও ফোকাস হ্যান্ডলিং কনফিগার করতে
setAudioAttributes() - অডিও আউটপুট ডিভাইস ডিসকানেক্ট হয়ে গেলে প্লেব্যাক আচরণ কনফিগার করতে
setHandleAudioBecomingNoisy() - ট্র্যাক বেছে নেওয়া কনফিগার করতে
setTrackSelector()
Media3 একটি PlayerView UI কম্পোনেন্ট প্রদান করে যা আপনি আপনার অ্যাপের
লেআউট ফাইলে অন্তর্ভুক্ত করতে পারেন। এই কম্পোনেন্ট প্লেব্যাক কন্ট্রোলের জন্য PlayerControlView, সাবটাইটেল দেখানোর জন্য SubtitleView এবং ভিডিও রেন্ডার করার জন্য Surface এনক্যাপসুলেট করে।
প্লেয়ার রেডি করা হচ্ছে
setMediaItem() এবং addMediaItem()-এর মতো পদ্ধতি ব্যবহার করে প্লেব্যাকের জন্য প্লেলিস্টে মিডিয়া আইটেম যোগ করুন। তারপর, মিডিয়া লোড করা শুরু করতে এবং প্রয়োজনীয় রিসোর্স পেতে prepare() কল করুন।
অ্যাপটি ফোরগ্রাউন্ডে না আসা পর্যন্ত আপনার এইসব ধাপ পারফর্ম করা উচিত নয়। আপনার প্লেয়ার
Activity বা Fragment-এ থাকলে, এর অর্থ হল API লেভেল ২৪ ও তার থেকে উন্নত ভার্সনে onStart() লাইফসাইকেল পদ্ধতিতে
অথবা API লেভেল ২৩ ও তার থেকে পুরনো ভার্সনে onResume() লাইফসাইকেল পদ্ধতিতে প্লেয়ার প্রস্তুত করা। Service-এ থাকা প্লেয়ারের জন্য,
আপনি onCreate()-এ এটি প্রস্তুত করতে পারবেন। লাইফসাইকেল পদ্ধতি কীভাবে প্রয়োগ করতে হয় তার উদাহরণ পেতে Exoplayer কোডল্যাব দেখুন।
প্লেয়ার কন্ট্রোল করা
প্লেয়ার প্রস্তুত হয়ে গেলে, প্লেয়ারে মেথড কল করে আপনি প্লেব্যাক কন্ট্রোল করতে পারবেন, যেমন:
- প্লেব্যাক শুরু ও পজ করতে
play()এবংpause() - বর্তমান মিডিয়া আইটেমের মধ্যে কোনও পজিশনে যেতে
seekTo() - প্লেলিস্টের মধ্যে নেভিগেট করতে
seekToNextMediaItem()এবংseekToPreviousMediaItem()
PlayerView বা PlayerControlView-এর মতো UI কম্পোনেন্ট প্লেয়ারের সাথে বাউন্ড করা থাকলে
সেই অনুযায়ী আপডেট হবে।
প্লেয়ারকে রিলিজ করুন
প্লেব্যাকের জন্য এমন রিসোর্স প্রয়োজন হতে পারে যা সীমিত পরিমাণে উপলভ্য, যেমন ভিডিও
ডিকোডার, তাই প্লেয়ারের আর প্রয়োজন না থাকলে রিসোর্স খালি করার জন্য
আপনার প্লেয়ারে release() কল করা গুরুত্বপূর্ণ।
আপনার প্লেয়ার Activity বা Fragment-এ থাকলে, API লেভেল ২৪ ও তার থেকে উন্নত ভার্সনে onStop() লাইফসাইকেল পদ্ধতিতে অথবা API লেভেল ২৩ ও তার থেকে পুরনো ভার্সনে onPause() পদ্ধতিতে প্লেয়ার রিলিজ করুন। Service-এ থাকা কোনও প্লেয়ারের জন্য, আপনি
onDestroy()-এ এটি রিলিজ করতে পারবেন। লাইফসাইকেল পদ্ধতি কীভাবে প্রয়োগ করতে হয় তার উদাহরণ পেতে Exoplayer কোডল্যাব দেখুন।
মিডিয়া সেশনের মাধ্যমে প্লেব্যাক ম্যানেজ করা
Android-এ, মিডিয়া সেশন প্রসেস বাউন্ডারি জুড়ে মিডিয়া প্লেয়ারের সাথে ইন্টার্যাক্ট করার জন্য একটি স্ট্যান্ডার্ডাইজড উপায় প্রদান করে। আপনার প্লেয়ারের সাথে মিডিয়া সেশন কানেক্ট করলে আপনি এক্সটার্নাল সোর্স থেকে মিডিয়া প্লেব্যাক বিজ্ঞাপন দেখাতে এবং প্লেব্যাক কমান্ড পেতে পারবেন, যেমন মোবাইল এবং বড় স্ক্রিনের ডিভাইসে সিস্টেম মিডিয়া কন্ট্রোল-এর সাথে ইন্টিগ্রেট করা।
মিডিয়া সেশন ব্যবহার করতে, Media3 সেশন মডিউলে ডিপেন্ডেন্সি যোগ করুন:
Kotlin
implementation("androidx.media3:media3-session:1.11.1")
গ্ৰুভি
implementation "androidx.media3:media3-session:1.11.1"
মিডিয়া সেশন তৈরি করুন
আপনি নিম্নলিখিত উপায়ে প্লেয়ার শুরু করার পরে MediaSession তৈরি করতে পারবেন:
Kotlin
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-এর স্ট্যাটাসের সাথে সিঙ্ক করে। এটি যেকোনও Player প্রয়োগের সাথে কাজ করে, যার মধ্যে
ExoPlayer, CastPlayer বা কাস্টম প্রয়োগ অন্তর্ভুক্ত।
অন্যান্য ক্লায়েন্টকে কন্ট্রোল করার অনুমতি দিন
ক্লায়েন্ট অ্যাপ আপনার মিডিয়া সেশনের প্লেব্যাক কন্ট্রোল করার জন্য মিডিয়া কন্ট্রোলার প্রয়োগ করতে পারে। এইসব অনুরোধ পেতে, আপনার MediaSession তৈরি করার সময় একটি কলব্যাক অবজেক্ট সেট করুন।
কোনও কন্ট্রোলার আপনার মিডিয়া সেশনে কানেক্ট করতে গেলে, onConnect()
মেথড কল করা হয়। আপনি প্রদত্ত ControllerInfo ব্যবহার করে সিদ্ধান্ত নিতে পারেন যে
অনুরোধটি গ্রহণ করবেন নাকি বাতিল করবেন। Media3
সেশন ডেমো অ্যাপ-এ এর একটি উদাহরণ দেখুন।
কানেক্ট করা হয়ে গেলে, কন্ট্রোলার সেশনে প্লেব্যাক কমান্ড পাঠাতে পারে। তারপর
সেশন সেইসব কমান্ড প্লেয়ারকে ডেলিগেট করে। Player ইন্টারফেসে সংজ্ঞায়িত প্লেব্যাক ও প্লেলিস্ট
কমান্ড সেশন দ্বারা অটোমেটিক
ম্যানেজ করা হয়।
অন্যান্য কলব্যাক পদ্ধতি আপনাকে, উদাহরণস্বরূপ, কাস্টম
প্লেব্যাক কমান্ড এবং প্লেলিস্ট পরিবর্তন করার অনুরোধগুলি পরিচালনা করতে দেয়। এইসব কলব্যাকে একইভাবে
একটি ControllerInfo অবজেক্ট অন্তর্ভুক্ত থাকে যাতে আপনি প্রতিটি অনুরোধের ভিত্তিতে
অ্যাক্সেস কন্ট্রোল নির্ধারণ করতে পারেন।
ব্যাকগ্রাউন্ডে মিডিয়া চালানো হচ্ছে
আপনার অ্যাপ ফোরগ্রাউন্ডে না থাকলেও মিডিয়া চালানো চালিয়ে যেতে, যেমন ব্যবহারকারী আপনার অ্যাপ খুলে না রাখলেও
মিউজিক, অডিওবুক বা পডকাস্ট চালাতে, আপনার Player এবং MediaSession ফোরগ্রাউন্ড
সার্ভিস-এ এনক্যাপসুলেট করা উচিত। Media3 এই উদ্দেশ্যে MediaSessionService ইন্টারফেস প্রদান করে।
MediaSessionService প্রয়োগ করা হচ্ছে
MediaSessionService এক্সটেন্ড করে এমন একটি ক্লাস তৈরি করুন এবং onCreate() লাইফসাইকেল পদ্ধতিতে আপনার
MediaSession ইনস্ট্যান্টিয়েট করুন।
Kotlin
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 রিটার্ন করুন।
Kotlin
// 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-এ আছে যা Activity বা
Fragment থেকে আলাদা যেখানে আপনার প্লেয়ার UI থাকে, আপনি MediaController ব্যবহার করে
সেগুলিকে একসাথে লিঙ্ক করতে পারবেন। আপনার UI-এর সাথে Activity বা Fragment-এর onStart() পদ্ধতিতে, আপনার MediaSession-এর জন্য একটি SessionToken তৈরি করুন, তারপর
SessionToken ব্যবহার করে একটি MediaController তৈরি করুন। MediaController তৈরি করা
অ্যাসিঙ্ক্রোনাসভাবে ঘটে।
Kotlin
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-এর আর প্রয়োজন না থাকলে, Activity-এর onStop() লাইফসাইকেল পদ্ধতিতে
MediaController.releaseFuture() কল করে
সেটি রিলিজ করতে ভুলবেন না।
বিজ্ঞপ্তি প্রকাশ করা
অ্যাক্টিভ থাকাকালীন বিজ্ঞপ্তি প্রকাশ করার জন্য ফোরগ্রাউন্ড সার্ভিস প্রয়োজন। MediaSessionService
অটোমেটিক আপনার জন্য MediaStyle বিজ্ঞপ্তি
MediaNotification হিসেবে তৈরি করবে। কাস্টম বিজ্ঞপ্তি প্রদান করতে, DefaultMediaNotificationProvider.Builder-এর সাথে MediaNotification.Provider তৈরি করুন
অথবা প্রোভাইডার ইন্টারফেসের কাস্টম
ইমপ্লিমেন্টেশন তৈরি করুন। 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, দুটির জন্যই ইনটেন্ট ফিল্টার অন্তর্ভুক্ত আছে। অতিরিক্ত
ইনটেন্ট ফিল্টার MediaBrowserCompat API ব্যবহার করে ক্লায়েন্ট অ্যাপকে
আপনার Service শনাক্ত করতে দেয়।
MediaLibrarySession-এর মাধ্যমে আপনি ট্রি স্ট্রাকচারে কন্টেন্ট লাইব্রেরি দেখাতে পারবেন,
যেখানে একটিমাত্র রুট MediaItem থাকবে। ট্রি-তে প্রতিটি MediaItem-এর যেকোনও সংখ্যক
চাইল্ড MediaItem নোড থাকতে পারে। আপনি ক্লায়েন্ট অ্যাপের অনুরোধের ভিত্তিতে অন্য কোনও রুট বা অন্য কোনও
ট্রি দেখাতে পারেন। যেমন, সাজেস্ট করা মিডিয়া আইটেমের তালিকা খুঁজছেন এমন কোনও ক্লায়েন্টকে
আপনি যে ট্রি দেখান তাতে শুধু রুট MediaItem এবং চাইল্ড MediaItem নোডের
একটি লেভেল থাকতে পারে, যেখানে অন্য কোনও ক্লায়েন্ট অ্যাপকে
আপনি যে ট্রি দেখান তাতে কন্টেন্টের আরও সম্পূর্ণ লাইব্রেরি
থাকতে পারে।
MediaLibrarySession তৈরি করা হচ্ছে
MediaLibrarySession, MediaSession API-কে আরও বাড়িয়ে দেয় যাতে কন্টেন্ট ব্রাউজিং
API যোগ করা যায়। MediaSession কলব্যাকের তুলনায়, MediaLibrarySession
কলব্যাক এই ধরনের পদ্ধতি যোগ করে:
onGetLibraryRoot()যখন কোনও ক্লায়েন্ট কন্টেন্ট ট্রির রুটMediaItem-এর জন্য অনুরোধ করেonGetChildren()যখন কোনও ক্লায়েন্ট কন্টেন্ট ট্রিতেMediaItem-এর চাইল্ডের জন্য অনুরোধ করেonGetSearchResult()যখন কোনও ক্লায়েন্ট প্রদত্ত কোয়েরির জন্য কন্টেন্ট ট্রি থেকে সার্চ ফলাফলের অনুরোধ করে
প্রাসঙ্গিক কলব্যাক পদ্ধতিতে একটি LibraryParams অবজেক্ট অন্তর্ভুক্ত থাকবে, যার সাথে
ক্লায়েন্ট অ্যাপ যে ধরনের কন্টেন্ট ট্রিতে আগ্রহী, সেই সম্পর্কে
অতিরিক্ত সিগন্যাল থাকবে।