AndroidX Media3 মাইগ্রেশন গাইড

যেসব অ্যাপ বর্তমানে স্ট্যান্ডঅ্যালোন com.google.android.exoplayer2 লাইব্রেরি ও androidx.media ব্যবহার করছে, সেগুলিকে androidx.media3-এ মাইগ্রেট করতে হবে। ExoPlayer 2.19.1 থেকে AndroidX Media3 1.1.1-এ gradle বিল্ড ফাইল, Java এবং Kotlin সোর্স ফাইল এবং XML লেআউট ফাইল মাইগ্রেট করতে মাইগ্রেশন স্ক্রিপ্ট ব্যবহার করুন।

এক নজরে

মাইগ্রেট করার আগে, নতুন API-এর সুবিধা, মাইগ্রেট করার API এবং আপনার অ্যাপের প্রোজেক্টের পূরণ করা উচিত এমন পূর্বশর্ত সম্পর্কে আরও জানতে নিম্নলিখিত বিভাগগুলি পর্যালোচনা করুন।

Jetpack Media3-তে কেন মাইগ্রেট করবেন

  • এটি হল ExoPlayer-এর নতুন হোম, যেখানে com.google.android.exoplayer2 বন্ধ করে দেওয়া হয়েছে।
  • MediaBrowser/MediaController-এর মাধ্যমে বিভিন্ন কম্পোনেন্ট/প্রসেস জুড়ে Player API অ্যাক্সেস করুন।
  • MediaSession এবং MediaController API-এর বর্ধিত ক্ষমতা ব্যবহার করুন।
  • ফাইন-গ্রেন অ্যাক্সেস কন্ট্রোল সহ প্লেব্যাক ক্ষমতা বিজ্ঞাপন দিন।
  • MediaSessionConnector ও PlayerNotificationManager সরিয়ে দিয়ে আপনার অ্যাপকে আরও সহজ করুন।
  • মিডিয়া-কম্প্যাট ক্লায়েন্ট API-এর সাথে ব্যাকওয়ার্ড কম্প্যাটিবল (MediaBrowserCompat/MediaControllerCompat/MediaMetadataCompat)

AndroidX Media3-তে মাইগ্রেট করার জন্য মিডিয়া API

  • ExoPlayer ও এর এক্সটেনশন
    এর মধ্যে বন্ধ হয়ে যাওয়া mediasession মডিউল ছাড়া পুরনো ExoPlayer প্রোজেক্টের সব মডিউল অন্তর্ভুক্ত। com.google.android.exoplayer2-এ প্যাকেজের উপর নির্ভর করে অ্যাপ বা মডিউলকে মাইগ্রেশন স্ক্রিপ্টের মাধ্যমে মাইগ্রেট করা যেতে পারে।
  • MediaSessionConnector (depending on the androidx.media.* packages of androidx.media:media:1.4.3+)
    MediaSessionConnector সরিয়ে দিন এবং এর পরিবর্তে androidx.media3.session.MediaSession ব্যবহার করুন।
  • MediaBrowserServiceCompat (depending on the androidx.media.* packages of androidx.media:media:1.4.3+)
    androidx.media.MediaBrowserServiceCompat-এর সাবক্লাসকে androidx.media3.session.MediaLibraryService-এ মাইগ্রেট করুন এবং MediaBrowserCompat.MediaItem ব্যবহার করে androidx.media3.common.MediaItem-এ কোড করুন।
  • MediaBrowserCompat (depending on the android.support.v4.media.* packages of androidx.media:media:1.4.3+)
    MediaBrowserCompat বা MediaControllerCompat ব্যবহার করে ক্লায়েন্ট কোড মাইগ্রেট করুন, যাতে androidx.media3.common.MediaItem-এর সাথে androidx.media3.session.MediaBrowser ব্যবহার করা যায়।

