১. ভূমিকা
সর্বশেষ হালনাগাদ: ২০২০-০৯-০৯
ভিডিও প্লেব্যাকের সময় মিডিয়া সেশন যোগ করার সুবিধাগুলো কী কী?
মিডিয়া সেশন হলো অ্যান্ড্রয়েড প্ল্যাটফর্ম এবং মিডিয়া অ্যাপগুলোর মধ্যে একটি অবিচ্ছেদ্য সংযোগ। এটি শুধু অ্যান্ড্রয়েডকে মিডিয়া চলার খবরই দেয় না—যাতে অ্যান্ড্রয়েড মিডিয়া সংক্রান্ত কার্যকলাপগুলো সঠিক সেশনে পাঠাতে পারে—বরং প্ল্যাটফর্মকে এও জানায় যে কী চলছে এবং কীভাবে তা নিয়ন্ত্রণ করা যাবে।
আপনার অ্যাপের মাধ্যমে একটি মিডিয়া সেশন প্রকাশ করার বিভিন্ন সুবিধা রয়েছে যা ব্যবহারকারীরা উপভোগ করবেন। এখানে কয়েকটি চমৎকার উদাহরণ দেওয়া হলো।
গুগল অ্যাসিস্ট্যান্ট
ব্যবহারকারীরা 'Pause,' 'Resume,' এবং 'Next'-এর মতো ভয়েস কমান্ডের মাধ্যমে আপনার অ্যাপে থাকা মিডিয়ার সাথে সহজেই ইন্টারঅ্যাক্ট করতে পারেন। বর্তমানে কী চলছে, সে সম্পর্কে তথ্য পেতে আপনার মিডিয়ার মেটাডেটাও ব্যবহার করা যেতে পারে।
অ্যান্ড্রয়েড টিভি
বড় পর্দায় দেখার অভিজ্ঞতার ক্ষেত্রে, HDMI-CEC সমর্থনকারী টিভি ব্যবহারকারীরা তাদের অ্যান্ড্রয়েড টিভি অ্যাপের মাধ্যমে প্রচলিত রিমোট কন্ট্রোল ব্যবহার করতে পারেন। প্লে/পজ, স্টপ, নেক্সট এবং প্রিভিয়াস বাটনের মাধ্যমে দেওয়া কমান্ডগুলো আপনার অ্যাপে পাঠানো হয়।
অন-স্ক্রিন মিডিয়া নিয়ন্ত্রণ
অ্যান্ড্রয়েড ৪.০ (এপিআই লেভেল ১৪) থেকে শুরু করে, সিস্টেম একটি মিডিয়া সেশনের প্লেব্যাক অবস্থা এবং মেটাডেটা অ্যাক্সেস করতে পারে। এই কার্যকারিতা লক স্ক্রিনে মিডিয়া কন্ট্রোল এবং আর্টওয়ার্ক প্রদর্শন করতে সক্ষম করে। অ্যান্ড্রয়েডের সংস্করণের উপর নির্ভর করে এই আচরণ ভিন্ন হতে পারে।
পটভূমি মাধ্যম
এই পরিস্থিতিগুলোর যেকোনোটিতেই মিডিয়া নিয়ন্ত্রণ করা সম্ভব, এমনকি মিডিয়া চালনাকারী অ্যাপটি ব্যাকগ্রাউন্ডে চালু থাকলেও।
অ্যাম্বিয়েন্ট কম্পিউটিং
আপনার মিডিয়াতে কী চলছে এবং কীভাবে তা নিয়ন্ত্রণ করা যায়, সেই সম্পর্কিত ডেটা প্রকাশ করলে তা বিভিন্ন ডিভাইসের মধ্যে সংযোগ স্থাপন করতে পারে, যার ফলে ব্যবহারকারীরা তাদের পছন্দের নানা উপায়ে সেটির সাথে মিথস্ক্রিয়া করতে পারে।
আপনি যা তৈরি করবেন
এই কোডল্যাবে, আপনি মিডিয়া সেশন সাপোর্ট যোগ করার জন্য বিদ্যমান এক্সোপ্লেয়ার স্যাম্পলটিকে সম্প্রসারিত করবেন। আপনার অ্যাপটি যা করবে:
- মিডিয়া সেশনের সক্রিয় অবস্থা সঠিকভাবে প্রতিফলিত করুন।
- এক্সোপ্লেয়ারে মিডিয়া নিয়ন্ত্রণগুলি প্রেরণ করুন
- কিউতে থাকা আইটেমগুলোর মেটাডেটা মিডিয়া সেশনে প্রেরণ করুন।
আপনি যা শিখবেন
- কেন মিডিয়া সেশন ব্যবহারকারীদের আরও সমৃদ্ধ অভিজ্ঞতা প্রদান করে
- কীভাবে একটি মিডিয়া সেশন তৈরি করবেন এবং এর অবস্থা পরিচালনা করবেন
- ExoPlayer-এ একটি মিডিয়া সেশন কীভাবে সংযুক্ত করবেন
- মিডিয়া সেশনে প্লেব্যাক কিউতে থাকা আইটেমগুলির মেটাডেটা কীভাবে অন্তর্ভুক্ত করবেন
- অতিরিক্ত (কাস্টম) অ্যাকশন কীভাবে যোগ করবেন
এই কোডল্যাবটি MediaSession SDK-এর উপর আলোকপাত করে। ExoPlayer ইমপ্লিমেন্টেশনের বিবরণ সহ অপ্রাসঙ্গিক ধারণা এবং কোড ব্লকগুলি এখানে আলোচনা করা হয়নি, তবে আপনার কেবল কপি-পেস্ট করার জন্য সেগুলি সরবরাহ করা হয়েছে।
আপনার যা যা লাগবে
- অ্যান্ড্রয়েড স্টুডিওর একটি সাম্প্রতিক সংস্করণ (৩.৫ বা তার পরবর্তী)
- অ্যান্ড্রয়েড অ্যাপ্লিকেশন তৈরির প্রাথমিক জ্ঞান
২. প্রস্তুতি গ্রহণ
আমাদের সূচনা বিন্দু কী?
আমাদের শুরুর জায়গা হলো ExoPlayer-এর মূল ডেমোটি। এই ডেমোটিতে অন-স্ক্রিন প্লেব্যাক কন্ট্রোলসহ ভিডিও রয়েছে, কিন্তু এতে ডিফল্টভাবে মিডিয়া সেশন ব্যবহার করা হয় না। আমাদের কাজ শুরু করে সেগুলো যুক্ত করার জন্য এটি একটি দারুণ সুযোগ!
ExoPlayer নমুনাটি সংগ্রহ করুন
ভালোভাবে শুরু করার জন্য, চলুন ExoPlayer স্যাম্পলটি দিয়ে শুরু করা যাক। নিচের কোডটি চালিয়ে GitHub রিপোজিটরিটি ক্লোন করুন।
git clone https://github.com/google/ExoPlayer.git
ডেমোটি খুলুন
অ্যান্ড্রয়েড স্টুডিওতে, demos/main অধীনে থাকা মূল ডেমো প্রজেক্টটি খুলুন।
অ্যান্ড্রয়েড স্টুডিও আপনাকে এসডিকে পাথ সেট করতে বলবে। যদি আপনি কোনো সমস্যার সম্মুখীন হন, তবে আইডিই এবং এসডিকে টুলস আপডেট করার জন্য দেওয়া সুপারিশগুলো অনুসরণ করতে পারেন।

