আপনার অ্যান্ড্রয়েড অ্যাপে উন্নত বৈশিষ্ট্য যোগ করুন

বিজ্ঞাপন বিরতি

Android প্রেরক SDK একটি প্রদত্ত মিডিয়া স্ট্রীমের মধ্যে বিজ্ঞাপন বিরতি এবং সহচর বিজ্ঞাপনগুলির জন্য সমর্থন প্রদান করে৷

অ্যাড ব্রেকগুলি কীভাবে কাজ করে সে সম্পর্কে আরও তথ্যের জন্য ওয়েব রিসিভার অ্যাড ব্রেকস ওভারভিউ দেখুন৷

যদিও প্রেরক এবং প্রাপক উভয়ের জন্য বিরতি নির্দিষ্ট করা যেতে পারে, তবে প্ল্যাটফর্ম জুড়ে সামঞ্জস্যপূর্ণ আচরণ বজায় রাখতে তাদের জন্য ওয়েব রিসিভার এবং অ্যান্ড্রয়েড টিভি রিসিভারে নির্দিষ্ট করার পরামর্শ দেওয়া হয়।

অ্যান্ড্রয়েডে, AdBreakClipInfo এবং AdBreakInfo ব্যবহার করে একটি লোড কমান্ডে বিজ্ঞাপন বিরতি নির্দিষ্ট করুন:

কোটলিন
val breakClip1: AdBreakClipInfo =
    AdBreakClipInfo.Builder("bc0")
        .setTitle("Clip title")
        .setPosterUrl("https://www.some.url")
        .setDuration(60000)
        .setWhenSkippableInMs(5000)  // Set this field so that the ad is skippable
        .build()

val breakClip2: AdBreakClipInfo = …
val breakClip3: AdBreakClipInfo = …

val break1: AdBreakClipInfo =
    AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000)
        .setId("b0")
        .setBreakClipIds({"bc0","bc1","bc2"})
        …
        .build()

val mediaInfo: MediaInfo = MediaInfo.Builder()
    …
    .setAdBreaks({break1})
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .build()

val mediaLoadRequestData: MediaLoadRequestData = MediaInfo.Builder()
    …
    .setMediaInfo(mediaInfo)
    .build()

remoteMediaClient.load(mediaLoadRequestData)
জাভা
AdBreakClipInfo breakClip1 =
    new AdBreakClipInfo.Builder("bc0")
        .setTitle("Clip title")
        .setPosterUrl("https://www.some.url")
        .setDuration(60000)
        .setWhenSkippableInMs(5000)  // Set this field so that the ad is skippable
        .build();

AdBreakClipInfo breakClip2 = …
AdBreakClipInfo breakClip3 = …

AdBreakInfo break1 =
    new AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000)
        .setId("b0")
        .setBreakClipIds({"bc0","bc1","bc2"})
        …
        .build();

MediaInfo mediaInfo = new MediaInfo.Builder()
    …
    .setAdBreaks({break1})
    .setAdBreakClips({breakClip1, breakClip2, breakClip3})
    .build();

MediaLoadRequestData mediaLoadRequestData = new MediaInfo.Builder()
    …
    .setMediaInfo(mediaInfo)
    .build();

remoteMediaClient.load(mediaLoadRequestData);

কাস্টম অ্যাকশন যোগ করুন

একটি প্রেরক অ্যাপ কাস্টম অ্যাকশন পরিচালনা করতে বা এর আচরণ ওভাররাইড করতে MediaIntentReceiver প্রসারিত করতে পারে। আপনি যদি নিজের MediaIntentReceiver প্রয়োগ করে থাকেন, তাহলে আপনাকে এটিকে ম্যানিফেস্টে যোগ করতে হবে এবং CastMediaOptions এ এর নামও সেট করতে হবে। এই উদাহরণটি কাস্টম ক্রিয়াগুলি সরবরাহ করে যা রিমোট মিডিয়া প্লেব্যাক টগল, মিডিয়া বোতাম টিপে এবং অন্যান্য ধরণের ক্রিয়াগুলিকে ওভাররাইড করে৷

// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
কোটলিন
// In your OptionsProvider
var mediaOptions = CastMediaOptions.Builder()
    .setMediaIntentReceiverClassName(MyMediaIntentReceiver::class.java.name)
    .build()

// Implementation of MyMediaIntentReceiver
internal class MyMediaIntentReceiver : MediaIntentReceiver() {
    override fun onReceiveActionTogglePlayback(currentSession: Session) {
    }

    override fun onReceiveActionMediaButton(currentSession: Session, intent: Intent) {
    }

    override fun onReceiveOtherAction(context: Context?, action: String, intent: Intent) {
    }
}
জাভা
// In your OptionsProvider
CastMediaOptions mediaOptions = new CastMediaOptions.Builder()
        .setMediaIntentReceiverClassName(MyMediaIntentReceiver.class.getName())
        .build();