পূর্বশর্ত

  1. আপনার প্রোজেক্ট সোর্স কন্ট্রোলের অধীনে আছে কিনা তা নিশ্চিত করুন

    স্ক্রিপ্টেড মাইগ্রেশন টুলের মাধ্যমে প্রয়োগ করা পরিবর্তনগুলি যাতে সহজেই ফিরিয়ে আনা যায় তা নিশ্চিত করুন। আপনার প্রোজেক্ট এখনও সোর্স কন্ট্রোলের অধীনে না থাকলে, এখন এটি শুরু করার জন্য ভাল সময়। কোনও কারণে আপনি এটি করতে না চাইলে, মাইগ্রেশন শুরু করার আগে আপনার প্রজেক্টের একটি ব্যাক-আপ কপি তৈরি করুন।

  2. আপনার অ্যাপ আপডেট করুন

    • আমাদের সাজেশন হল, আপনার প্রোজেক্ট আপডেট করে ExoPlayer লাইব্রেরির সবচেয়ে লেটেস্ট ভার্সন ব্যবহার করুন এবং পুরনো হয়ে যাওয়া মেথডকে কল করা সরিয়ে দিন। আপনি মাইগ্রেশনের জন্য স্ক্রিপ্ট ব্যবহার করতে চাইলে, আপনাকে স্ক্রিপ্ট দ্বারা ম্যানেজ করা ভার্সনের সাথে আপডেট করা ভার্সন ম্যাচ করাতে হবে।

    • আপনার অ্যাপের compileSdkVersion অন্তত 32 করুন।

    • উপরে উল্লিখিত আপডেট করা ডিপেন্ডেন্সিগুলির সাথে কাজ করে এমন একটি সাম্প্রতিক ভার্সনে Gradle এবং Android Studio Gradle প্লাগ-ইন আপগ্রেড করুন। যেমন:

      • Android Gradle প্লাগ-ইন ভার্সন: 7.1.0
      • Gradle ভার্সন: 7.4
    • অ্যাস্টেরিক্স (*) ব্যবহার করা সব ওয়াইল্ডকার্ড ইম্পোর্ট স্টেটমেন্ট পরিবর্তন করুন এবং সম্পূর্ণ কোয়ালিফায়েড ইম্পোর্ট স্টেটমেন্ট ব্যবহার করুন: ওয়াইল্ডকার্ড ইম্পোর্ট স্টেটমেন্ট মুছে দিন এবং সম্পূর্ণ কোয়ালিফায়েড স্টেটমেন্ট ইম্পোর্ট করতে Android Studio ব্যবহার করুন (F2 - Alt/Enter, F2 - Alt/Enter, ...)।

    • com.google.android.exoplayer2.PlayerView থেকে মাইগ্রেট করে com.google.android.exoplayer2.StyledPlayerView-এ যান। এটি প্রয়োজন কারণ AndroidX Media3-তে com.google.android.exoplayer2.PlayerView-এর সমতুল্য কিছু নেই।

স্ক্রিপ্ট সহায়তা সহ ExoPlayer মাইগ্রেট করা

এই স্ক্রিপ্ট androidx.media3-এর অধীনে com.google.android.exoplayer2 থেকে নতুন প্যাকেজ ও মডিউল স্ট্রাকচারে সরানোর সুবিধা দেয়। স্ক্রিপ্ট আপনার প্রোজেক্টে কিছু যাচাইকরণ চেক প্রয়োগ করে এবং যাচাইকরণ না করা গেলে সতর্কতা প্রিন্ট করে। অন্যথায়, এটি Java বা Kotlin-এ লেখা Android Gradle প্রোজেক্টের রিসোর্সে রিনেম করা ক্লাস ও প্যাকেজের ম্যাপিং প্রয়োগ করে।

usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
 PROJECT_ROOT: path to your project root (location of 'gradlew')
 -p: list package mappings and then exit
 -c: list class mappings (precedence over package mappings) and then exit
 -d: list dependency mappings and then exit
 -l: list files that will be considered for rewrite and then exit
 -x: exclude the path from the list of file to be changed: 'app/src/test'
 -m: migrate packages, classes and dependencies to AndroidX Media3
 -f: force the action even when validation fails
 -v: print the exoplayer2/media3 version strings of this script
 -h, --help: show this help text