আপনাকে যদি গ্রেডলের সর্বশেষ সংস্করণ ব্যবহার করতে বলা হয়, তবে তা আপডেট করে নিন।
অ্যাপটি কীভাবে ডিজাইন করা হয়েছে সে সম্পর্কে একটি প্রাথমিক ধারণা পেতে একটু সময় নিন। লক্ষ্য করুন, এখানে দুটি অ্যাক্টিভিটি রয়েছে: SampleChooserActivity এবং PlayerActivity। আমরা এই কোডল্যাবের বাকি সময়টা PlayerActivity-তে কাটাব, যেখানে মিডিয়াটি আসলে প্লে হয়, তাই এই ক্লাসটি খুলুন এবং পরবর্তী বিভাগে চলে যান।
৩. একটি মিডিয়া সেশন তৈরি করুন এবং এর অবস্থা পরিচালনা করুন।
মিডিয়া সেশন তৈরি করুন
PlayerActivity.java খুলুন। এই ক্লাসটি ExoPlayer তৈরি করে এবং এর বিভিন্ন ফাংশন, যেমন স্ক্রিনে ভিডিও রেন্ডার করা, পরিচালনা করে। এই অ্যাক্টিভিটিতে আমরা ExoPlayer-কে একটি মিডিয়া সেশনের সাথে সংযুক্ত করব।
ক্লাসের শুরুতে নিম্নলিখিত দুটি ফিল্ড ঘোষণা করুন। আমরা এই অংশ জুড়ে এই ফিল্ডগুলো ব্যবহার করব।
private MediaSessionCompat mediaSession;
private MediaSessionConnector mediaSessionConnector;
আপনাকে 'Module: demo'-এর জন্য মডিউল-স্তরের build.gradle এ 'extension-mediasession' প্রোজেক্ট ডিপেন্ডেন্সিটি যোগ করতে হবে:
implementation project(path: ':extension-mediasession')
উল্লেখ্য যে, MediaSessionConnector রিজলভ করার ত্রুটির উপর মাউস রাখলে Android Studio আপনাকে এই ডিপেন্ডেন্সিটি স্বয়ংক্রিয়ভাবে যোগ করতে সাহায্য করতে পারে:

অবশেষে, নিম্নলিখিতটি যোগ করে ক্লাস ইম্পোর্টগুলো সমাধান করুন:
import android.support.v4.media.session.MediaSessionCompat;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
অ্যাক্টিভিটিটি তৈরি করার সময় আমরা একটি মিডিয়া সেশন এবং একটি মিডিয়া সেশন কানেক্টর তৈরি করতে চাইব, যা মিডিয়া সেশন এবং ExoPlayer-এর মধ্যে মধ্যস্থতাকারী হিসেবে কাজ করবে।
এটি যুক্ত করার আদর্শ জায়গা হলো যেখানে ExoPlayer তৈরি করা হয়। আমাদের ডেমো অ্যাপে, আমরা initializePlayer() এর শেষে আমাদের কোড যুক্ত করতে পারি। প্লেয়ারটি ইনস্ট্যানশিয়েট হওয়ার পরে এই লজিকটি যোগ করতে ভুলবেন না!
private void initializePlayer() {
if (player == null) {
...
player = ...
...
mediaSession = new MediaSessionCompat(this, "sample");
mediaSessionConnector = new MediaSessionConnector(mediaSession);
mediaSessionConnector.setPlayer(player);
}
...
}
মিডিয়া সেশন প্রকাশ করুন
যখন মিডিয়া সেশনের আর প্রয়োজন হবে না, তখন তা রিলিজ করুন। releasePlayer() ফাংশনে ExoPlayer রিলিজ করার সময়, আমরা নিম্নলিখিত কোডটিও অন্তর্ভুক্ত করতে পারি:
private void releasePlayer() {
if (mediaSession != null) {
mediaSession.release();
}
...
}
মিডিয়া সেশনের অবস্থা পরিচালনা করুন
এখন যেহেতু আমরা মিডিয়া সেশনটি ইনস্ট্যানশিয়েট করেছি, আমাদের নিশ্চিত করতে হবে যে ব্যবহারকারী যখন অ্যাক্টিভিটিটির সাথে ইন্টারঅ্যাক্ট করবে, তখন এর স্টেট যেন সঠিকভাবে প্রতিফলিত হয়।
যখন ব্যবহারকারী অ্যাক্টিভিটিটি শুরু করবেন, তখন মিডিয়া সেশনটি সক্রিয় হওয়া উচিত:
@Override
public void onStart() {
...
if (mediaSession != null) {
mediaSession.setActive(true);
}
}
যেহেতু আমাদের অ্যাপ্লিকেশনটি ব্যাকগ্রাউন্ডে মিডিয়া প্লে করে না, তাই ব্যবহারকারী অ্যাক্টিভিটি থেকে বেরিয়ে যাওয়ার সাথে সাথে মিডিয়া সেশনটি যেন নিষ্ক্রিয় হয়ে যায়, তা নিশ্চিত করা অপরিহার্য:
@Override
public void onStop() {
super.onStop();
if (mediaSession != null) {
mediaSession.setActive(false);
}
...
}
চলুন ডেমোটি চালানো যাক।
- একটি অ্যান্ড্রয়েড ডিভাইস সংযুক্ত করুন অথবা একটি এমুলেটর চালু করুন।
- অ্যান্ড্রয়েড স্টুডিও টুলবার থেকে চালানোর জন্য 'demo' নির্বাচন করা আছে কিনা, তা নিশ্চিত করুন।

