মিডিয়া ব্রাউজার ক্লায়েন্ট তৈরি করা

ক্লায়েন্ট/সার্ভার ডিজাইন সম্পূর্ণ করতে, আপনাকে একটি অ্যাক্টিভিটি কম্পোনেন্ট তৈরি করতে হবে যাতে আপনার UI কোড, একটি সংশ্লিষ্ট MediaController এবং একটি MediaBrowser থাকে।

MediaBrowser দুটি গুরুত্বপূর্ণ কাজ করে: এটি MediaBrowserService-এর সাথে কানেক্ট করে এবং কানেক্ট করার পরে এটি আপনার UI-এর জন্য MediaController তৈরি করে।

মনে রাখবেন: MediaBrowser-এর সাজেস্ট করা প্রয়োগ হল MediaBrowserCompat, যা Media-Compat সাপোর্ট লাইব্রেরিতে উল্লেখ করা আছে। এই পৃষ্ঠা জুড়ে "MediaBrowser" শব্দটি MediaBrowserCompat-এর একটি ইনস্ট্যান্সকে বোঝায়।

MediaBrowserService-এ কানেক্ট করুন

আপনার ক্লায়েন্ট অ্যাক্টিভিটি তৈরি করা হলে, এটি MediaBrowserService-এর সাথে কানেক্ট করে। এতে একটু হ্যান্ডশেক ও নাচও আছে। অ্যাক্টিভিটির লাইফসাইকেল কলব্যাক এইভাবে পরিবর্তন করুন:

  • onCreate() একটি MediaBrowserCompat তৈরি করে। আপনার MediaBrowserService এবং আপনার সংজ্ঞায়িত MediaBrowserCompat.ConnectionCallback-এর নাম পাস করুন।
  • onStart() MediaBrowserService-এর সাথে কানেক্ট করে। এখানেই MediaBrowserCompat.ConnectionCallback-এর ম্যাজিক শুরু হয়। কানেকশন সফল হলে, onConnect() কলব্যাক মিডিয়া কন্ট্রোলার তৈরি করে, মিডিয়া সেশনের সাথে এটি লিঙ্ক করে, আপনার UI কন্ট্রোল MediaController-এর সাথে লিঙ্ক করে এবং মিডিয়া সেশন থেকে কলব্যাক পাওয়ার জন্য কন্ট্রোলার রেজিস্টার করে।
  • onResume() অডিও স্ট্রিম সেট করে যাতে আপনার অ্যাপ ডিভাইসের ভলিউম কন্ট্রোলে সাড়া দেয়।
  • আপনার অ্যাক্টিভিটি বন্ধ হয়ে গেলে, onStop() আপনার MediaBrowser ডিসকানেক্ট করে এবং MediaController.Callback অনিবন্ধিত করে।

Kotlin

class MediaPlayerActivity : AppCompatActivity() {

    private lateinit var mediaBrowser: MediaBrowserCompat

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // ...
        // Create MediaBrowserServiceCompat
        mediaBrowser = MediaBrowserCompat(
                this,
                ComponentName(this, MediaPlaybackService::class.java),
                connectionCallbacks,
                null // optional Bundle
        )
    }

    public override fun onStart() {
        super.onStart()
        mediaBrowser.connect()
    }

    public override fun onResume() {
        super.onResume()
        volumeControlStream = AudioManager.STREAM_MUSIC
    }

    public override fun onStop() {
        super.onStop()
        // (see "stay in sync with the MediaSession")
        MediaControllerCompat.getMediaController(this)?.unregisterCallback(controllerCallback)
        mediaBrowser.disconnect()
    }
}

জাভা

public class MediaPlayerActivity extends AppCompatActivity {
  private MediaBrowserCompat mediaBrowser;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    // Create MediaBrowserServiceCompat
    mediaBrowser = new MediaBrowserCompat(this,
      new ComponentName(this, MediaPlaybackService.class),
        connectionCallbacks,
        null); // optional Bundle
  }

  @Override
  public void onStart() {
    super.onStart();
    mediaBrowser.connect();
  }

  @Override
  public void onResume() {
    super.onResume();
    setVolumeControlStream(AudioManager.STREAM_MUSIC);
  }

  @Override
  public void onStop() {
    super.onStop();
    // (see "stay in sync with the MediaSession")
    if (MediaControllerCompat.getMediaController(MediaPlayerActivity.this) != null) {
      MediaControllerCompat.getMediaController(MediaPlayerActivity.this).unregisterCallback(controllerCallback);
    }
    mediaBrowser.disconnect();

  }
}

MediaBrowserCompat.ConnectionCallback কাস্টমাইজ করুন