মাইগ্রেশন স্ক্রিপ্ট ব্যবহার করা

  1. আপনি যে ভার্সনে অ্যাপ আপডেট করেছেন, সেই ভার্সনের সাথে সম্পর্কিত GitHub-এ ExoPlayer প্রোজেক্টের ট্যাগ থেকে মাইগ্রেশন স্ক্রিপ্ট ডাউনলোড করুন:

    curl -o media3-migration.sh \
      "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
    
  2. স্ক্রিপ্ট এক্সিকিউটেবল করুন:

    chmod 744 media3-migration.sh
    
  3. বিকল্প সম্পর্কে জানতে --help সহ স্ক্রিপ্ট রান করান।

  4. -l ব্যবহার করে স্ক্রিপ্ট রান করান যাতে মাইগ্রেশনের জন্য বেছে নেওয়া ফাইলের সেট তালিকাভুক্ত করা যায় (সতর্কতা ছাড়াই তালিকাভুক্ত করতে -f ব্যবহার করুন):

    ./media3-migration.sh -l -f /path/to/gradle/project/root
    
  5. Media3-তে প্যাকেজ, ক্লাস ও মডিউল ম্যাপ করতে -m ব্যবহার করে স্ক্রিপ্ট রান করান। -m বিকল্পের মাধ্যমে স্ক্রিপ্ট রান করালে, বেছে নেওয়া ফাইলে পরিবর্তন প্রয়োগ করা হবে।

    • পরিবর্তন না করেই যাচাইকরণ সংক্রান্ত সমস্যার সময় বন্ধ হয়ে যাওয়া
    ./media3-migration.sh -m /path/to/gradle/project/root
    
    • বাধ্যতামূলক এক্সিকিউশন

    স্ক্রিপ্ট যদি পূর্বশর্ত লঙ্ঘনের ঘটনা খুঁজে পায়, তাহলে -f ফ্ল্যাগ ব্যবহার করে মাইগ্রেশন বাধ্যতামূলক করা যেতে পারে:

    ./media3-migration.sh -m -f /path/to/gradle/project/root
    
 # list files selected for migration when excluding paths
 ./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
 # migrate the selected files
 ./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root

-m বিকল্প ব্যবহার করে স্ক্রিপ্ট চালানোর পরে এই ম্যানুয়াল ধাপগুলি সম্পূর্ণ করুন:

  1. স্ক্রিপ্ট কীভাবে আপনার কোড পরিবর্তন করেছে তা চেক করুন: একটি ডিফারেন্স টুল ব্যবহার করুন এবং সম্ভাব্য সমস্যা সমাধান করুন (যদি মনে করেন যে স্ক্রিপ্টে একটি সাধারণ সমস্যা আছে যা -f বিকল্পটি পাস না করেই যোগ করা হয়েছে, তাহলে একটি বাগ ফাইল করার কথা বিবেচনা করুন)।
  2. প্রোজেক্ট তৈরি করুন: ./gradlew clean build ব্যবহার করুন অথবা Android Studio-তে ফাইল > Gradle ফাইলের সাথে প্রোজেক্ট সিঙ্ক করুন, তারপর তৈরি করুন > প্রোজেক্ট ক্লিন করুন এবং তারপর তৈরি করুন > প্রোজেক্ট আবার তৈরি করুন বিকল্প বেছে নিন (Android Studio-র'তৈরি করুন - তৈরি করার আউটপুট' ট্যাবে আপনার তৈরি করা মনিটর করুন)।

সাজেস্ট করা ফলো-আপ ধাপ:

  1. অস্থিতিশীল API-এর ব্যবহার সংক্রান্ত সমস্যার জন্য অপ্ট-ইন করুন।
  2. অননুমোদিত API কলের পরিবর্তে অন্য API ব্যবহার করুন: সাজেস্ট করা বিকল্প API ব্যবহার করুন। Android Studio-তে সতর্কতা চিহ্নের উপরে মাউস নিয়ে যান এবং প্রদত্ত কলের পরিবর্তে কী ব্যবহার করতে হবে তা জানতে বন্ধ হয়ে যাওয়া সিম্বলের JavaDoc দেখুন।
  3. ইমপোর্ট স্টেটমেন্ট সাজানো: Android Studio-তে প্রোজেক্ট খুলুন, তারপর প্রোজেক্ট ভিউয়ারে প্যাকেজ ফোল্ডার নোডে মাউসের ডানদিকের বোতামে ক্লিক করে পরিবর্তিত সোর্স ফাইল থাকা প্যাকেজে ইমপোর্ট অপ্টিমাইজ করুন বিকল্প বেছে নিন।

MediaSessionConnector-এর জায়গায় androidx.media3.session.MediaSession লিখুন