- ক্লিক করুন
অ্যান্ড্রয়েড স্টুডিও টুলবার থেকে। - আপনার ডিভাইসে অ্যাপটি চালু হয়ে গেলে, চালানোর জন্য একটি ভিডিও স্ট্রিম নির্বাচন করুন।
- প্লেব্যাক শুরু হয়ে গেলে, মিডিয়া সেশন নিয়ন্ত্রণ করতে নিম্নলিখিত
adbকমান্ডগুলো ব্যবহার করে দেখুন:
adb shell media dispatch pause
adb shell media dispatch play
adb shell media dispatch play-pause
adb shell media dispatch fast-forward
adb shell media dispatch rewind
- অ্যান্ড্রয়েড আপনার মিডিয়া সেশনকে কীভাবে দেখে, তাও খতিয়ে দেখুন। বিশেষ করে, অ্যাকশন ফিল্ডটি দেখে আপনি যাচাই করতে পারেন কোন কোন অ্যাকশন সমর্থিত। এখানে আপনি যে সংখ্যাটি দেখছেন, তা হলো PlaybackState অবজেক্টে ঘোষিত অ্যাকশন আইডিগুলোর একটি সমন্বয়। মিডিয়া সেশনটি দেখতে রান করুন:
adb shell dumpsys media_session - আপনি যদি মাইক্রোফোনসহ কোনো ফিজিক্যাল ডিভাইস ব্যবহার করেন, তাহলে গুগল অ্যাসিস্ট্যান্ট চালু করে ভয়েস কমান্ড দেওয়ার চেষ্টা করুন, যেমন: "পজ করুন।" "রিজিউম করুন।" "১ মিনিট ফাস্ট-ফরোয়ার্ড করুন।"
অ্যান্ড্রয়েড টিভিতে চলমান এক্সোপ্লেয়ারের নমুনা।
৪. প্লেব্যাক কিউতে থাকা আইটেমগুলোর মেটাডেটা অন্তর্ভুক্ত করা
আমরা এখন আমাদের মিডিয়া সেশনের সমর্থিত বৈশিষ্ট্যগুলি প্রসারিত করতে পারি, যেখানে আমরা আগে initializePlayer() -এ আমাদের MediaSessionConnector তৈরি করেছিলাম।
একটি TimelineQueueNavigator যোগ করা
এক্সোপ্লেয়ার মিডিয়ার কাঠামোকে একটি টাইমলাইন হিসেবে উপস্থাপন করে। এটি কীভাবে কাজ করে সে সম্পর্কে বিস্তারিত জানতে, এক্সোপ্লেয়ারের টাইমলাইন অবজেক্ট সম্পর্কে একটু পড়ুন। এই কাঠামো ব্যবহার করে, কন্টেন্ট পরিবর্তিত হলে আমরা জানতে পারি এবং অনুরোধ করা হলে বর্তমানে যা চলছে তার মেটাডেটা প্রকাশ করতে পারি।
এটি সম্পন্ন করার জন্য, আমরা একটি TimelineQueueNavigator সংজ্ঞায়িত করব। initializePlayer() ফাংশনে MediaSessionConnector-এর ইনস্ট্যানসিয়েশনটি খুঁজুন এবং mediaSession ইনিশিয়ালাইজ হওয়ার পরে TimelineQueueNavigator-এর একটি ইমপ্লিমেন্টেশন যোগ করুন।
mediaSessionConnector.setQueueNavigator(new TimelineQueueNavigator(mediaSession) {
@Override
public MediaDescriptionCompat getMediaDescription(Player player, int windowIndex) {
return new MediaDescriptionCompat.Builder()
.setTitle(player.getCurrentMediaItem().mediaMetadata.title)
.setDescription("MediaDescription description for " + windowIndex)
.setSubtitle("MediaDescription subtitle")
.build();
}
});
নিম্নলিখিতটি যোগ করে ক্লাস ইম্পোর্টগুলো সমাধান করুন:
import android.support.v4.media.MediaDescriptionCompat;
import com.google.android.exoplayer2.ext.mediasession.TimelineQueueNavigator;
লক্ষ্য করুন যে windowIndex প্যারামিটারটি প্লেব্যাক কিউ-এর সেই ইনডেক্সের আইটেমটির সাথে সঙ্গতিপূর্ণ।
এখন যেহেতু আপনি কিছু মেটাডেটা যোগ করেছেন, আপনি পরীক্ষা করে দেখতে পারেন যে অ্যাসিস্ট্যান্ট বুঝতে পারছে কিনা কী চলছে। অ্যান্ড্রয়েড টিভিতে একটি ভিডিও চালানোর সময়, অ্যাসিস্ট্যান্টকে চালু করুন এবং জিজ্ঞাসা করুন "কী চলছে?"