// Implementation of MyMediaIntentReceiver
class MyMediaIntentReceiver extends MediaIntentReceiver {
    @Override
    protected void onReceiveActionTogglePlayback(Session currentSession) {
    }

    @Override
    protected void onReceiveActionMediaButton(Session currentSession, Intent intent) {
    }

    @Override
    protected void onReceiveOtherAction(Context context, String action, Intent intent) {
    }
}

একটি কাস্টম চ্যানেল যোগ করুন

প্রেরক অ্যাপটি রিসিভার অ্যাপের সাথে যোগাযোগ করতে, আপনার অ্যাপটিকে একটি কাস্টম চ্যানেল তৈরি করতে হবে। প্রেরক রিসিভারকে স্ট্রিং বার্তা পাঠাতে কাস্টম চ্যানেল ব্যবহার করতে পারেন। প্রতিটি কাস্টম চ্যানেল একটি অনন্য নামস্থান দ্বারা সংজ্ঞায়িত করা হয় এবং অবশ্যই urn:x-cast: উপসর্গ দিয়ে শুরু করতে হবে, উদাহরণস্বরূপ, urn:x-cast:com.example.custom । একাধিক কাস্টম চ্যানেল থাকা সম্ভব, প্রতিটিতে একটি অনন্য নামস্থান রয়েছে। রিসিভার অ্যাপ একই নামস্থান ব্যবহার করে বার্তা পাঠাতে ও গ্রহণ করতে পারে।

কাস্টম চ্যানেলটি Cast.MessageReceivedCallback ইন্টারফেসের সাথে প্রয়োগ করা হয়েছে:

কোটলিন
class HelloWorldChannel : MessageReceivedCallback {
    val namespace: String
        get() = "urn:x-cast:com.example.custom"

    override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) {
        Log.d(TAG, "onMessageReceived: $message")
    }
}
জাভা
class HelloWorldChannel implements Cast.MessageReceivedCallback {
    public String getNamespace() {
        return "urn:x-cast:com.example.custom";
    }
    @Override
    public void onMessageReceived(CastDevice castDevice, String namespace, String message) {
        Log.d(TAG, "onMessageReceived: " + message);
    }
}

একবার প্রেরক অ্যাপটি রিসিভার অ্যাপের সাথে সংযুক্ত হয়ে গেলে, setMessageReceivedCallbacks পদ্ধতি ব্যবহার করে কাস্টম চ্যানেল তৈরি করা যেতে পারে:

কোটলিন
try {
    mCastSession.setMessageReceivedCallbacks(
        mHelloWorldChannel.namespace,
        mHelloWorldChannel)
} catch (e: IOException) {
    Log.e(TAG, "Exception while creating channel", e)
}
জাভা
try {
    mCastSession.setMessageReceivedCallbacks(
            mHelloWorldChannel.getNamespace(),
            mHelloWorldChannel);
} catch (IOException e) {
    Log.e(TAG, "Exception while creating channel", e);
}

একবার কাস্টম চ্যানেল তৈরি হয়ে গেলে, প্রেরক সেই চ্যানেলে রিসিভারকে স্ট্রিং বার্তা পাঠাতে sendMessage পদ্ধতি ব্যবহার করতে পারেন:

কোটলিন
private fun sendMessage(message: String) {
    if (mHelloWorldChannel != null) {
        try {
            mCastSession.sendMessage(mHelloWorldChannel.namespace, message)
                .setResultCallback { status ->
                    if (!status.isSuccess) {
                        Log.e(TAG, "Sending message failed")
                    }
                }
        } catch (e: Exception) {
            Log.e(TAG, "Exception while sending message", e)
        }
    }
}
জাভা
private void sendMessage(String message) {
    if (mHelloWorldChannel != null) {
        try {
            mCastSession.sendMessage(mHelloWorldChannel.getNamespace(), message)
                .setResultCallback( status -> {
                    if (!status.isSuccess()) {
                        Log.e(TAG, "Sending message failed");
                    }
                });
        } catch (Exception e) {
            Log.e(TAG, "Exception while sending message", e);
        }
    }
}

অটোপ্লে সমর্থন করে

অটোপ্লে এবং সারিবদ্ধ APIs বিভাগটি দেখুন।

UX উইজেটের জন্য চিত্র নির্বাচন ওভাররাইড করুন

ফ্রেমওয়ার্কের বিভিন্ন উপাদান (যেমন কাস্ট ডায়ালগ, মিনি কন্ট্রোলার, এবং UIMediaController, যদি তাই কনফিগার করা থাকে) বর্তমানে কাস্টিং মিডিয়ার জন্য আর্টওয়ার্ক প্রদর্শন করবে। ছবির আর্টওয়ার্কের URLগুলি সাধারণত মিডিয়ার জন্য MediaMetadata তে অন্তর্ভুক্ত করা হয়, তবে প্রেরক অ্যাপের URLগুলির জন্য একটি বিকল্প উত্স থাকতে পারে৷