পুরনো MediaSessionCompat জগতে, MediaSessionConnector প্লেয়ারের স্টেটকে সেশনের স্টেটের সাথে সিঙ্ক করার জন্য দায়ী ছিল এবং কন্ট্রোলার থেকে এমন কমান্ড গ্রহণ করত যেগুলি উপযুক্ত প্লেয়ার মেথডে ডেলিগেট করতে হত। AndroidX Media3-এর মাধ্যমে, এটি MediaSession সরাসরি কানেক্টরের প্রয়োজন ছাড়াই করা হয়।

  1. MediaSessionConnector-এর সমস্ত রেফারেন্স ও ব্যবহার সরিয়ে দিন: আপনি যদি ExoPlayer ক্লাস ও প্যাকেজ মাইগ্রেট করার জন্য অটোমেটেড স্ক্রিপ্ট ব্যবহার করে থাকেন, তাহলে স্ক্রিপ্ট সম্ভবত আপনার কোডকে এমন অবস্থায় রেখে গেছে যা কম্পাইল করা যায় না। এটিMediaSessionConnector সম্পর্কিত এবং এর সমাধান করা যায় না। আপনি অ্যাপ তৈরি বা চালু করার চেষ্টা করলে, Android Studio আপনাকে ভুল কোড দেখাবে।

  2. আপনি যেখানে ডিপেন্ডেন্সি ম্যানেজ করেন সেই build.gradle ফাইলে, AndroidX Media3 সেশন মডিউলে ইমপ্লিমেন্টেশন ডিপেন্ডেন্সি যোগ করুন এবং লেগ্যাসি ডিপেন্ডেন্সি সরিয়ে দিন:

    implementation "androidx.media3:media3-session:1.11.1"
    
  3. MediaSessionCompat-এর জায়গায় androidx.media3.session.MediaSession বসান।

  4. আপনি যে কোড সাইটে লেগ্যাসি MediaSessionCompat তৈরি করেছেন, সেখানে একটি MediaSession তৈরি করতে androidx.media3.session.MediaSession.Builder ব্যবহার করুন। সেশন বিল্ডার তৈরি করতে প্লেয়ারকে পাস করুন।

    Kotlin

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

    জাভা

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

  5. আপনার অ্যাপের প্রয়োজন অনুযায়ী MySessionCallback প্রয়োগ করুন। এটি ঐচ্ছিক। আপনি যদি কন্ট্রোলারদের প্লেয়ারে মিডিয়া আইটেম যোগ করার অনুমতি দিতে চান, তাহলে MediaSession.Callback.onAddMediaItems() প্রয়োগ করুন। এটি বিভিন্ন বর্তমান ও লেগ্যাসি API পদ্ধতি পরিবেশন করে যা প্লেয়ারে মিডিয়া আইটেম যোগ করে যাতে ব্যাকওয়ার্ড-কম্প্যাটিবল উপায়ে প্লেব্যাক করা যায়। এর মধ্যে Media3 কন্ট্রোলারের MediaController.set/addMediaItems() পদ্ধতি, সেইসাথে লেগ্যাসি API-এর TransportControls.prepareFrom*/playFrom* পদ্ধতি অন্তর্ভুক্ত। onAddMediaItems-এর একটি স্যাম্পেল প্রয়োগ সেশন ডেমো অ্যাপের PlaybackService-এ পাওয়া যাবে।

  6. মাইগ্রেশনের আগে আপনি যে কোড সাইটে সেশন বন্ধ করেছিলেন, সেখানে মিডিয়া সেশন রিলিজ করুন:

    Kotlin

    mediaSession?.run {
      player.release()
      release()
      mediaSession = null
    }

    জাভা

    if (mediaSession != null) {
      mediaSession.getPlayer().release();
      mediaSession.release();
      mediaSession = null;
    }

Media3-তে MediaSessionConnector কার্যকারিতা

নিম্নলিখিত সারণীতে Media3 API দেখানো হয়েছে যা MediaSessionConnector-এ আগে প্রয়োগ করা কার্যকারিতা ম্যানেজ করে।