আপনার অ্যাক্টিভিটি MediaBrowserCompat তৈরি করলে, আপনাকে অবশ্যই ConnectionCallback-এর একটি ইনস্ট্যান্স তৈরি করতে হবে। MediaBrowserService থেকে মিডিয়া সেশন টোকেন ফিরিয়ে আনতে এর onConnected() পদ্ধতি পরিবর্তন করুন এবং MediaControllerCompat তৈরি করতে টোকেন ব্যবহার করুন।

কন্ট্রোলারে লিঙ্ক সেভ করতে MediaControllerCompat.setMediaController() সুবিধাজনক পদ্ধতি ব্যবহার করুন। এটি মিডিয়া বোতাম ম্যানেজ করার সুবিধা চালু করে। এছাড়াও, ট্রান্সপোর্ট কন্ট্রোল তৈরি করার সময় কন্ট্রোলার ফিরিয়ে আনতে এটি আপনাকে MediaControllerCompat.getMediaController() কল করার অনুমতি দেয়।

নিচের কোড স্যাম্পেল থেকে onConnected() পদ্ধতি কীভাবে পরিবর্তন করতে হয় তা দেখানো হয়েছে।

Kotlin

private val connectionCallbacks = object : MediaBrowserCompat.ConnectionCallback() {
    override fun onConnected() {

        // Get the token for the MediaSession
        mediaBrowser.sessionToken.also { token ->

            // Create a MediaControllerCompat
            val mediaController = MediaControllerCompat(
                    this@MediaPlayerActivity, // Context
                    token
            )

            // Save the controller
            MediaControllerCompat.setMediaController(this@MediaPlayerActivity, mediaController)
        }

        // Finish building the UI
        buildTransportControls()
    }

    override fun onConnectionSuspended() {
        // The Service has crashed. Disable transport controls until it automatically reconnects
    }

    override fun onConnectionFailed() {
        // The Service has refused our connection
    }
}

জাভা

private final MediaBrowserCompat.ConnectionCallback connectionCallbacks =
  new MediaBrowserCompat.ConnectionCallback() {
    @Override
    public void onConnected() {

      // Get the token for the MediaSession
      MediaSessionCompat.Token token = mediaBrowser.getSessionToken();

      // Create a MediaControllerCompat
      MediaControllerCompat mediaController =
        new MediaControllerCompat(MediaPlayerActivity.this, // Context
        token);

      // Save the controller
      MediaControllerCompat.setMediaController(MediaPlayerActivity.this, mediaController);

      // Finish building the UI
      buildTransportControls();
    }

    @Override
    public void onConnectionSuspended() {
      // The Service has crashed. Disable transport controls until it automatically reconnects
    }

    @Override
    public void onConnectionFailed() {
      // The Service has refused our connection
    }
  };

মিডিয়া কন্ট্রোলারের সাথে আপনার UI কানেক্ট করুন

উপরে দেওয়া ConnectionCallback স্যাম্পেল কোডে, আপনার UI-কে আরও আকর্ষণীয় করে তুলতে buildTransportControls()-এ একটি কল অন্তর্ভুক্ত করা হয়েছে। প্লেয়ার কন্ট্রোল করে এমন UI এলিমেন্টের জন্য আপনাকে onClickListeners সেট করতে হবে। প্রত্যেকটির জন্য উপযুক্ত MediaControllerCompat.TransportControls পদ্ধতি বেছে নিন।

আপনার কোডটি দেখতে এইরকম হবে, প্রতিটি বোতামের জন্য একটি onClickListener সহ:

Kotlin

fun buildTransportControls() {
    val mediaController = MediaControllerCompat.getMediaController(this@MediaPlayerActivity)
    // Grab the view for the play/pause button
    playPause = findViewById<ImageView>(R.id.play_pause).apply {
        setOnClickListener {
            // Since this is a play/pause button, you'll need to test the current state
            // and choose the action accordingly

            val pbState = mediaController.playbackState.state
            if (pbState == PlaybackStateCompat.STATE_PLAYING) {
                mediaController.transportControls.pause()
            } else {
                mediaController.transportControls.play()
            }
        }
    }

    // Display the initial state
    val metadata = mediaController.metadata
    val pbState = mediaController.playbackState

    // Register a Callback to stay in sync
    mediaController.registerCallback(controllerCallback)
}

জাভা