ImagePicker ক্লাস একটি MediaMetadata তে ছবির তালিকা থেকে একটি উপযুক্ত ছবি নির্বাচন করার জন্য একটি উপায় সংজ্ঞায়িত করে, ছবির ব্যবহারের উপর ভিত্তি করে, উদাহরণস্বরূপ, বিজ্ঞপ্তি থাম্বনেল বা পূর্ণ স্ক্রীন ব্যাকগ্রাউন্ড। ডিফল্ট ImagePicker ইমপ্লিমেন্টেশন সর্বদা প্রথম ইমেজ বেছে নেয়, অথবা MediaMetadata কোন ইমেজ পাওয়া না গেলে নাল রিটার্ন করে। আপনার অ্যাপ ImagePicker সাবক্লাস করতে পারে এবং একটি বিকল্প বাস্তবায়ন প্রদান করতে onPickImage(MediaMetadata, ImageHints) পদ্ধতিটিকে ওভাররাইড করতে পারে এবং তারপর CastMediaOptions.Builder এর setImagePicker পদ্ধতির সাথে সেই সাবক্লাসটি নির্বাচন করতে পারে। ImageHints একটি ImagePicker UI-তে প্রদর্শনের জন্য নির্বাচন করা ছবির ধরন এবং আকার সম্পর্কে ইঙ্গিত প্রদান করে।

কাস্ট ডায়ালগ কাস্টমাইজ করা হচ্ছে

সেশন লাইফসাইকেল পরিচালনা

SessionManager হল সেশন লাইফসাইকেল পরিচালনার কেন্দ্রীয় স্থান। SessionManager সেশন শুরু, পুনরায় শুরু এবং শেষ করতে Android MediaRouter রুট নির্বাচনের অবস্থার পরিবর্তনগুলি শোনে। যখন একটি রুট নির্বাচন করা হয়, SessionManager একটি Session অবজেক্ট তৈরি করবে এবং এটি শুরু বা পুনরায় শুরু করার চেষ্টা করবে। যখন একটি রুট অনির্বাচিত হয়, SessionManager বর্তমান সেশন শেষ করবে।

অতএব, SessionManager সঠিকভাবে সেশন লাইফসাইকেল পরিচালনা করে তা নিশ্চিত করতে, আপনাকে অবশ্যই নিশ্চিত করতে হবে যে:

আপনি কীভাবে কাস্ট ডায়ালগ তৈরি করেন তার উপর নির্ভর করে, অতিরিক্ত ক্রিয়াগুলি করা প্রয়োজন হতে পারে:

  • আপনি যদি MediaRouteChooserDialog এবং MediaRouteControllerDialog ব্যবহার করে কাস্ট ডায়ালগ তৈরি করেন, তাহলে এই ডায়ালগগুলি MediaRouter এ স্বয়ংক্রিয়ভাবে রুট নির্বাচন আপডেট করবে, তাই কিছুই করার দরকার নেই৷
  • আপনি যদি CastButtonFactory.setUpMediaRouteButton(Context, Menu, int) বা CastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton) ব্যবহার করে আপনার কাস্ট বোতাম সেট আপ করেন, তাহলে ডায়ালগগুলি আসলে MediaRouteChooserDialog ব্যবহার করে তৈরি করা হয়, তাই MediaRouteControllerDialog কিছু করার দরকার নেই।
  • অন্যান্য ক্ষেত্রে, আপনি কাস্টম কাস্ট ডায়ালগ তৈরি করবেন, তাই MediaRouter এ রুট নির্বাচনের অবস্থা আপডেট করতে আপনাকে উপরের নির্দেশাবলী অনুসরণ করতে হবে।

জিরো ডিভাইস স্টেট

আপনি যদি কাস্টম কাস্ট ডায়ালগ তৈরি করেন, আপনার কাস্টম MediaRouteChooserDialog সঠিকভাবে শূন্য ডিভাইস খুঁজে পাওয়ার ক্ষেত্রে পরিচালনা করবে৷ ডায়ালগে এমন সূচক থাকা উচিত যা আপনার ব্যবহারকারীদের কাছে স্পষ্ট করে দেয় যখন আপনার অ্যাপ এখনও ডিভাইসগুলি খুঁজে বের করার চেষ্টা করছে এবং যখন আবিষ্কারের প্রচেষ্টা আর সক্রিয় থাকে না।

আপনি যদি ডিফল্ট MediaRouteChooserDialog ব্যবহার করেন, তাহলে শূন্য ডিভাইসের অবস্থা ইতিমধ্যেই পরিচালনা করা হয়েছে।

পরবর্তী পদক্ষেপ

এটি এমন বৈশিষ্ট্যগুলিকে সমাপ্ত করে যা আপনি আপনার Android প্রেরক অ্যাপে যোগ করতে পারেন৷ আপনি এখন অন্য প্ল্যাটফর্মের জন্য একটি প্রেরক অ্যাপ তৈরি করতে পারেন ( iOS বা ওয়েব ), অথবা একটি ওয়েব রিসিভার অ্যাপ তৈরি করতে পারেন।