MediaSessionConnectorAndroidX Media3
CustomActionProvider MediaSession.Callback.onCustomCommand()/ MediaSession.setMediaButtonPreferences()
PlaybackPreparer MediaSession.Callback.onAddMediaItems() (prepare() ইন্টার্নালি কল করা হয়)
QueueNavigator ForwardingSimpleBasePlayer
QueueEditor MediaSession.Callback.onAddMediaItems()
RatingCallback MediaSession.Callback.onSetRating()
PlayerNotificationManager DefaultMediaNotificationProvider/ MediaNotification.Provider

MediaBrowserService থেকে MediaLibraryService-এ মাইগ্রেট করুন

AndroidX Media3 MediaLibraryService নিয়ে এসেছে যা MediaBrowserServiceCompat-এর পরিবর্তে ব্যবহার করা যাবে। MediaLibraryService-এর JavaDoc এবং এর সুপার ক্লাস MediaSessionService API এবং পরিষেবার অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং মডেল সম্পর্কে একটি ভালো ভূমিকা প্রদান করে।

MediaLibraryService, MediaBrowserService-এর সাথে ব্যাকওয়ার্ড কম্প্যাটিবল হিসেবে কাজ করে। MediaBrowserCompat বা MediaControllerCompat ব্যবহার করছে এমন কোনও ক্লায়েন্ট অ্যাপ, MediaLibraryService-এর সাথে কানেক্ট করার সময় কোড পরিবর্তন না করেই কাজ চালিয়ে যেতে পারে। ক্লায়েন্টের ক্ষেত্রে, আপনার অ্যাপ MediaLibraryService বা পুরনো MediaBrowserServiceCompat ব্যবহার করছে কিনা তা স্পষ্টভাবে বোঝা যায়।