void buildTransportControls()
{
  // Grab the view for the play/pause button
  playPause = (ImageView) findViewById(R.id.play_pause);

  // Attach a listener to the button
  playPause.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
      // Since this is a play/pause button, you'll need to test the current state
      // and choose the action accordingly

      int pbState = MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getPlaybackState().getState();
      if (pbState == PlaybackStateCompat.STATE_PLAYING) {
        MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getTransportControls().pause();
      } else {
        MediaControllerCompat.getMediaController(MediaPlayerActivity.this).getTransportControls().play();
      }
  });

  MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(MediaPlayerActivity.this);

  // Display the initial state
  MediaMetadataCompat metadata = mediaController.getMetadata();
  PlaybackStateCompat pbState = mediaController.getPlaybackState();

  // Register a Callback to stay in sync
  mediaController.registerCallback(controllerCallback);
}
}

TransportControls পদ্ধতি আপনার পরিষেবার মিডিয়া সেশনে কলব্যাক পাঠায়। প্রতিটি কন্ট্রোলের জন্য আপনি সংশ্লিষ্ট MediaSessionCompat.Callback পদ্ধতি নির্ধারণ করেছেন কিনা তা নিশ্চিত করুন।

মিডিয়া সেশনের সাথে সিঙ্ক করে থাকুন

UI-তে মিডিয়া সেশনের বর্তমান অবস্থা দেখানো উচিত, যেমনটি PlaybackState ও মেটাডেটায় বর্ণনা করা হয়েছে। আপনি ট্রান্সপোর্ট কন্ট্রোল তৈরি করার সময়, সেশনের বর্তমান অবস্থা দেখতে, আপনার UI-তে তা দেখাতে এবং অবস্থা ও উপলভ্য অ্যাকশনের উপর ভিত্তি করে ট্রান্সপোর্ট কন্ট্রোল চালু ও বন্ধ করতে পারবেন।

মিডিয়া সেশনের স্ট্যাটাস বা মেটাডেটা পরিবর্তন হলে প্রতিবার কলব্যাক পেতে, এই দুটি পদ্ধতি সহ MediaControllerCompat.Callback সংজ্ঞায়িত করুন:

Kotlin

private var controllerCallback = object : MediaControllerCompat.Callback() {

    override fun onMetadataChanged(metadata: MediaMetadataCompat?) {}

    override fun onPlaybackStateChanged(state: PlaybackStateCompat?) {}
}

জাভা

MediaControllerCompat.Callback controllerCallback =
  new MediaControllerCompat.Callback() {
    @Override
    public void onMetadataChanged(MediaMetadataCompat metadata) {}

    @Override
    public void onPlaybackStateChanged(PlaybackStateCompat state) {}
  };

আপনি ট্রান্সপোর্ট কন্ট্রোল তৈরি করার সময় কলব্যাক রেজিস্টার করুন (buildTransportControls() পদ্ধতি দেখুন) এবং অ্যাক্টিভিটি বন্ধ হয়ে গেলে এটি আনরেজিস্টার করুন (অ্যাক্টিভিটির onStop() লাইফসাইকেল পদ্ধতিতে)।

মিডিয়া সেশন শেষ হয়ে গেলে ডিসকানেক্ট করুন

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

তাই, সেশন নষ্ট হয়ে গেলে, আপনাকে disconnect() কল করে MediaBrowserService থেকে অবশ্যই ডিসকানেক্ট করতে হবে। এটি নিশ্চিত করে যে ব্রাউজার পরিষেবার কোনও বাউন্ড ক্লায়েন্ট নেই এবং OS-এর মাধ্যমে নষ্ট করা যেতে পারে। আপনাকে পরে MediaBrowserService-এর সাথে আবার কানেক্ট করতে হলে (যেমন, আপনার অ্যাপ্লিকেশন মিডিয়া অ্যাপের সাথে স্থায়ী কানেকশন বজায় রাখতে চাইলে), পুরনোটি আবার ব্যবহার করার পরিবর্তে MediaBrowser-এর নতুন ইনস্ট্যান্স তৈরি করুন।

নিম্নলিখিত কোড স্নিপেট একটি কলব্যাক ইমপ্লিমেন্টেশন দেখায় যা মিডিয়া সেশন নষ্ট হয়ে গেলে ব্রাউজার পরিষেবা থেকে ডিসকানেক্ট করে দেয়:

Kotlin

private var controllerCallback = object : MediaControllerCompat.Callback() {
    override fun onSessionDestroyed() {
      mediaBrowser.disconnect()
      // maybe schedule a reconnection using a new MediaBrowser instance
    }
}

জাভা

MediaControllerCompat.Callback controllerCallback =
  new MediaControllerCompat.Callback() {
    @Override
    public void onSessionDestroyed() {
      mediaBrowser.disconnect();
      // maybe schedule a reconnection using a new MediaBrowser instance
    }
  };