৫. ক্রিয়াগুলি কাস্টমাইজ করা
হয়তো আপনার প্লেয়ার কিছু অ্যাকশন সাপোর্ট করে না, অথবা আপনি আরও অ্যাকশনের সাপোর্ট যোগ করতে চান? চলুন এবার মিডিয়া সেশনটি নিয়ে আরেকটু গভীরভাবে আলোচনা করা যাক, যেখানে আমরা আগে initializePlayer() ফাংশনে আমাদের MediaSessionConnector তৈরি করেছিলাম।
সমর্থিত পদক্ষেপ ঘোষণা করা
মিডিয়া সেশনটি কোন কোন অ্যাকশন সমর্থন করবে তা কাস্টমাইজ করতে mediaSessionConnector.setEnabledPlaybackActions() ব্যবহার করে দেখতে পারেন।
লক্ষ্য করুন যে সম্পূর্ণ সেটটি হলো:
mediaSessionConnector.setEnabledPlaybackActions(
PlaybackStateCompat.ACTION_PLAY_PAUSE
| PlaybackStateCompat.ACTION_PLAY
| PlaybackStateCompat.ACTION_PAUSE
| PlaybackStateCompat.ACTION_SEEK_TO
| PlaybackStateCompat.ACTION_FAST_FORWARD
| PlaybackStateCompat.ACTION_REWIND
| PlaybackStateCompat.ACTION_STOP
| PlaybackStateCompat.ACTION_SET_REPEAT_MODE
| PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE
);
চলুন আবার দেখি এই ডেটা কীভাবে প্ল্যাটফর্মে প্রকাশ করা হয়:
- আগের মতোই, একটি ভিডিও চালু করুন।
- আপনার মিডিয়া সেশনের মেটাডেটা অ্যান্ড্রয়েড কীভাবে দেখে, তা জানতে নিম্নলিখিত কমান্ডটি চালান:
adb shell dumpsys media_session - মেটাডেটা ধারণকারী লাইনটি খুঁজুন এবং লক্ষ্য করুন যে শিরোনাম ও বিবরণ অন্তর্ভুক্ত আছে এবং
com.google.android.exoplayer2.demo/sampleসাথে যুক্ত রয়েছে।
অতিরিক্ত পদক্ষেপ যোগ করা
আমরা কিছু অতিরিক্ত পদক্ষেপের মাধ্যমে আমাদের মিডিয়া সেশনকে আরও প্রসারিত করতে পারি। এই অংশে, আমরা শুধু ক্যাপশনের জন্য সমর্থন যোগ করব।
সহায়ক ক্যাপশন
মিডিয়া সেশনে ক্যাপশনের সাপোর্ট যোগ করলে ব্যবহারকারীরা ভয়েসের মাধ্যমে তা চালু বা বন্ধ করতে পারবেন। যেখানে আপনি মিডিয়া সেশন কানেক্টরটি ইনিশিয়ালাইজ করেছিলেন, সেখানে নিম্নলিখিতটি যোগ করুন:
mediaSessionConnector.setCaptionCallback(new MediaSessionConnector.CaptionCallback() {
@Override
public void onSetCaptioningEnabled(Player player, boolean enabled) {
Log.d("MediaSession", "onSetCaptioningEnabled: enabled=" + enabled);
}
@Override
public boolean hasCaptions(Player player) {
return true;
}
@Override
public boolean onCommand(Player player, ControlDispatcher controlDispatcher, String command, Bundle extras, ResultReceiver cb) {
return false;
}
}
);
অবশেষে, কোনো অনুপস্থিত ইম্পোর্ট থাকলে তা সমাধান করুন।
আপনি অ্যান্ড্রয়েড টিভিতে গুগল অ্যাসিস্ট্যান্ট চালু করে "ক্যাপশন চালু করুন" বলে এটি পরীক্ষা করতে পারেন। এটি কীভাবে আপনার কোডকে কল করছে তা দেখতে লগক্যাটে থাকা মেসেজগুলো দেখুন।
৬. অভিনন্দন
অভিনন্দন, আপনি সফলভাবে নমুনাটিতে মিডিয়া সেশন যুক্ত করেছেন!
আপনি নিম্নলিখিত উপায়ে বিপুল পরিমাণ কার্যকারিতা অর্জন করেছেন:
- একটি মিডিয়া সেশন যোগ করা,
- ExoPlayer-এর একটি ইনস্ট্যান্সের সাথে মিডিয়া সেশন সংযুক্ত করা,
- মেটাডেটা এবং অতিরিক্ত পদক্ষেপ যোগ করা।
একটি মিডিয়া অ্যাপকে আরও সমৃদ্ধ করতে এবং ব্যবহারকারীদের আরও বহুমুখী অভিজ্ঞতা দেওয়ার জন্য প্রয়োজনীয় মূল পদক্ষেপগুলো এখন আপনি জানেন!
শেষ মন্তব্য
এই কোডল্যাবটি ExoPlayer সোর্স কোডের একটি স্যাম্পলের উপর ভিত্তি করে তৈরি করা হয়েছে। সরাসরি সোর্স থেকে ExoPlayer ব্যবহার করার কোনো প্রয়োজন নেই, এবং এর পরিবর্তে ExoPlayer ও MediaSessionConnector-এর ডিপেন্ডেন্সিগুলো পুল করার পরামর্শ দেওয়া হচ্ছে, যাতে সর্বশেষ রিলিজগুলোর সাথে আপ-টু-ডেট থাকা সহজ হয়।
এটি করার জন্য, কেবল প্রোজেক্টের নির্ভরতাগুলি প্রতিস্থাপন করুন, যেমন:
implementation project(modulePrefix + 'library-core')
implementation project(path: ':extension-mediasession')
Maven রিপোজিটরি থেকে ডেটা টানতে, যেমন:
implementation 'com.google.android.exoplayer:exoplayer-core:2.+'
implementation 'com.google.android.exoplayer:extension-mediasession:2.+'