পরিষেবা, অ্যাক্টিভিটি ও এক্সটার্নাল অ্যাপ সহ অ্যাপ কম্পোনেন্ট ডায়াগ্রাম।
ছবি ১: মিডিয়া অ্যাপ কম্পোনেন্টের ওভারভিউ
  1. ব্যাকওয়ার্ড কম্প্যাটিবিলিটি কাজ করার জন্য, আপনাকে AndroidManifest.xml-এ আপনার পরিষেবার সাথে দুটি পরিষেবা ইন্টারফেস রেজিস্টার করতে হবে। এইভাবে, কোনও ক্লায়েন্ট প্রয়োজনীয় পরিষেবা ইন্টারফেসের মাধ্যমে আপনার পরিষেবা খুঁজে পায়:

    <service android:name=".MusicService" android:exported="true">
        <intent-filter>
            <action android:name="androidx.media3.session.MediaLibraryService"/>
            <action android:name="android.media.browse.MediaBrowserService" />
        </intent-filter>
    </service>
    
  2. আপনি যেখানে ডিপেন্ডেন্সি ম্যানেজ করেন সেই build.gradle ফাইলে, AndroidX Media3 সেশন মডিউলে একটি ইমপ্লিমেন্টেশন ডিপেন্ডেন্সি যোগ করুন এবং পুরনো ডিপেন্ডেন্সি সরিয়ে দিন:

    implementation "androidx.media3:media3-session:1.11.1"
    
  3. আপনার পরিষেবা পরিবর্তন করে MediaLibraryService থেকে ইনহেরিট করুন, এর পরিবর্তে MediaBrowserService আগে বলা হয়েছে, MediaLibraryService হল লেগ্যাসি MediaBrowserService-এর সাথে মানানসই। সেই অনুযায়ী, পরিষেবাটি ক্লায়েন্টদের যে বৃহত্তর API অফার করছে সেটি এখনও একই আছে। তাই, এটি সম্ভব যে কোনও অ্যাপ MediaBrowserService কার্যকর করার জন্য প্রয়োজনীয় বেশিরভাগ লজিক রাখতে পারে এবং নতুন MediaLibraryService-এর জন্য এটি মানিয়ে নিতে পারে।

    লেগ্যাসি MediaBrowserServiceCompat-এর তুলনায় প্রধান পার্থক্যগুলি হল:

    • পরিষেবার লাইফ-সাইকেল পদ্ধতি প্রয়োগ করুন: পরিষেবার মধ্যে যে পদ্ধতিগুলি ওভাররাইড করতে হবে সেগুলি হল onCreate/onDestroy, যেখানে অ্যাপ লাইব্রেরি সেশন, প্লেয়ার ও অন্যান্য সম্পদ বরাদ্দ/রিলিজ করে। পরিষেবার সাধারণ লাইফ-সাইকেল পদ্ধতি ছাড়াও, কোনও অ্যাপকে onGetSession(MediaSession.ControllerInfo) ওভাররাইড করে onCreate-এ বিল্ট-ইন করা MediaLibrarySession রিটার্ন করতে হয়।

    • MediaLibraryService.MediaLibrarySessionCallback প্রয়োগ করুন: সেশন তৈরি করতে MediaLibraryService.MediaLibrarySessionCallback প্রয়োজন যা প্রকৃত ডোমেন API পদ্ধতি প্রয়োগ করে। তাই, লিগ্যাসি পরিষেবার API পদ্ধতি ওভাররাইড করার পরিবর্তে, আপনি MediaLibrarySession.Callback-এর পদ্ধতি ওভাররাইড করবেন।

      কলব্যাকটি তারপর MediaLibrarySession তৈরি করতে ব্যবহার করা হয়:

      Kotlin

      mediaLibrarySession = MediaLibrarySession.Builder(context, player, MySessionCallback()).build()

      জাভা

      mediaLibrarySession =
          new MediaLibrarySession.Builder(context, player, new MySessionCallback()).build();

      API ডকুমেন্টেশনে MediaLibrarySessionCallback-এর সম্পূর্ণ API দেখুন।

    • MediaSession.Callback.onAddMediaItems() প্রয়োগ করুন: কলব্যাক onAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>) প্লেয়ারে মিডিয়া আইটেম যোগ করার জন্য বিভিন্ন বর্তমান ও লিগ্যাসি API পদ্ধতি পরিবেশন করে, যা ব্যাকওয়ার্ড-কম্প্যাটিবল উপায়ে প্লেব্যাক করে। এর মধ্যে Media3 কন্ট্রোলারের MediaController.set/addMediaItems() পদ্ধতি এবং TransportControls.prepareFrom*/playFrom* লেগ্যাসি API-এর পদ্ধতি অন্তর্ভুক্ত। কলব্যাক প্রয়োগ করার একটি নমুনা সেশন ডেমো অ্যাপের PlaybackService-এ পাওয়া যাবে।

    • AndroidX Media3 MediaBrowserCompat.MediaItem এবং MediaMetadataCompat-এর পরিবর্তে androidx.media3.common.MediaItem ব্যবহার করছে। লেগ্যাসি ক্লাসের সাথে যুক্ত আপনার কোডের অংশগুলি সেই অনুযায়ী পরিবর্তন করতে হবে অথবা Media3 MediaItem-এর সাথে ম্যাপ করতে হবে।

    • সাধারণ অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং মডেল Futures-এ পরিবর্তন করা হয়েছে, যা MediaBrowserServiceCompat-এর ডিট্যাচেবল Result অ্যাপ্রোচের বিপরীত। আপনার পরিষেবা প্রয়োগ করার ফলে কোনও ফলাফল আলাদা করার পরিবর্তে অ্যাসিঙ্ক্রোনাস ListenableFuture রিটার্ন করতে পারে অথবা কোনও ভ্যালু সরাসরি রিটার্ন করার জন্য অবিলম্বে Future রিটার্ন করতে পারে।

PlayerNotificationManager সরিয়ে দেওয়া

MediaLibraryService অটোমেটিক মিডিয়া বিজ্ঞপ্তি কাজ করে এবং MediaLibraryService বা MediaSessionService ব্যবহার করার সময় PlayerNotificationManager সরিয়ে দেওয়া যায়।

কোনও অ্যাপ কাস্টম MediaNotification.Provider সেট করে বিজ্ঞপ্তি কাস্টমাইজ করতে পারে যা onCreate()-এ DefaultMediaNotificationProvider-এর পরিবর্তে ব্যবহার করা হয়। তারপরে, MediaLibraryService প্রয়োজনমতো ফোরগ্রাউন্ডে পরিষেবা চালু করার বিষয়টি দেখে নেয়।

MediaLibraryService.updateNotification() ওভাররাইড করার মাধ্যমে, কোনও অ্যাপ আরও বিজ্ঞপ্তি পোস্ট করার সম্পূর্ণ মালিকানা নিতে এবং প্রয়োজন অনুসারে ফোরগ্রাউন্ডে পরিষেবা শুরু/বন্ধ করতে পারে।

