Jetpack Media3 একটি Player ইন্টারফেস সংজ্ঞায়িত করে যা ভিডিও এবং অডিও ফাইল প্লেব্যাকের জন্য মৌলিক কার্যকারিতার রূপরেখা দেয়। Media3-তে ExoPlayer হল এই ইন্টারফেসের ডিফল্ট বাস্তবায়ন। আমরা ExoPlayer ব্যবহার করার পরামর্শ দিই, কারণ এটি বেশিরভাগ প্লেব্যাক ব্যবহারের ক্ষেত্রে বিস্তৃত বৈশিষ্ট্য সরবরাহ করে এবং আপনার যে কোনও অতিরিক্ত ব্যবহারের ক্ষেত্রে এটি কাস্টমাইজযোগ্য। ExoPlayer ডিভাইস এবং OS ফ্র্যাগমেন্টেশনকেও বিমূর্ত করে যাতে আপনার কোড সমগ্র Android ইকোসিস্টেম জুড়ে ধারাবাহিকভাবে কাজ করে। ExoPlayer-এ অন্তর্ভুক্ত রয়েছে:
- প্লেলিস্টের জন্য সমর্থন
- বিভিন্ন ধরণের প্রগতিশীল এবং অভিযোজিত স্ট্রিমিং ফর্ম্যাটের জন্য সমর্থন
- ক্লায়েন্ট-সাইড এবং সার্ভার-সাইড উভয় বিজ্ঞাপন সন্নিবেশের জন্য সমর্থন
- DRM-সুরক্ষিত প্লেব্যাকের জন্য সমর্থন
এই পৃষ্ঠাটি আপনাকে প্লেব্যাক অ্যাপ তৈরির কিছু গুরুত্বপূর্ণ ধাপ সম্পর্কে জানাবে এবং আরও বিস্তারিত জানার জন্য আপনি Media3 ExoPlayer- এর উপর আমাদের সম্পূর্ণ নির্দেশিকাগুলি দেখতে পারেন।
শুরু করা
শুরু করতে, Jetpack Media3 এর ExoPlayer, UI এবং Common মডিউলের উপর একটি নির্ভরতা যোগ করুন:
implementation "androidx.media3:media3-exoplayer:1.8.0" implementation "androidx.media3:media3-ui:1.8.0" implementation "androidx.media3:media3-common:1.8.0"
আপনার ব্যবহারের উপর নির্ভর করে, DASH ফর্ম্যাটে স্ট্রিম চালানোর জন্য আপনার Media3 থেকে অতিরিক্ত মডিউলের প্রয়োজন হতে পারে, যেমন exoplayer-dash ।
আপনার পছন্দের লাইব্রেরির সংস্করণটি 1.8.0 দিয়ে প্রতিস্থাপন করতে ভুলবেন না। সর্বশেষ সংস্করণটি দেখতে আপনি রিলিজ নোটগুলি দেখতে পারেন।
একটি মিডিয়া প্লেয়ার তৈরি করা হচ্ছে
Media3 এর মাধ্যমে, আপনি Player ইন্টারফেসের অন্তর্ভুক্ত বাস্তবায়ন, ExoPlayer ব্যবহার করতে পারেন, অথবা আপনি আপনার নিজস্ব কাস্টম বাস্তবায়ন তৈরি করতে পারেন।
একটি এক্সোপ্লেয়ার তৈরি করা হচ্ছে
ExoPlayer ইনস্ট্যান্স তৈরি করার সবচেয়ে সহজ উপায় হল:
কোটলিন
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 লেভেল 24 এবং তার উপরে onStart() লাইফসাইকেল পদ্ধতিতে প্লেয়ারটিকে প্রস্তুত করা অথবা API লেভেল 23 এবং তার নীচে onResume() লাইফসাইকেল পদ্ধতিতে। Service এ থাকা প্লেয়ারের জন্য, আপনি এটি onCreate() এ প্রস্তুত করতে পারেন। লাইফসাইকেল পদ্ধতিগুলি কীভাবে বাস্তবায়ন করতে হয় তার উদাহরণের জন্য Exoplayer codelab দেখুন।
প্লেয়ার নিয়ন্ত্রণ করুন
প্লেয়ার প্রস্তুত হওয়ার পরে, আপনি প্লেয়ারে কলিং পদ্ধতি ব্যবহার করে প্লেব্যাক নিয়ন্ত্রণ করতে পারেন যেমন:
- প্লেব্যাক শুরু এবং পজ করার জন্য
play()এবংpause()। -
seekTo()বর্তমান মিডিয়া আইটেমের মধ্যে একটি অবস্থানে যাওয়ার জন্য - প্লেলিস্টটি নেভিগেট করার জন্য
seekToNextMediaItem()এবংseekToPreviousMediaItem()করুন।
PlayerView বা PlayerControlView এর মতো UI উপাদানগুলি প্লেয়ারের সাথে আবদ্ধ হলে সেই অনুযায়ী আপডেট হবে।
প্লেয়ারটিকে ছেড়ে দিন
প্লেব্যাকের জন্য সীমিত সরবরাহের রিসোর্সের প্রয়োজন হতে পারে, যেমন ভিডিও ডিকোডার, তাই যখন প্লেয়ারটির আর প্রয়োজন থাকে না তখন রিসোর্স খালি করার জন্য আপনার প্লেয়ারে release() কল করা গুরুত্বপূর্ণ।
যদি আপনার প্লেয়ারটি একটি Activity অথবা Fragment এ থাকে, তাহলে API লেভেল 24 এবং তার উপরে onStop() লাইফসাইকেল পদ্ধতিতে প্লেয়ারটি ছেড়ে দিন অথবা API লেভেল 23 এবং তার নীচে onPause() পদ্ধতিতে প্লেয়ারটি ছেড়ে দিন। Service এ থাকা প্লেয়ারের জন্য, আপনি এটি onDestroy() এ ছেড়ে দিতে পারেন। লাইফসাইকেল পদ্ধতিগুলি কীভাবে বাস্তবায়ন করতে হয় তার উদাহরণের জন্য Exoplayer codelab দেখুন।
মিডিয়া সেশনের মাধ্যমে প্লেব্যাক পরিচালনা করা
অ্যান্ড্রয়েডে, মিডিয়া সেশনগুলি প্রক্রিয়া সীমানা পেরিয়ে একটি মিডিয়া প্লেয়ারের সাথে ইন্টারঅ্যাক্ট করার একটি মানসম্মত উপায় প্রদান করে। আপনার প্লেয়ারের সাথে একটি মিডিয়া সেশন সংযুক্ত করলে আপনি আপনার মিডিয়া প্লেব্যাকের বাহ্যিক বিজ্ঞাপন দিতে পারবেন এবং বাহ্যিক উৎস থেকে প্লেব্যাক কমান্ড গ্রহণ করতে পারবেন, উদাহরণস্বরূপ মোবাইল এবং বড় স্ক্রিন ডিভাইসে সিস্টেম মিডিয়া নিয়ন্ত্রণের সাথে একীভূত করা।
মিডিয়া সেশন ব্যবহার করতে, Media3 সেশন মডিউলে একটি নির্ভরতা যোগ করুন:
implementation "androidx.media3:media3-session:1.8.0"
একটি মিডিয়া সেশন তৈরি করুন
আপনি নিম্নলিখিতভাবে একটি প্লেয়ার চালু করার পরে একটি 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 Session ডেমো অ্যাপে এর একটি উদাহরণ দেখুন।
একবার সংযুক্ত হয়ে গেলে, একটি নিয়ামক সেশনে প্লেব্যাক কমান্ড পাঠাতে পারে। এরপর সেশনটি সেই কমান্ডগুলি প্লেয়ারের কাছে অর্পণ করে। 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 এর সাথে সংযোগ স্থাপন করা হচ্ছে
এখন যেহেতু আপনার মিডিয়া সেশনটি Activity বা Fragment থেকে আলাদা একটি Service রয়েছে যেখানে আপনার প্লেয়ার UI থাকে, আপনি একটি MediaController ব্যবহার করে তাদের একসাথে লিঙ্ক করতে পারেন। আপনার UI এর সাথে Activity বা Fragment onStart() পদ্ধতিতে, আপনার MediaSession এর জন্য একটি SessionToken তৈরি করুন, তারপর SessionToken ব্যবহার করে একটি MediaController তৈরি করুন। একটি 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 আর প্রয়োজন হয় না, যেমন Activity এর onStop() লাইফসাইকেল পদ্ধতি, তখন MediaController.releaseFuture() কল করে এটি ছেড়ে দিতে ভুলবেন না।
একটি বিজ্ঞপ্তি প্রকাশ করা হচ্ছে
সক্রিয় থাকাকালীন ফোরগ্রাউন্ড পরিষেবাগুলিকে একটি বিজ্ঞপ্তি প্রকাশ করতে হবে। একটি MediaSessionService স্বয়ংক্রিয়ভাবে আপনার জন্য MediaNotification আকারে একটি MediaStyle বিজ্ঞপ্তি তৈরি করবে। একটি কাস্টম বিজ্ঞপ্তি প্রদান করতে, 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 কন্টেন্ট ব্রাউজিং API যোগ করার জন্য MediaSession API প্রসারিত করে। MediaSession কলব্যাকের তুলনায়, MediaLibrarySession কলব্যাক নিম্নলিখিত পদ্ধতিগুলি যোগ করে:
-
onGetLibraryRoot()যখন কোনও ক্লায়েন্ট কোনও কন্টেন্ট ট্রির রুটMediaItemঅনুরোধ করে -
onGetChildren()যখন কোনও ক্লায়েন্ট কন্টেন্ট ট্রিতে থাকা কোনওMediaItemবাচ্চাদের অনুরোধ করে -
onGetSearchResult()যখন কোনও ক্লায়েন্ট কোনও নির্দিষ্ট প্রশ্নের জন্য কন্টেন্ট ট্রি থেকে অনুসন্ধান ফলাফলের অনুরোধ করে
প্রাসঙ্গিক কলব্যাক পদ্ধতিতে একটি LibraryParams অবজেক্ট অন্তর্ভুক্ত থাকবে যেখানে ক্লায়েন্ট অ্যাপের আগ্রহের ধরণের কন্টেন্ট ট্রি সম্পর্কে অতিরিক্ত সংকেত থাকবে।