MediaBrowser ব্যবহার করে ক্লায়েন্ট কোড মাইগ্রেট করা

AndroidX Media3-এর মাধ্যমে, MediaBrowser MediaController/Player ইন্টারফেস প্রয়োগ করে এবং মিডিয়া লাইব্রেরি ব্রাউজ করা ছাড়াও মিডিয়া প্লেব্যাক কন্ট্রোল করতে ব্যবহার করা যায়। লেগ্যাসি ওয়ার্ল্ডে আপনাকে MediaBrowserCompat ও MediaControllerCompat তৈরি করতে হলে, Media3-তে আপনি শুধুমাত্র MediaBrowser ব্যবহার করেই একই কাজ করতে পারবেন।

MediaBrowser তৈরি করা যেতে পারে এবং কানেকশনের জন্য অপেক্ষা করা যেতে পারে পরিষেবা প্রতিষ্ঠিত হচ্ছে:

Kotlin

scope.launch {
  val sessionToken = SessionToken(context, ComponentName(context, "MusicService"))
  browser =
    MediaBrowser.Builder(context, sessionToken)
      .setListener(BrowserListener())
      .buildAsync()
      .await()
}

জাভা

SessionToken sessionToken =
    new SessionToken(context, new ComponentName(context, "MusicService"));
ListenableFuture<MediaBrowser> browserFuture =
    new MediaBrowser.Builder(context, sessionToken)
        .setListener(new BrowserListener())
        .buildAsync();

ব্যাকগ্রাউন্ডে প্লেব্যাক কন্ট্রোল করার জন্য কীভাবে MediaController তৈরি করতে হয় তা জানতে মিডিয়া সেশনে প্লেব্যাক কন্ট্রোল করা লিঙ্কে দেখুন।

পরবর্তী ধাপ ও পরিষ্কার করা

অস্থির API সংক্রান্ত সমস্যা

Media3-তে মাইগ্রেট করার পরে, আপনি অস্থির API ব্যবহার সম্পর্কে লিন্ট সমস্যা দেখতে পেতে পারেন। এইসব API ব্যবহার করা নিরাপদ এবং আমাদের নতুন বাইনারি কম্প্যাটিবিলিটি গ্যারান্টির উপজাত হিসেবে লিন্ট সংক্রান্ত সমস্যা দেখা দেয়। আপনার যদি কঠোর বাইনারি কম্প্যাটিবিলিটির প্রয়োজন না হয়, তাহলে @OptIn অ্যানোটেশনের মাধ্যমে এইসব সমস্যা নিরাপদে এড়িয়ে যাওয়া যেতে পারে।

ব্যাকগ্রাউন্ড

পরবর্তী ভার্সনগুলির মধ্যে লাইব্রেরির বাইনারি মানানসই হওয়ার ব্যাপারে ExoPlayer v1 বা v2 কোনওটিই কঠোর গ্যারান্টি দেয় না। প্লেব্যাকের প্রায় প্রতিটি দিক কাস্টমাইজ করার জন্য অ্যাপকে অনুমতি দিতে ExoPlayer API সারফেসকে ডিজাইন অনুযায়ী খুব বড় করা হয়েছে। ExoPlayer-এর পরবর্তী ভার্সনগুলি মাঝে মাঝে প্রতীক নাম পরিবর্তন বা অন্যান্য ব্রেকিং পরিবর্তন (যেমন, ইন্টারফেসে নতুন প্রয়োজনীয় পদ্ধতি) নিয়ে আসে। বেশিরভাগ ক্ষেত্রে, নতুন প্রতীক চালু করে এবং কিছু ভার্সনের জন্য পুরনো প্রতীকটি সরিয়ে দিয়ে এই ধরনের সমস্যা কমানো হয়েছে। এর ফলে ডেভেলপাররা তাদের ব্যবহার করা কোড মাইগ্রেট করার সময় পেয়েছেন। তবে, এটি সবসময় সম্ভব হয়নি।

এইসব ব্রেকিং পরিবর্তনের ফলে ExoPlayer v1 এবং v2 লাইব্রেরির ব্যবহারকারীদের জন্য দুটি সমস্যা হয়েছে:

  1. ExoPlayer ভার্সন থেকে আপগ্রেড করলে কোড কম্পাইল করা বন্ধ হয়ে যেতে পারে।
  2. সরাসরি এবং মধ্যবর্তী লাইব্রেরির মাধ্যমে ExoPlayer-এর উপর নির্ভর করে এমন কোনও অ্যাপকে নিশ্চিত করতে হবে যে দুটি নির্ভরতা একই ভার্সনের, অন্যথায় বাইনারি ইনকম্প্যাটিবিলিটির ফলে রানটাইম ক্র্যাশ হতে পারে।

Media3-তে উন্নতি

Media3, API সারফেসের একটি সাবসেটের জন্য বাইনারি কম্প্যাটিবিলিটির গ্যারান্টি দেয়। যেসব পার্ট বাইনারি মানানসই হওয়ার গ্যারান্টি দেয় না, সেগুলি @UnstableApi দিয়ে চিহ্নিত করা হয়। এই পার্থক্য স্পষ্ট করার জন্য, @OptIn দিয়ে অ্যানোটেট করা না থাকলে, আনস্টেবল API সিম্বল ব্যবহার করলে লিন্ট এরর তৈরি হয়।

ExoPlayer v2 থেকে Media3-তে মাইগ্রেট করার পরে, আপনি অনেক আনস্টেবল API লিন্ট সংক্রান্ত সমস্যা দেখতে পেতে পারেন। এর ফলে মনে হতে পারে যে Media3, ExoPlayer v2-এর তুলনায় 'কম স্থিতিশীল'। এটি সেই ঘটনা নয়। Media3 API-এর 'অস্থির' অংশগুলি ExoPlayer v2 API সারফেসের সম্পূর্ণ অংশের মতো একই লেভেলের স্থিতিশীলতা প্রদান করে এবং স্থিতিশীল Media3 API সারফেসের গ্যারান্টি ExoPlayer v2-এ উপলভ্য নয়। দুটির মধ্যে পার্থক্য হল, লিন্ট সংক্রান্ত সমস্যা এখন আপনাকে স্থিতিশীলতার বিভিন্ন লেভেল সম্পর্কে সতর্ক করে।

অস্থিতিশীল API লিন্ট সংক্রান্ত সমস্যার সমাধান করা

কীভাবে @OptIn-এর মাধ্যমে অস্থির API-এর Java ও Kotlin ব্যবহারকে অ্যানোটেট করবেন সেই বিষয়ে বিস্তারিত জানতে, এইসব লিন্ট সংক্রান্ত সমস্যার সমাধান বিভাগ দেখুন।

সঞ্চালনে নেই এমন API

আপনি হয়ত লক্ষ্য করবেন যে Android Studio-তে অননুমোদিত API-তে করা কল স্ট্রাইক-থ্রু করা আছে। আমরা সাজেস্ট করি যে এই ধরনের কলগুলি উপযুক্ত বিকল্পের সাথে পরিবর্তন করুন। এর পরিবর্তে কোন API ব্যবহার করতে হবে তা জানতে, চিহ্নের উপর মাউস নিয়ে গিয়ে JavaDoc দেখুন।

স্ক্রিনশট: বন্ধ করে দেওয়া পদ্ধতির বিকল্প হিসেবে JavaDoc কীভাবে দেখানো যায়
ছবি ৩: Android Studio-তে JavaDoc টুলটিপ, কোনও বাতিল হয়ে যাওয়া প্রতীকের বিকল্প সাজেস্ট করে।

কোড স্যাম্পেল ও ডেমো অ্যাপ

  • AndroidX Media3 সেশন ডেমো অ্যাপ (মোবাইল ও WearOS)
    • কাস্টম অ্যাকশন
    • সিস্টেম UI বিজ্ঞপ্তি, MediaButton/BT
    • Google Assistant প্লেব্যাক কন্ট্রোল
  • UAMP: Android Media Player (branch media3) (মোবাইল, AutomotiveOS)
    • সিস্টেম UI বিজ্ঞপ্তি, MediaButton/BT, প্লেব্যাক আবার চালু করা
    • Google Assistant/WearOS প্লেব্যাক কন্ট্রোল
    • AutomotiveOS: কাস্টম কমান্ড ও সাইন-ইন