1. بررسی اجمالی
این کد لبه به شما می آموزد که چگونه یک برنامه ویدیویی موجود در اندروید را برای ارسال محتوا در یک دستگاه دارای Google Cast تغییر دهید.
Google Cast چیست؟
Google Cast به کاربران امکان می دهد محتوا را از دستگاه تلفن همراه به تلویزیون ارسال کنند. سپس کاربران می توانند از دستگاه تلفن همراه خود به عنوان یک کنترل از راه دور برای پخش رسانه در تلویزیون استفاده کنند.
Google Cast SDK به شما امکان می دهد برنامه خود را برای کنترل تلویزیون یا سیستم صوتی گسترش دهید. Cast SDK به شما امکان می دهد اجزای رابط کاربری لازم را بر اساس چک لیست طراحی Google Cast اضافه کنید.
چک لیست طراحی Google Cast برای ساده و قابل پیش بینی کردن تجربه کاربر Cast در همه پلتفرم های پشتیبانی شده ارائه شده است.
قرار است چه چیزی بسازیم؟
پس از تکمیل این کد لبه، یک برنامه ویدیویی Android خواهید داشت که میتواند ویدیوها را به دستگاهی با قابلیت Google Cast ارسال کند.
چیزی که یاد خواهید گرفت
- چگونه Google Cast SDK را به یک برنامه ویدیویی نمونه اضافه کنیم.
- نحوه اضافه کردن دکمه Cast برای انتخاب دستگاه Google Cast.
- نحوه اتصال به دستگاه Cast و راه اندازی گیرنده رسانه.
- نحوه پخش ویدیو
- چگونه مینی کنترلر Cast را به برنامه خود اضافه کنید.
- نحوه پشتیبانی از اعلانهای رسانه و کنترلهای صفحه قفل
- نحوه اضافه کردن یک کنترلر توسعه یافته
- نحوه ارائه یک پوشش مقدماتی
- چگونه ویجتهای Cast را سفارشی کنیم.
- نحوه ادغام با Cast Connect
آنچه شما نیاز دارید
- جدیدترین Android SDK .
- اندروید استودیو نسخه 3.2+
- یک دستگاه تلفن همراه با Android 4.1+ Jelly Bean (سطح API 16).
- یک کابل داده USB برای اتصال دستگاه تلفن همراه به رایانه توسعه.
- یک دستگاه Google Cast مانند Chromecast یا Android TV که با دسترسی به اینترنت پیکربندی شده است.
- تلویزیون یا مانیتور با ورودی HDMI.
- برای آزمایش ادغام Cast Connect به Chromecast با Google TV نیاز است، اما برای بقیه Codelab اختیاری است. اگر یکی ندارید، در پایان این آموزش از مرحله Add Cast Connect Support رد شوید.
تجربه کنید
- شما باید دانش قبلی کاتلین و توسعه اندروید را داشته باشید.
- شما همچنین به دانش قبلی در مورد تماشای تلویزیون نیاز دارید :)
چگونه از این آموزش استفاده خواهید کرد؟
به تجربه خود از ساخت اپلیکیشن های اندرویدی چه امتیازی می دهید؟
تجربه خود را از تماشای تلویزیون چگونه ارزیابی می کنید؟
2. کد نمونه را دریافت کنید
می توانید تمام کدهای نمونه را در رایانه خود دانلود کنید ...
و فایل فشرده دانلود شده را باز کنید.
3. برنامه نمونه را اجرا کنید
ابتدا، بیایید ببینیم که برنامه نمونه تکمیل شده چگونه به نظر می رسد. این برنامه یک پخش کننده ویدیوی اساسی است. کاربر می تواند یک ویدیو را از یک لیست انتخاب کند و سپس می تواند ویدیو را به صورت محلی در دستگاه پخش کند یا آن را به دستگاه Google Cast ارسال کند.
با دانلود کد، دستورالعمل های زیر نحوه باز کردن و اجرای برنامه نمونه تکمیل شده در Android Studio را شرح می دهد:
Import Project را در صفحه خوش آمدگویی یا گزینه های منو File > New > Import Project... را انتخاب کنید.
را انتخاب کنید دایرکتوری
app-done
از پوشه کد نمونه و روی OK کلیک کنید.
روی فایل > کلیک کنید همگام سازی پروژه با فایل های Gradle .
اشکال زدایی USB را در دستگاه Android خود فعال کنید - در اندروید 4.2 و بالاتر، صفحه گزینه های برنامه نویس به طور پیش فرض پنهان است. برای اینکه آن را قابل مشاهده کنید، به Settings > About phone بروید و هفت بار روی Build number ضربه بزنید. به صفحه قبلی بازگردید، به System > Advanced بروید و روی Developer options نزدیک پایین ضربه بزنید، سپس روی USB debugging ضربه بزنید تا روشن شود.
دستگاه اندروید خود را وصل کنید و روی آن کلیک کنید دکمه اجرا در اندروید استودیو. پس از چند ثانیه باید ببینید که برنامه ویدیویی با نام Cast Videos ظاهر می شود.
روی دکمه Cast در برنامه ویدیو کلیک کنید و دستگاه Google Cast خود را انتخاب کنید.
یک ویدیو را انتخاب کنید و روی دکمه پخش کلیک کنید.
پخش ویدیو در دستگاه Google Cast شما شروع می شود.
کنترل کننده گسترش یافته نمایش داده می شود. می توانید از دکمه پخش/مکث برای کنترل پخش استفاده کنید.
به لیست ویدیوها برگردید.
اکنون یک مینی کنترلر در پایین صفحه قابل مشاهده است.
روی دکمه مکث در کنترلر کوچک کلیک کنید تا ویدیو روی گیرنده متوقف شود. برای ادامه پخش مجدد ویدیو، روی دکمه پخش در مینی کنترلر کلیک کنید.
روی دکمه هوم دستگاه موبایل کلیک کنید. اعلانها را پایین بکشید و اکنون باید یک اعلان برای جلسه Cast ببینید.
تلفن خود را قفل کنید و وقتی قفل آن را باز می کنید، باید اعلانی را روی صفحه قفل مشاهده کنید تا پخش رسانه را کنترل کنید یا ارسال را متوقف کنید.
به برنامه ویدیو برگردید و روی دکمه Cast کلیک کنید تا ارسال محتوا در دستگاه Google Cast متوقف شود.
سوالات متداول
4. پروژه شروع را آماده کنید
باید پشتیبانی از Google Cast را به برنامه شروعی که دانلود کردید اضافه کنیم. در اینجا برخی از اصطلاحات Google Cast وجود دارد که در این لبه کد استفاده خواهیم کرد:
- یک برنامه فرستنده روی دستگاه تلفن همراه یا لپ تاپ اجرا می شود،
- یک برنامه گیرنده در دستگاه Google Cast اجرا می شود.
اکنون شما آماده هستید تا با استفاده از Android Studio روی پروژه شروع کننده ایجاد کنید:
- را انتخاب کنید
دایرکتوری
app-start
از دانلود کد نمونه خود ( وارد کردن پروژه را در صفحه خوش آمدگویی یا گزینه منو File > New > Import Project... را انتخاب کنید). - را کلیک کنید
همگام سازی پروژه با دکمه Gradle Files .
- را کلیک کنید
دکمه اجرا برای اجرای برنامه و کاوش در رابط کاربری.
طراحی اپلیکیشن
این برنامه لیستی از ویدیوها را از یک وب سرور راه دور دریافت می کند و فهرستی را برای مرورگر در اختیار کاربر قرار می دهد. کاربران می توانند یک ویدیو را برای دیدن جزئیات انتخاب کنند یا ویدیو را به صورت محلی در دستگاه تلفن همراه پخش کنند.
این برنامه از دو فعالیت اصلی تشکیل شده است: VideoBrowserActivity
و LocalPlayerActivity
. برای ادغام عملکرد Google Cast، Activities باید از AppCompatActivity
یا از والد آن FragmentActivity
به ارث برده شود. این محدودیت وجود دارد زیرا ما باید MediaRouteButton
(ارائه شده در کتابخانه پشتیبانی MediaRouter ) را به عنوان MediaRouteActionProvider
اضافه کنیم و این فقط در صورتی کار می کند که فعالیت از کلاس های ذکر شده در بالا به ارث برده شود. کتابخانه پشتیبانی MediaRouter به کتابخانه پشتیبانی AppCompat بستگی دارد که کلاس های مورد نیاز را ارائه می دهد.
VideoBrowserActivity
این فعالیت حاوی یک Fragment
( VideoBrowserFragment
) است. این لیست توسط یک ArrayAdapter
( VideoListAdapter
) پشتیبانی می شود. لیست ویدیوها و ابرداده مرتبط با آنها در یک سرور راه دور به عنوان یک فایل JSON میزبانی می شود. یک AsyncTaskLoader
( VideoItemLoader
) این JSON را واکشی می کند و آن را پردازش می کند تا لیستی از اشیاء MediaItem
بسازد.
یک شی MediaItem
یک ویدیو و ابرداده مرتبط با آن، مانند عنوان، توضیحات، URL برای جریان، URL برای تصاویر پشتیبان، و تراکهای متن مرتبط (برای زیرنویسها) در صورت وجود، مدل میکند. شی MediaItem
بین اکتیویتی ها ارسال می شود، بنابراین MediaItem
روش های کاربردی برای تبدیل آن به Bundle
و بالعکس دارد.
هنگامی که لودر لیست MediaItems
را می سازد، آن لیست را به VideoListAdapter
ارسال می کند که سپس لیست MediaItems
را در VideoBrowserFragment
ارائه می کند. به کاربر لیستی از تصاویر کوچک ویدیو با توضیحات کوتاه برای هر ویدیو ارائه می شود. هنگامی که یک مورد انتخاب می شود، MediaItem
مربوطه به یک Bundle
تبدیل می شود و به LocalPlayerActivity
ارسال می شود.
LocalPlayerActivity
این فعالیت فراداده مربوط به یک ویدیوی خاص را نمایش می دهد و به کاربر اجازه می دهد ویدیو را به صورت محلی در دستگاه تلفن همراه پخش کند.
این فعالیت میزبان یک VideoView
، برخی از کنترلهای رسانه، و یک ناحیه متنی برای نمایش توضیحات ویدیوی انتخابی است. پخش کننده قسمت بالای صفحه را پوشش می دهد و فضایی را برای توضیحات دقیق ویدیو در زیر باز می کند. کاربر می تواند پخش/مکث کند یا به دنبال پخش محلی ویدیوها باشد.
وابستگی ها
از آنجایی که ما از AppCompatActivity
استفاده می کنیم، به کتابخانه پشتیبانی AppCompat نیاز داریم. برای مدیریت لیست ویدیوها و دریافت ناهمزمان تصاویر لیست، از کتابخانه Volley استفاده می کنیم.
سوالات متداول
5. افزودن دکمه Cast
یک برنامه با قابلیت Cast دکمه Cast را در هر یک از فعالیت های خود نمایش می دهد. با کلیک بر روی دکمه Cast، لیستی از دستگاههای Cast که کاربر میتواند انتخاب کند، نمایش داده میشود. اگر کاربر در دستگاه فرستنده محتوا را به صورت محلی پخش می کرد، انتخاب دستگاه Cast پخش را در آن دستگاه Cast شروع یا از سر می گیرد. در هر زمانی در طول جلسه Cast، کاربر میتواند روی دکمه Cast کلیک کرده و ارسال برنامه شما به دستگاه Cast را متوقف کند. همانطور که در چک لیست طراحی Google Cast توضیح داده شده است، کاربر باید بتواند هنگام انجام هر فعالیتی از برنامه شما به دستگاه Cast متصل شود یا از آن جدا شود.
وابستگی ها
فایل app build.gradle را بهروزرسانی کنید تا وابستگیهای کتابخانه لازم را شامل شود:
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.mediarouter:mediarouter:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
implementation 'com.android.volley:volley:1.2.1'
implementation "androidx.core:core-ktx:1.8.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
پروژه را همگامسازی کنید تا ساختهای پروژه بدون خطا تأیید شود.
مقداردهی اولیه
چارچوب Cast دارای یک شی تکتنی جهانی به CastContext
است که همه تعاملات Cast را هماهنگ میکند.
شما باید رابط OptionsProvider
را برای تامین CastOptions
مورد نیاز برای مقداردهی اولیه CastContext
singleton پیاده سازی کنید. مهمترین گزینه شناسه برنامه گیرنده است که برای فیلتر کردن نتایج کشف دستگاه Cast و راه اندازی برنامه گیرنده هنگام شروع جلسه Cast استفاده می شود.
هنگامی که برنامه خود را با قابلیت Cast خود توسعه می دهید، باید به عنوان توسعه دهنده Cast ثبت نام کنید و سپس یک شناسه برنامه برای برنامه خود دریافت کنید. برای این کد لبه، از یک شناسه برنامه نمونه استفاده خواهیم کرد.
فایل جدید CastOptionsProvider.kt
زیر را به بسته com.google.sample.cast.refplayer
پروژه اضافه کنید:
package com.google.sample.cast.refplayer
import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider
class CastOptionsProvider : OptionsProvider {
override fun getCastOptions(context: Context): CastOptions {
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.build()
}
override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
return null
}
}
اکنون OptionsProvider
در تگ " application
" برنامه AndroidManifest.xml
اعلام کنید:
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
با تنبلی CastContext
را در متد VideoBrowserActivity
onCreate مقداردهی کنید:
import com.google.android.gms.cast.framework.CastContext
private var mCastContext: CastContext? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.video_browser)
setupActionBar()
mCastContext = CastContext.getSharedInstance(this)
}
همان منطق اولیه سازی را به LocalPlayerActivity
اضافه کنید.
دکمه Cast
اکنون که CastContext
مقداردهی اولیه شده است، باید دکمه Cast را اضافه کنیم تا کاربر بتواند یک دستگاه Cast را انتخاب کند. دکمه Cast توسط MediaRouteButton
از کتابخانه پشتیبانی MediaRouter پیاده سازی شده است. مانند هر نماد عملی که می توانید به فعالیت خود اضافه کنید (با استفاده از ActionBar
یا Toolbar
)، ابتدا باید آیتم منوی مربوطه را به منوی خود اضافه کنید.
فایل res/menu/browse.xml
را ویرایش کنید و آیتم MediaRouteActionProvider
را در منو قبل از آیتم تنظیمات اضافه کنید:
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
با استفاده از CastButtonFactory
برای اتصال MediaRouteButton
به چارچوب Cast، روش onCreateOptionsMenu()
از VideoBrowserActivity
نادیده بگیرید:
import com.google.android.gms.cast.framework.CastButtonFactory
private var mediaRouteMenuItem: MenuItem? = null
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.browse, menu)
mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
R.id.media_route_menu_item)
return true
}
به روشی مشابه، onCreateOptionsMenu
در LocalPlayerActivity
لغو کنید.
را کلیک کنید دکمه اجرا برای اجرای برنامه در دستگاه تلفن همراه شما. باید یک دکمه Cast را در نوار عملکرد برنامه ببینید و وقتی روی آن کلیک میکنید، دستگاههای Cast را در شبکه محلی شما فهرست میکند. کشف دستگاه به طور خودکار توسط
CastContext
مدیریت می شود. دستگاه Cast خود را انتخاب کنید و برنامه گیرنده نمونه در دستگاه Cast بارگیری میشود. می توانید بین فعالیت مرور و فعالیت پخش کننده محلی حرکت کنید و وضعیت دکمه Cast همگام نگه داشته می شود.
ما هیچ پشتیبانی برای پخش رسانه وصل نکردهایم، بنابراین هنوز نمیتوانید ویدیوها را در دستگاه Cast پخش کنید. برای قطع ارتباط روی دکمه Cast کلیک کنید.
6. پخش محتوای ویدیویی
ما برنامه نمونه را گسترش میدهیم تا ویدیوها را از راه دور در دستگاه Cast پخش کند. برای انجام این کار، باید به رویدادهای مختلف تولید شده توسط چارچوب Cast گوش دهیم.
رسانه ریخته گری
در سطح بالا، اگر میخواهید رسانهای را در دستگاه Cast پخش کنید، باید این کارها را انجام دهید:
- یک شی
MediaInfo
ایجاد کنید که یک آیتم رسانه را مدل می کند. - به دستگاه Cast متصل شوید و برنامه گیرنده خود را راه اندازی کنید.
- شی
MediaInfo
را در گیرنده خود بارگذاری کنید و محتوا را پخش کنید. - وضعیت رسانه را پیگیری کنید.
- دستورات پخش را بر اساس تعاملات کاربر به گیرنده ارسال کنید.
ما قبلاً مرحله 2 را در بخش قبل انجام داده ایم. انجام مرحله 3 با چارچوب Cast آسان است. مرحله 1 معادل نگاشت یک شی به شی دیگر است. MediaInfo
چیزی است که چارچوب Cast آن را درک می کند و MediaItem
محفظه برنامه ما برای یک آیتم رسانه است. ما به راحتی می توانیم یک MediaItem
را به MediaInfo
نگاشت کنیم.
برنامه نمونه LocalPlayerActivity
از قبل با استفاده از این فهرست، بین پخش محلی و از راه دور تمایز قائل می شود:
private var mLocation: PlaybackLocation? = null
enum class PlaybackLocation {
LOCAL, REMOTE
}
enum class PlaybackState {
PLAYING, PAUSED, BUFFERING, IDLE
}
در این کد لبه برای شما مهم نیست که بدانید دقیقاً چگونه منطق پخش کننده نمونه کار می کند. درک این نکته مهم است که پخش کننده رسانه برنامه شما باید اصلاح شود تا از دو مکان پخش به روشی مشابه آگاه باشد.
در حال حاضر پخش کننده محلی همیشه در حالت پخش محلی است زیرا هنوز چیزی در مورد وضعیت های Casting نمی داند. ما باید رابط کاربری را بر اساس انتقال وضعیتی که در چارچوب Cast اتفاق میافتد، بهروزرسانی کنیم. به عنوان مثال، اگر شروع به ارسال محتوا کنیم، باید پخش محلی را متوقف کنیم و برخی از کنترل ها را غیرفعال کنیم. به طور مشابه، اگر زمانی که در این فعالیت هستیم، بازیگران را متوقف کنیم، باید به پخش محلی منتقل شویم. برای رسیدگی به آن باید به رویدادهای مختلف تولید شده توسط چارچوب Cast گوش دهیم.
مدیریت جلسه بازیگران
برای چارچوب Cast، یک جلسه Cast مراحل اتصال به یک دستگاه، راهاندازی (یا پیوستن)، اتصال به یک برنامه گیرنده، و راهاندازی یک کانال کنترل رسانه را در صورت لزوم ترکیب میکند. کانال کنترل رسانه نحوه ارسال و دریافت پیامها از پخشکننده رسانه گیرنده توسط چارچوب Cast است.
وقتی کاربر دستگاهی را از روی دکمه Cast انتخاب میکند، جلسه Cast بهطور خودکار شروع میشود و وقتی کاربر ارتباط خود را قطع میکند، بهطور خودکار متوقف میشود. اتصال مجدد به جلسه گیرنده به دلیل مشکلات شبکه نیز به طور خودکار توسط Cast SDK انجام می شود.
بیایید یک SessionManagerListener
به LocalPlayerActivity
اضافه کنیم:
import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...
private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...
private fun setupCastListener() {
mSessionManagerListener = object : SessionManagerListener<CastSession> {
override fun onSessionEnded(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
onApplicationConnected(session)
}
override fun onSessionResumeFailed(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionStarted(session: CastSession, sessionId: String) {
onApplicationConnected(session)
}
override fun onSessionStartFailed(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionStarting(session: CastSession) {}
override fun onSessionEnding(session: CastSession) {}
override fun onSessionResuming(session: CastSession, sessionId: String) {}
override fun onSessionSuspended(session: CastSession, reason: Int) {}
private fun onApplicationConnected(castSession: CastSession) {
mCastSession = castSession
if (null != mSelectedMedia) {
if (mPlaybackState == PlaybackState.PLAYING) {
mVideoView!!.pause()
loadRemoteMedia(mSeekbar!!.progress, true)
return
} else {
mPlaybackState = PlaybackState.IDLE
updatePlaybackLocation(PlaybackLocation.REMOTE)
}
}
updatePlayButton(mPlaybackState)
invalidateOptionsMenu()
}
private fun onApplicationDisconnected() {
updatePlaybackLocation(PlaybackLocation.LOCAL)
mPlaybackState = PlaybackState.IDLE
mLocation = PlaybackLocation.LOCAL
updatePlayButton(mPlaybackState)
invalidateOptionsMenu()
}
}
}
در فعالیت LocalPlayerActivity
، ما علاقه مندیم که از اتصال یا قطع ارتباط ما با دستگاه Cast مطلع شویم تا بتوانیم به پخش کننده محلی یا از آن جابجا شویم. توجه داشته باشید که اتصال میتواند نه تنها با نمونهای از برنامهای که در دستگاه تلفن همراه شما اجرا میشود، بلکه میتواند توسط نمونه دیگری از برنامه شما (یا دیگری) که در دستگاه تلفن همراه دیگری اجرا میشود، مختل شود.
جلسه فعال فعلی با نام SessionManager.getCurrentSession()
قابل دسترسی است. در پاسخ به تعامل کاربر با گفتگوهای Cast، جلسات به طور خودکار ایجاد و حذف می شوند.
ما باید شنود جلسه خود را ثبت کنیم و برخی از متغیرهایی را که در اکتیویتی استفاده خواهیم کرد مقداردهی اولیه کنیم. متد LocalPlayerActivity
onCreate
را به:
import com.google.android.gms.cast.framework.CastContext
...
private var mCastContext: CastContext? = null
...
override fun onCreate(savedInstanceState: Bundle?) {
...
mCastContext = CastContext.getSharedInstance(this)
mCastSession = mCastContext!!.sessionManager.currentCastSession
setupCastListener()
...
loadViews()
...
val bundle = intent.extras
if (bundle != null) {
....
if (shouldStartPlayback) {
....
} else {
if (mCastSession != null && mCastSession!!.isConnected()) {
updatePlaybackLocation(PlaybackLocation.REMOTE)
} else {
updatePlaybackLocation(PlaybackLocation.LOCAL)
}
mPlaybackState = PlaybackState.IDLE
updatePlayButton(mPlaybackState)
}
}
...
}
در حال بارگیری رسانه
در Cast SDK، RemoteMediaClient
مجموعهای از APIهای راحت را برای مدیریت پخش رسانه از راه دور در گیرنده فراهم میکند. برای CastSession
که از پخش رسانه پشتیبانی می کند، یک نمونه از RemoteMediaClient
به طور خودکار توسط SDK ایجاد می شود. با فراخوانی متد getRemoteMediaClient()
در نمونه CastSession
قابل دسترسی است. روشهای زیر را به LocalPlayerActivity
اضافه کنید تا ویدیوی انتخابی فعلی را روی گیرنده بارگیری کنید:
import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
if (mCastSession == null) {
return
}
val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
remoteMediaClient.load( MediaLoadRequestData.Builder()
.setMediaInfo(buildMediaInfo())
.setAutoplay(autoPlay)
.setCurrentTime(position.toLong()).build())
}
private fun buildMediaInfo(): MediaInfo? {
val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
return mSelectedMedia!!.url?.let {
MediaInfo.Builder(it)
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("videos/mp4")
.setMetadata(movieMetadata)
.setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
.build()
}
}
اکنون روشهای مختلف موجود را بهروزرسانی کنید تا از منطق جلسه Cast برای پشتیبانی از پخش از راه دور استفاده کنید:
private fun play(position: Int) {
startControllersTimer()
when (mLocation) {
PlaybackLocation.LOCAL -> {
mVideoView!!.seekTo(position)
mVideoView!!.start()
}
PlaybackLocation.REMOTE -> {
mPlaybackState = PlaybackState.BUFFERING
updatePlayButton(mPlaybackState)
//seek to a new position within the current media item's new position
//which is in milliseconds from the beginning of the stream
mCastSession!!.remoteMediaClient?.seek(position.toLong())
}
else -> {}
}
restartTrickplayTimer()
}
private fun togglePlayback() {
...
PlaybackState.IDLE -> when (mLocation) {
...
PlaybackLocation.REMOTE -> {
if (mCastSession != null && mCastSession!!.isConnected) {
loadRemoteMedia(mSeekbar!!.progress, true)
}
}
else -> {}
}
...
}
override fun onPause() {
...
mCastContext!!.sessionManager.removeSessionManagerListener(
mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
Log.d(TAG, "onResume() was called")
mCastContext!!.sessionManager.addSessionManagerListener(
mSessionManagerListener!!, CastSession::class.java)
if (mCastSession != null && mCastSession!!.isConnected) {
updatePlaybackLocation(PlaybackLocation.REMOTE)
} else {
updatePlaybackLocation(PlaybackLocation.LOCAL)
}
super.onResume()
}
برای متد updatePlayButton
، مقدار متغیر isConnected
را تغییر دهید:
private fun updatePlayButton(state: PlaybackState?) {
...
val isConnected = (mCastSession != null
&& (mCastSession!!.isConnected || mCastSession!!.isConnecting))
...
}
اکنون، روی دکمه اجرا برای اجرای برنامه در دستگاه تلفن همراه شما. به دستگاه Cast خود متصل شوید و شروع به پخش ویدیو کنید. شما باید ویدیو را در حال پخش روی گیرنده ببینید.
7. مینی کنترلر
چک لیست طراحی Cast مستلزم آن است که همه برنامههای Cast یک کنترلکننده کوچک ارائه دهند که وقتی کاربر از صفحه محتوای فعلی دور میشود ظاهر شود. مینی کنترلر دسترسی فوری و یک یادآوری قابل مشاهده را برای جلسه Cast فعلی فراهم می کند.
Cast SDK یک نمای سفارشی، MiniControllerFragment
ارائه میکند، که میتواند به فایل طرحبندی برنامه فعالیتهایی که میخواهید کنترلکننده کوچک را در آنها نشان دهید اضافه شود.
تعریف قطعه زیر را به پایین هر دو res/layout/player_activity.xml
و res/layout/video_browser.xml
اضافه کنید:
<fragment
android:id="@+id/castMiniController"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>
را کلیک کنید دکمه اجرا برای اجرای برنامه و پخش ویدیو. هنگامی که پخش در گیرنده شروع می شود، باید مینی کنترلر را در پایین هر فعالیت مشاهده کنید. با استفاده از مینی کنترلر می توانید پخش از راه دور را کنترل کنید. اگر بین فعالیت مرور و فعالیت پخش کننده محلی حرکت کنید، وضعیت مینی کنترلر باید با وضعیت پخش رسانه گیرنده همگام باشد.
8. اعلان و صفحه قفل
چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا کنترلهای رسانه را از یک اعلان و صفحه قفل اجرا کند.
Cast SDK یک MediaNotificationService
برای کمک به برنامه فرستنده در ساخت کنترلهای رسانه برای اعلان و صفحه قفل ارائه میکند. این سرویس به صورت خودکار در مانیفست برنامه شما ادغام می شود.
هنگامی که فرستنده در حال ارسال محتوا است، MediaNotificationService
در پسزمینه اجرا میشود و یک اعلان با تصویر کوچک تصویر و ابرداده در مورد مورد ارسالکننده فعلی، یک دکمه پخش/مکث، و یک دکمه توقف نشان میدهد.
هنگام تنظیم اولیه CastContext
کنترلهای اعلان و صفحه قفل را میتوان با CastOptions
فعال کرد. کنترل های رسانه برای اعلان و صفحه قفل به طور پیش فرض روشن هستند. تا زمانی که اعلان روشن باشد، ویژگی صفحه قفل روشن است.
CastOptionsProvider
را ویرایش کنید و پیاده سازی getCastOptions
را برای مطابقت با این کد تغییر دهید:
import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions
override fun getCastOptions(context: Context): CastOptions {
val notificationOptions = NotificationOptions.Builder()
.setTargetActivityClassName(VideoBrowserActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build()
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
را کلیک کنید دکمه اجرا برای اجرای برنامه در دستگاه تلفن همراه شما. یک ویدیو ارسال کنید و از برنامه نمونه دور شوید. برای ویدیویی که در حال حاضر روی گیرنده پخش می شود باید یک اعلان وجود داشته باشد. دستگاه همراه خود را قفل کنید و صفحه قفل اکنون باید کنترلهایی را برای پخش رسانه در دستگاه Cast نشان دهد.
9. پوشش مقدماتی
چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا دکمه Cast را به کاربران فعلی معرفی کند تا به آنها اطلاع دهد که برنامه فرستنده اکنون از ارسال محتوا پشتیبانی می کند و همچنین به کاربران تازه وارد Google Cast کمک می کند.
Cast SDK یک نمای سفارشی به IntroductoryOverlay
را ارائه می دهد که می تواند برای برجسته کردن دکمه Cast در اولین نمایش داده شدن به کاربران استفاده شود. کد زیر را به VideoBrowserActivity
اضافه کنید:
import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper
private var mIntroductoryOverlay: IntroductoryOverlay? = null
private fun showIntroductoryOverlay() {
mIntroductoryOverlay?.remove()
if (mediaRouteMenuItem?.isVisible == true) {
Looper.myLooper().run {
mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
this@VideoBrowserActivity, mediaRouteMenuItem!!)
.setTitleText("Introducing Cast")
.setSingleTime()
.setOnOverlayDismissedListener(
object : IntroductoryOverlay.OnOverlayDismissedListener {
override fun onOverlayDismissed() {
mIntroductoryOverlay = null
}
})
.build()
mIntroductoryOverlay!!.show()
}
}
}
اکنون، یک CastStateListener
اضافه کنید و onPause
که یک دستگاه Cast در دسترس است onCreate
onResume
showIntroductoryOverlay
را فراخوانی کنید.
import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener
private var mCastStateListener: CastStateListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.video_browser)
setupActionBar()
mCastStateListener = object : CastStateListener {
override fun onCastStateChanged(newState: Int) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay()
}
}
}
mCastContext = CastContext.getSharedInstance(this)
}
override fun onResume() {
super.onResume()
mCastContext?.addCastStateListener(mCastStateListener!!)
}
override fun onPause() {
super.onPause()
mCastContext?.removeCastStateListener(mCastStateListener!!)
}
داده های برنامه را پاک کنید یا برنامه را از دستگاه خود حذف کنید. سپس، روی دکمه اجرا برای اجرای برنامه در دستگاه تلفن همراه خود و باید پوشش مقدماتی را مشاهده کنید (اگر همپوشانی نمایش داده نشد، داده های برنامه را پاک کنید).
10. کنترل کننده گسترش یافته
چکلیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا کنترلکننده گستردهای را برای رسانه در حال پخش فراهم کند. کنترلر توسعه یافته یک نسخه تمام صفحه از مینی کنترلر است.
Cast SDK ویجتی را برای کنترلر توسعه یافته به نام ExpandedControllerActivity
فراهم می کند. این یک کلاس انتزاعی است که برای اضافه کردن دکمه Cast باید آن را زیر کلاس قرار دهید.
ابتدا یک فایل منبع منوی جدید به نام expanded_controller.xml
ایجاد کنید تا کنترلر توسعه یافته دکمه Cast را ارائه دهد:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
</menu>
یک بسته جدید expandedcontrols
در بسته com.google.sample.cast.refplayer
ایجاد کنید. سپس یک فایل جدید به نام ExpandedControlsActivity.kt
در بسته com.google.sample.cast.refplayer.expandedcontrols
ایجاد کنید.
package com.google.sample.cast.refplayer.expandedcontrols
import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory
class ExpandedControlsActivity : ExpandedControllerActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.expanded_controller, menu)
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
return true
}
}
اکنون ExpandedControlsActivity
را در AndroidManifest.xml
در تگ application
بالای OPTIONS_PROVIDER_CLASS_NAME
اعلام کنید:
<application>
...
<activity
android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.CastVideosDark"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
</activity>
...
</application>
CastOptionsProvider
را ویرایش کنید و NotificationOptions
و CastMediaOptions
تغییر دهید تا فعالیت هدف را روی ExpandedControlsActivity
تنظیم کنید:
import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity
override fun getCastOptions(context: Context): CastOptions {
val notificationOptions = NotificationOptions.Builder()
.setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
روش LocalPlayerActivity
loadRemoteMedia
را برای نمایش ExpandedControlsActivity
هنگام بارگیری رسانه راه دور به روز کنید:
import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
if (mCastSession == null) {
return
}
val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
override fun onStatusUpdated() {
val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
startActivity(intent)
remoteMediaClient.unregisterCallback(this)
}
})
remoteMediaClient.load(MediaLoadRequestData.Builder()
.setMediaInfo(buildMediaInfo())
.setAutoplay(autoPlay)
.setCurrentTime(position.toLong()).build())
}
را کلیک کنید دکمه اجرا برای اجرای برنامه در دستگاه تلفن همراه و پخش ویدیو. باید کنترلر گسترش یافته را ببینید. به لیست ویدیوها برگردید و با کلیک بر روی مینی کنترلر، کنترلر باز شده دوباره بارگذاری می شود. برای دیدن اعلان از برنامه دور شوید. روی تصویر اعلان کلیک کنید تا کنترلر توسعه یافته بارگیری شود.
11. پشتیبانی Cast Connect را اضافه کنید
کتابخانه Cast Connect به برنامههای فرستنده موجود اجازه میدهد با برنامههای Android TV از طریق پروتکل Cast ارتباط برقرار کنند. Cast Connect در بالای زیرساخت Cast ساخته می شود و برنامه Android TV شما به عنوان گیرنده عمل می کند.
وابستگی ها
توجه: برای اجرای Cast Connect، play-services-cast-framework
باید 19.0.0
یا بالاتر باشد.
گزینه های راه اندازی
برای راهاندازی برنامه Android TV که به آن گیرنده Android نیز گفته میشود، باید پرچم setAndroidReceiverCompatible
را در شی LaunchOptions
روی true تنظیم کنیم. این شی LaunchOptions
نحوه راه اندازی گیرنده را دیکته می کند و به CastOptions
ارسال شده توسط کلاس CastOptionsProvider
ارسال می شود. با تنظیم پرچم ذکر شده در بالا روی false
، گیرنده وب برای شناسه برنامه تعریف شده در کنسول توسعه دهنده Cast راه اندازی می شود.
در فایل CastOptionsProvider.kt
موارد زیر را به متد getCastOptions
اضافه کنید:
import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
.setAndroidReceiverCompatible(true)
.build()
return new CastOptions.Builder()
.setLaunchOptions(launchOptions)
...
.build()
اعتبار راه اندازی را تنظیم کنید
در سمت فرستنده، میتوانید CredentialsData
برای نشان دادن افرادی که به جلسه میپیوندند، مشخص کنید. credentials
رشته ای است که می تواند توسط کاربر تعریف شود، تا زمانی که برنامه ATV شما بتواند آن را درک کند. CredentialsData
فقط در زمان راهاندازی یا زمان پیوستن به برنامه Android TV شما منتقل میشود. اگر در حین اتصال دوباره آن را تنظیم کنید، به برنامه Android TV شما منتقل نخواهد شد.
برای تنظیم Launch Credentials CredentialsData
باید تعریف شده و به شی LaunchOptions
ارسال شود. کد زیر را به متد getCastOptions
در فایل CastOptionsProvider.kt
خود اضافه کنید:
import com.google.android.gms.cast.CredentialsData
...
val credentialsData = CredentialsData.Builder()
.setCredentials("{\"userId\": \"abc\"}")
.build()
val launchOptions = LaunchOptions.Builder()
...
.setCredentialsData(credentialsData)
.build()
اعتبارنامه ها را در LoadRequest تنظیم کنید
در صورتی که برنامه گیرنده وب و برنامه Android TV شما credentials
به طور متفاوتی مدیریت می کنند، ممکن است لازم باشد برای هر کدام credentials
جداگانه تعریف کنید. برای مراقبت از آن، کد زیر را در فایل LocalPlayerActivity.kt
خود در تابع loadRemoteMedia
اضافه کنید:
remoteMediaClient.load(MediaLoadRequestData.Builder()
...
.setCredentials("user-credentials")
.setAtvCredentials("atv-user-credentials")
.build())
بسته به برنامه گیرندهای که فرستنده شما به آن ارسال میکند، SDK اکنون بهطور خودکار بررسی میکند که از کدام اعتبارنامهها برای جلسه جاری استفاده کند.
آزمایش Cast Connect
مراحل نصب Android TV APK در Chromecast با Google TV
- آدرس IP دستگاه Android TV خود را پیدا کنید. معمولاً در تنظیمات > شبکه و اینترنت > (نام شبکه ای که دستگاه شما به آن متصل است) موجود است. در سمت راست، جزئیات و IP دستگاه شما را در شبکه نشان می دهد.
- از آدرس IP دستگاه خود برای اتصال از طریق ADB با استفاده از ترمینال به آن استفاده کنید:
$ adb connect <device_ip_address>:5555
- از پنجره ترمینال خود، به پوشه سطح بالا برای نمونههای Codelab که در ابتدای این کد لبه دانلود کردهاید، بروید. به عنوان مثال:
$ cd Desktop/android_codelab_src
- فایل apk. را در این پوشه در Android TV خود با اجرای:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- اکنون باید بتوانید برنامه ای به نام Cast Videos را در منوی برنامه های شما در دستگاه Android TV خود مشاهده کنید.
- به پروژه Android Studio خود بازگردید و روی دکمه Run کلیک کنید تا برنامه فرستنده را در دستگاه تلفن همراه فیزیکی خود نصب و اجرا کنید. در گوشه سمت راست بالا، روی نماد Cast کلیک کنید و دستگاه Android TV خود را از گزینههای موجود انتخاب کنید. اکنون باید برنامه Android TV را مشاهده کنید که در دستگاه Android TV شما راه اندازی شده است و پخش یک ویدیو به شما امکان می دهد تا با استفاده از کنترل از راه دور Android TV خود، پخش ویدیو را کنترل کنید.
12. ویجت های Cast را سفارشی کنید
میتوانید ویجتهای Cast را با تنظیم رنگها، شکل دادن به دکمهها، متن و ظاهر تصاویر کوچک، و با انتخاب انواع دکمهها برای نمایش، سفارشی کنید.
res/values/styles_castvideo.xml
را به روز کنید
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
<item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
<item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
<item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.ActionBar
</item>
...
</style>
تم های سفارشی زیر را اعلام کنید:
<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
<item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
<item name="mediaRouteButtonTint">#EEFF41</item>
</style>
<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
<item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
<item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
<item name="android:textColor">#FFFFFF</item>
</style>
<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
<item name="castShowImageThumbnail">true</item>
<item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
<item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
<item name="castBackground">@color/accent</item>
<item name="castProgressBarColor">@color/orange</item>
</style>
<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
<item name="castButtonColor">#FFFFFF</item>
<item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
<item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
<item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>
13. تبریک می گویم
اکنون میدانید که چگونه یک برنامه ویدیویی را با استفاده از ابزارکهای Cast SDK در Android فعال کنید.
برای جزئیات بیشتر، به راهنمای برنامهنویس Android Sender مراجعه کنید.
1. بررسی اجمالی
این کد لبه به شما می آموزد که چگونه یک برنامه ویدیویی موجود در اندروید را برای ارسال محتوا در یک دستگاه دارای Google Cast تغییر دهید.
Google Cast چیست؟
Google Cast به کاربران امکان می دهد محتوا را از دستگاه تلفن همراه به تلویزیون ارسال کنند. سپس کاربران می توانند از دستگاه تلفن همراه خود به عنوان یک کنترل از راه دور برای پخش رسانه در تلویزیون استفاده کنند.
Google Cast SDK به شما امکان می دهد برنامه خود را برای کنترل تلویزیون یا سیستم صوتی گسترش دهید. Cast SDK به شما امکان می دهد اجزای رابط کاربری لازم را بر اساس چک لیست طراحی Google Cast اضافه کنید.
چک لیست طراحی Google Cast برای ساده و قابل پیش بینی کردن تجربه کاربر Cast در همه پلتفرم های پشتیبانی شده ارائه شده است.
قرار است چه چیزی بسازیم؟
پس از تکمیل این کد لبه، یک برنامه ویدیویی Android خواهید داشت که میتواند ویدیوها را به دستگاهی با قابلیت Google Cast ارسال کند.
چیزی که یاد خواهید گرفت
- چگونه Google Cast SDK را به یک برنامه ویدیویی نمونه اضافه کنیم.
- نحوه اضافه کردن دکمه Cast برای انتخاب دستگاه Google Cast.
- نحوه اتصال به دستگاه Cast و راه اندازی گیرنده رسانه.
- نحوه پخش ویدیو
- چگونه مینی کنترلر Cast را به برنامه خود اضافه کنید.
- نحوه پشتیبانی از اعلانهای رسانه و کنترلهای صفحه قفل
- نحوه اضافه کردن یک کنترلر توسعه یافته
- نحوه ارائه یک پوشش مقدماتی
- چگونه ویجتهای Cast را سفارشی کنیم.
- نحوه ادغام با Cast Connect
آنچه شما نیاز دارید
- جدیدترین Android SDK .
- اندروید استودیو نسخه 3.2+
- یک دستگاه تلفن همراه با Android 4.1+ Jelly Bean (سطح API 16).
- یک کابل داده USB برای اتصال دستگاه تلفن همراه به رایانه توسعه.
- یک دستگاه Google Cast مانند Chromecast یا Android TV که با دسترسی به اینترنت پیکربندی شده است.
- تلویزیون یا مانیتور با ورودی HDMI.
- برای آزمایش ادغام Cast Connect به Chromecast با Google TV نیاز است، اما برای بقیه Codelab اختیاری است. اگر یکی ندارید، در پایان این آموزش از مرحله Add Cast Connect Support رد شوید.
تجربه کنید
- شما باید دانش قبلی کاتلین و توسعه اندروید را داشته باشید.
- شما همچنین به دانش قبلی در مورد تماشای تلویزیون نیاز دارید :)
چگونه از این آموزش استفاده خواهید کرد؟
به تجربه خود از ساخت اپلیکیشن های اندرویدی چه امتیازی می دهید؟
تجربه خود را از تماشای تلویزیون چگونه ارزیابی می کنید؟
2. کد نمونه را دریافت کنید
می توانید تمام کدهای نمونه را در رایانه خود دانلود کنید ...
و فایل فشرده دانلود شده را باز کنید.
3. برنامه نمونه را اجرا کنید
ابتدا، بیایید ببینیم که برنامه نمونه تکمیل شده چگونه به نظر می رسد. این برنامه یک پخش کننده ویدیوی اساسی است. کاربر می تواند یک ویدیو را از یک لیست انتخاب کند و سپس می تواند ویدیو را به صورت محلی در دستگاه پخش کند یا آن را به دستگاه Google Cast ارسال کند.
با دانلود کد، دستورالعمل های زیر نحوه باز کردن و اجرای برنامه نمونه تکمیل شده در Android Studio را شرح می دهد:
Import Project را در صفحه خوش آمدگویی یا گزینه های منو File > New > Import Project... را انتخاب کنید.
را انتخاب کنید دایرکتوری
app-done
از پوشه کد نمونه و روی OK کلیک کنید.
روی فایل > کلیک کنید همگام سازی پروژه با فایل های Gradle .
اشکال زدایی USB را در دستگاه Android خود فعال کنید - در اندروید 4.2 و بالاتر، صفحه گزینه های برنامه نویس به طور پیش فرض پنهان است. برای اینکه آن را قابل مشاهده کنید، به Settings > About phone بروید و هفت بار روی Build number ضربه بزنید. به صفحه قبلی بازگردید، به System > Advanced بروید و روی Developer options نزدیک پایین ضربه بزنید، سپس روی USB debugging ضربه بزنید تا روشن شود.
دستگاه اندروید خود را وصل کنید و روی آن کلیک کنید دکمه اجرا در اندروید استودیو. پس از چند ثانیه باید ببینید که برنامه ویدیویی با نام Cast Videos ظاهر می شود.
روی دکمه Cast در برنامه ویدیو کلیک کنید و دستگاه Google Cast خود را انتخاب کنید.
یک ویدیو را انتخاب کنید و روی دکمه پخش کلیک کنید.
پخش ویدیو در دستگاه Google Cast شما شروع می شود.
کنترل کننده گسترش یافته نمایش داده می شود. می توانید از دکمه پخش/مکث برای کنترل پخش استفاده کنید.
به لیست ویدیوها برگردید.
اکنون یک مینی کنترلر در پایین صفحه قابل مشاهده است.
روی دکمه مکث در کنترلر کوچک کلیک کنید تا ویدیو روی گیرنده متوقف شود. برای ادامه پخش مجدد ویدیو، روی دکمه پخش در مینی کنترلر کلیک کنید.
روی دکمه هوم دستگاه موبایل کلیک کنید. اعلانها را پایین بکشید و اکنون باید یک اعلان برای جلسه Cast ببینید.
تلفن خود را قفل کنید و وقتی قفل آن را باز می کنید، باید اعلانی را روی صفحه قفل مشاهده کنید تا پخش رسانه را کنترل کنید یا ارسال را متوقف کنید.
به برنامه ویدیو برگردید و روی دکمه Cast کلیک کنید تا ارسال محتوا در دستگاه Google Cast متوقف شود.
سوالات متداول
4. پروژه شروع را آماده کنید
باید پشتیبانی از Google Cast را به برنامه شروعی که دانلود کردید اضافه کنیم. در اینجا برخی از اصطلاحات Google Cast وجود دارد که در این لبه کد استفاده خواهیم کرد:
- یک برنامه فرستنده روی دستگاه تلفن همراه یا لپ تاپ اجرا می شود،
- یک برنامه گیرنده در دستگاه Google Cast اجرا می شود.
اکنون شما آماده ساخت در بالای پروژه استارت با استفاده از Android Studio هستید:
- را انتخاب کنید
دایرکتوری
app-start
از بارگیری کد نمونه خود (وارد کردن پروژه واردات در صفحه Welcome یا File> New> Import Project ... گزینه منو). - کلیک بر روی
پروژه همگام سازی با دکمه Gradle Files .
- کلیک بر روی
دکمه را اجرا کنید تا برنامه را اجرا کنید و UI را کاوش کنید.
طراحی اپلیکیشن
این برنامه لیستی از فیلم ها را از یک سرور وب از راه دور دریافت می کند و لیستی را برای مرور کاربر فراهم می کند. کاربران می توانند یک ویدیو را برای دیدن جزئیات یا پخش ویدیو به صورت محلی در دستگاه تلفن همراه انتخاب کنند.
این برنامه از دو فعالیت اصلی تشکیل شده است: VideoBrowserActivity
و LocalPlayerActivity
. به منظور ادغام عملکرد بازیگران Google ، فعالیت ها باید از طریق AppCompatActivity
یا والدین آن FragmentActivity
شوند. این محدودیت وجود دارد از آنجا که ما نیاز به اضافه کردن MediaRouteButton
(ارائه شده در کتابخانه پشتیبانی Mediarouter ) به عنوان یک MediaRouteActionProvider
داریم و این تنها در صورتی که فعالیت از کلاسهای فوق الذکر باشد ، کار خواهد کرد. کتابخانه پشتیبانی Mediarouter به کتابخانه پشتیبانی AppCompat بستگی دارد که کلاسهای مورد نیاز را ارائه می دهد.
VideoBrowseractivity
این فعالیت شامل یک Fragment
( VideoBrowserFragment
) است. این لیست توسط ArrayAdapter
( VideoListAdapter
) پشتیبانی می شود. لیست فیلم ها و ابرداده های مرتبط با آنها به عنوان یک فایل JSON در یک سرور از راه دور میزبانی می شوند. یک AsyncTaskLoader
( VideoItemLoader
) این JSON را واگذار می کند و آن را برای ساختن لیستی از اشیاء MediaItem
پردازش می کند.
یک شیء MediaItem
یک فیلم و ابرداده مرتبط با آن ، مانند عنوان ، توضیحات ، URL برای جریان ، URL برای تصاویر پشتیبانی و آهنگ های متن مرتبط (برای زیرنویس های بسته) را در صورت وجود مدل می کند. شیء MediaItem
بین فعالیت ها منتقل می شود ، بنابراین MediaItem
روش های ابزار برای تبدیل آن به یک Bundle
و برعکس دارد.
هنگامی که لودر لیست MediaItems
را ایجاد می کند ، آن لیست را به VideoListAdapter
منتقل می کند که سپس لیست MediaItems
را در VideoBrowserFragment
ارائه می دهد. کاربر با لیستی از تصاویر کوچک ویدیویی با توضیحات کوتاه برای هر ویدیو ارائه شده است. هنگامی که یک مورد انتخاب می شود ، MediaItem
مربوطه به یک Bundle
تبدیل می شود و به LocalPlayerActivity
منتقل می شود.
فعالیت محلی
این فعالیت ابرداده را در مورد یک ویدیوی خاص نشان می دهد و به کاربر اجازه می دهد تا ویدیو را به صورت محلی در دستگاه تلفن همراه پخش کند.
این فعالیت میزبان یک VideoView
، برخی از کنترل رسانه ها و یک منطقه متنی برای نشان دادن توضیحات ویدیوی انتخاب شده است. پخش کننده قسمت بالای صفحه را پوشش می دهد و اتاق را برای توضیحات دقیق فیلم در زیر می گذارد. کاربر می تواند بازی/مکث کند یا به دنبال پخش محلی فیلم ها باشد.
وابستگی ها
از آنجا که ما از AppCompatActivity
استفاده می کنیم ، به کتابخانه پشتیبانی AppCompat احتیاج داریم. برای مدیریت لیست فیلم ها و به طور غیر همزمان گرفتن تصاویر برای لیست ، ما از کتابخانه واللی استفاده می کنیم.
سوالات متداول
5. اضافه کردن دکمه بازیگران
یک برنامه با قابلیت ریخته گری دکمه بازیگران را در هر یک از فعالیت های خود نشان می دهد. با کلیک بر روی دکمه Cast، لیستی از دستگاههای Cast که کاربر میتواند انتخاب کند، نمایش داده میشود. اگر کاربر در دستگاه فرستنده محتوا را به صورت محلی پخش می کرد، انتخاب دستگاه Cast پخش را در آن دستگاه Cast شروع یا از سر می گیرد. در هر زمان در طول جلسه بازیگران ، کاربر می تواند روی دکمه CAST کلیک کرده و برنامه ریزی خود را به دستگاه بازیگران متوقف کند. کاربر باید در هر فعالیتی از برنامه شما ، همانطور که در لیست چک طراحی Google Cast توضیح داده شده است ، از دستگاه بازیگران وصل یا جدا شود.
وابستگی ها
پرونده build.gradle را به روز کنید تا وابستگی های لازم در کتابخانه را شامل شود:
dependencies {
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.mediarouter:mediarouter:1.3.1'
implementation 'androidx.recyclerview:recyclerview:1.2.1'
implementation 'com.google.android.gms:play-services-cast-framework:21.1.0'
implementation 'com.android.volley:volley:1.2.1'
implementation "androidx.core:core-ktx:1.8.0"
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
}
همگام سازی پروژه برای تأیید پروژه بدون خطا.
مقداردهی اولیه
چارچوب بازیگران دارای یک شیء Singleton جهانی ، CastContext
است که همه تعامل بازیگران را هماهنگ می کند.
شما باید رابط OptionsProvider
را برای تهیه CastOptions
مورد نیاز برای اولیه سازی Singleton CastContext
پیاده سازی کنید. مهمترین گزینه شناسه برنامه گیرنده است که برای فیلتر کردن نتایج کشف دستگاه بازیگران و راه اندازی برنامه گیرنده هنگام شروع جلسه بازیگران استفاده می شود.
هنگامی که برنامه خود را با قابلیت بازیگران خود تهیه می کنید ، باید به عنوان یک توسعه دهنده بازیگران ثبت نام کنید و سپس شناسه برنامه را برای برنامه خود بدست آورید. برای این CodeLab ، ما از یک شناسه برنامه نمونه استفاده خواهیم کرد.
پرونده جدید CastOptionsProvider.kt
را به بسته com.google.sample.cast.refplayer
از پروژه اضافه کنید:
package com.google.sample.cast.refplayer
import android.content.Context
import com.google.android.gms.cast.framework.OptionsProvider
import com.google.android.gms.cast.framework.CastOptions
import com.google.android.gms.cast.framework.SessionProvider
class CastOptionsProvider : OptionsProvider {
override fun getCastOptions(context: Context): CastOptions {
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.build()
}
override fun getAdditionalSessionProviders(context: Context): List<SessionProvider>? {
return null
}
}
اکنون OptionsProvider
در برچسب " application
" برنامه AndroidManifest.xml
اعلام کنید:
<meta-data
android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME"
android:value="com.google.sample.cast.refplayer.CastOptionsProvider" />
CastContext
در روش onCreate VideoBrowserActivity
به صورت تنبیه کنید:
import com.google.android.gms.cast.framework.CastContext
private var mCastContext: CastContext? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.video_browser)
setupActionBar()
mCastContext = CastContext.getSharedInstance(this)
}
همان منطق اولیه سازی را به LocalPlayerActivity
اضافه کنید.
دکمه بازیگران
اکنون که CastContext
اولیه سازی شده است ، باید دکمه CAST را اضافه کنیم تا به کاربر اجازه دهد یک دستگاه ریخته گری را انتخاب کند. دکمه بازیگران توسط MediaRouteButton
از کتابخانه پشتیبانی Mediarouter اجرا شده است. مانند هر نماد اکشن که می توانید به فعالیت خود اضافه کنید (با استفاده از یک ActionBar
یا Toolbar
) ، ابتدا باید مورد منوی مربوطه را به منوی خود اضافه کنید.
پرونده res/menu/browse.xml
را ویرایش کرده و مورد MediaRouteActionProvider
را در منو قبل از مورد تنظیمات اضافه کنید:
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
روش onCreateOptionsMenu()
VideoBrowserActivity
با استفاده از CastButtonFactory
برای سیم کشی MediaRouteButton
به چارچوب بازیگران نادیده بگیرید:
import com.google.android.gms.cast.framework.CastButtonFactory
private var mediaRouteMenuItem: MenuItem? = null
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.browse, menu)
mediaRouteMenuItem = CastButtonFactory.setUpMediaRouteButton(getApplicationContext(), menu,
R.id.media_route_menu_item)
return true
}
onCreateOptionsMenu
در LocalPlayerActivity
به روشی مشابه نادیده بگیرید.
کلیک بر روی دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید. شما باید یک دکمه بازیگران را در نوار اکشن برنامه مشاهده کنید و وقتی روی آن کلیک می کنید ، دستگاه های بازیگران را در شبکه محلی خود لیست می کند. کشف دستگاه به طور خودکار توسط
CastContext
اداره می شود. دستگاه ریخته گری خود را انتخاب کنید و برنامه گیرنده نمونه بر روی دستگاه ریخته گری بارگیری می شود. می توانید بین فعالیت مرور و فعالیت پخش کننده محلی حرکت کنید و وضعیت دکمه بازیگران در همگام سازی نگه داشته می شود.
ما هیچ پشتیبانی از پخش رسانه ها را به خود اختصاص نداده ایم ، بنابراین شما هنوز نمی توانید در دستگاه بازیگران فیلم پخش کنید. برای قطع ارتباط بر روی دکمه CAST کلیک کنید.
6. ریخته گری محتوای ویدیویی
ما برنامه نمونه را گسترش خواهیم داد تا فیلم ها را از راه دور بر روی دستگاه بازیگران پخش کنیم. برای انجام این کار ، ما باید به رویدادهای مختلف ایجاد شده توسط چارچوب بازیگران گوش دهیم.
رسانه های ریخته گری
در سطح بالایی ، اگر می خواهید رسانه ای را در دستگاه بازیگران بازی کنید ، باید این کارها را انجام دهید:
- یک شیء
MediaInfo
ایجاد کنید که یک مورد رسانه ای را مدل کند. - به دستگاه ریخته گری متصل شوید و برنامه گیرنده خود را راه اندازی کنید.
- شیء
MediaInfo
را در گیرنده خود بارگیری کرده و محتوا را بازی کنید. - وضعیت رسانه را پیگیری کنید.
- ارسال دستورات پخش به گیرنده بر اساس تعامل کاربر.
ما قبلاً مرحله 2 را در بخش قبلی انجام داده ایم. مرحله 3 با چارچوب بازیگران آسان است. مرحله 1 برای نقشه برداری یک شی به شیء دیگر است. MediaInfo
چیزی است که چارچوب بازیگران آن را درک می کند و MediaItem
محاصره برنامه ما برای یک مورد رسانه ای است. ما به راحتی می توانیم یک MediaItem
را به یک MediaInfo
ترسیم کنیم.
برنامه نمونه LocalPlayerActivity
در حال حاضر بین پخش محلی در مقابل از راه دور با استفاده از این enum تمایز قائل می شود:
private var mLocation: PlaybackLocation? = null
enum class PlaybackLocation {
LOCAL, REMOTE
}
enum class PlaybackState {
PLAYING, PAUSED, BUFFERING, IDLE
}
در این CodeLab برای شما مهم نیست که دقیقاً درک کنید که تمام منطق نمونه پخش کننده نمونه کار می کند. درک این نکته مهم است که پخش کننده رسانه برنامه شما باید اصلاح شود تا از دو مکان پخش به روشی مشابه آگاه باشد.
در حال حاضر بازیکن محلی همیشه در حالت پخش محلی قرار دارد زیرا هنوز چیزی در مورد حالت های ریخته گری نمی داند. ما باید UI را بر اساس انتقال حالت که در چارچوب بازیگران اتفاق می افتد ، به روز کنیم. به عنوان مثال ، اگر شروع به بازیگری کنیم ، باید جلوی پخش محلی را بگیریم و برخی از کنترل ها را غیرفعال کنیم. به همین ترتیب ، اگر وقتی در این فعالیت هستیم ، از ریخته گری متوقف شویم ، باید به پخش محلی منتقل شویم. برای رسیدگی به این امر باید به رویدادهای مختلفی که توسط چارچوب بازیگران ایجاد شده است گوش دهیم.
مدیریت جلسه بازیگران
برای چارچوب بازیگران یک جلسه بازیگران مراحل اتصال به یک دستگاه ، راه اندازی (یا پیوستن) ، اتصال به یک برنامه گیرنده و در صورت لزوم کانال کنترل رسانه را ترکیب می کند. کانال کنترل رسانه ای است که چگونه چارچوب بازیگران پیام های بازیکن گیرنده رسانه را ارسال و دریافت می کند.
هنگامی که کاربر دستگاهی را از دکمه CAST انتخاب می کند ، جلسه بازیگران به صورت خودکار شروع می شود و در هنگام قطع کاربر به طور خودکار متوقف می شود. اتصال مجدد به جلسه گیرنده به دلیل مشکلات شبکه نیز به طور خودکار توسط بازیگران SDK انجام می شود.
بیایید یک SessionManagerListener
را به LocalPlayerActivity
اضافه کنیم:
import com.google.android.gms.cast.framework.CastSession
import com.google.android.gms.cast.framework.SessionManagerListener
...
private var mSessionManagerListener: SessionManagerListener<CastSession>? = null
private var mCastSession: CastSession? = null
...
private fun setupCastListener() {
mSessionManagerListener = object : SessionManagerListener<CastSession> {
override fun onSessionEnded(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) {
onApplicationConnected(session)
}
override fun onSessionResumeFailed(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionStarted(session: CastSession, sessionId: String) {
onApplicationConnected(session)
}
override fun onSessionStartFailed(session: CastSession, error: Int) {
onApplicationDisconnected()
}
override fun onSessionStarting(session: CastSession) {}
override fun onSessionEnding(session: CastSession) {}
override fun onSessionResuming(session: CastSession, sessionId: String) {}
override fun onSessionSuspended(session: CastSession, reason: Int) {}
private fun onApplicationConnected(castSession: CastSession) {
mCastSession = castSession
if (null != mSelectedMedia) {
if (mPlaybackState == PlaybackState.PLAYING) {
mVideoView!!.pause()
loadRemoteMedia(mSeekbar!!.progress, true)
return
} else {
mPlaybackState = PlaybackState.IDLE
updatePlaybackLocation(PlaybackLocation.REMOTE)
}
}
updatePlayButton(mPlaybackState)
invalidateOptionsMenu()
}
private fun onApplicationDisconnected() {
updatePlaybackLocation(PlaybackLocation.LOCAL)
mPlaybackState = PlaybackState.IDLE
mLocation = PlaybackLocation.LOCAL
updatePlayButton(mPlaybackState)
invalidateOptionsMenu()
}
}
}
در فعالیت LocalPlayerActivity
، ما علاقه مندیم که هنگام اتصال یا قطع شدن از دستگاه ریخته گری ، مطلع شویم تا بتوانیم به بازیکن محلی یا از آن تغییر دهیم. توجه داشته باشید که اتصال نه تنها با استفاده از برنامه کاربردی شما که در دستگاه تلفن همراه شما اجرا می شود ، می تواند مختل شود ، بلکه می تواند با نمونه دیگری از برنامه (یا دیگری) شما که روی یک دستگاه تلفن همراه متفاوت اجرا می شود ، مختل شود.
جلسه فعال در حال حاضر به عنوان SessionManager.getCurrentSession()
قابل دسترسی است. جلسات در پاسخ به تعامل کاربر با گفتگوی های بازیگران به طور خودکار ایجاد و پاره می شوند.
ما باید شنونده جلسه خود را ثبت کنیم و برخی از متغیرهایی را که در فعالیت استفاده خواهیم کرد ، آغاز کنیم. روش onCreate
LocalPlayerActivity
را به:
import com.google.android.gms.cast.framework.CastContext
...
private var mCastContext: CastContext? = null
...
override fun onCreate(savedInstanceState: Bundle?) {
...
mCastContext = CastContext.getSharedInstance(this)
mCastSession = mCastContext!!.sessionManager.currentCastSession
setupCastListener()
...
loadViews()
...
val bundle = intent.extras
if (bundle != null) {
....
if (shouldStartPlayback) {
....
} else {
if (mCastSession != null && mCastSession!!.isConnected()) {
updatePlaybackLocation(PlaybackLocation.REMOTE)
} else {
updatePlaybackLocation(PlaybackLocation.LOCAL)
}
mPlaybackState = PlaybackState.IDLE
updatePlayButton(mPlaybackState)
}
}
...
}
در حال بارگیری رسانه
در بازیگران SDK ، RemoteMediaClient
مجموعه ای از API های مناسب را برای مدیریت پخش رسانه ای از راه دور روی گیرنده فراهم می کند. برای یک CastSession
که از پخش رسانه پشتیبانی می کند ، نمونه ای از RemoteMediaClient
به طور خودکار توسط SDK ایجاد می شود. با فراخوانی روش getRemoteMediaClient()
در نمونه CastSession
می توان به آن دسترسی پیدا کرد. روش های زیر را به LocalPlayerActivity
اضافه کنید تا فیلم انتخاب شده در حال حاضر روی گیرنده بارگذاری شود:
import com.google.android.gms.cast.framework.media.RemoteMediaClient
import com.google.android.gms.cast.MediaInfo
import com.google.android.gms.cast.MediaLoadOptions
import com.google.android.gms.cast.MediaMetadata
import com.google.android.gms.common.images.WebImage
import com.google.android.gms.cast.MediaLoadRequestData
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
if (mCastSession == null) {
return
}
val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
remoteMediaClient.load( MediaLoadRequestData.Builder()
.setMediaInfo(buildMediaInfo())
.setAutoplay(autoPlay)
.setCurrentTime(position.toLong()).build())
}
private fun buildMediaInfo(): MediaInfo? {
val movieMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MOVIE)
mSelectedMedia?.studio?.let { movieMetadata.putString(MediaMetadata.KEY_SUBTITLE, it) }
mSelectedMedia?.title?.let { movieMetadata.putString(MediaMetadata.KEY_TITLE, it) }
movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(0))))
movieMetadata.addImage(WebImage(Uri.parse(mSelectedMedia!!.getImage(1))))
return mSelectedMedia!!.url?.let {
MediaInfo.Builder(it)
.setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
.setContentType("videos/mp4")
.setMetadata(movieMetadata)
.setStreamDuration((mSelectedMedia!!.duration * 1000).toLong())
.build()
}
}
اکنون روشهای مختلف موجود را برای استفاده از منطق جلسه CAST برای پشتیبانی از پخش از راه دور به روز کنید:
private fun play(position: Int) {
startControllersTimer()
when (mLocation) {
PlaybackLocation.LOCAL -> {
mVideoView!!.seekTo(position)
mVideoView!!.start()
}
PlaybackLocation.REMOTE -> {
mPlaybackState = PlaybackState.BUFFERING
updatePlayButton(mPlaybackState)
//seek to a new position within the current media item's new position
//which is in milliseconds from the beginning of the stream
mCastSession!!.remoteMediaClient?.seek(position.toLong())
}
else -> {}
}
restartTrickplayTimer()
}
private fun togglePlayback() {
...
PlaybackState.IDLE -> when (mLocation) {
...
PlaybackLocation.REMOTE -> {
if (mCastSession != null && mCastSession!!.isConnected) {
loadRemoteMedia(mSeekbar!!.progress, true)
}
}
else -> {}
}
...
}
override fun onPause() {
...
mCastContext!!.sessionManager.removeSessionManagerListener(
mSessionManagerListener!!, CastSession::class.java)
}
override fun onResume() {
Log.d(TAG, "onResume() was called")
mCastContext!!.sessionManager.addSessionManagerListener(
mSessionManagerListener!!, CastSession::class.java)
if (mCastSession != null && mCastSession!!.isConnected) {
updatePlaybackLocation(PlaybackLocation.REMOTE)
} else {
updatePlaybackLocation(PlaybackLocation.LOCAL)
}
super.onResume()
}
برای روش updatePlayButton
، مقدار متغیر isConnected
را تغییر دهید:
private fun updatePlayButton(state: PlaybackState?) {
...
val isConnected = (mCastSession != null
&& (mCastSession!!.isConnected || mCastSession!!.isConnecting))
...
}
اکنون ، روی کلیک کنید دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید. به دستگاه بازیگران خود وصل شوید و پخش یک فیلم را شروع کنید. شما باید فیلم را روی گیرنده پخش کنید.
7. مینی کنترل کننده
چک لیست طراحی بازیگران نیاز دارد که تمام برنامه های بازیگران یک کنترلر مینی ارائه دهند که هنگام حرکت کاربر از صفحه محتوای فعلی ظاهر می شود. Mini Controller دسترسی فوری و یادآوری قابل مشاهده برای جلسه بازیگران فعلی را فراهم می کند.
Cast SDK نمای سفارشی ، MiniControllerFragment
را ارائه می دهد ، که می تواند به پرونده طرح برنامه از فعالیتهایی که می خواهید مینی کنترلر را نشان دهید اضافه شود.
تعریف قطعه زیر را به پایین هر دو res/layout/player_activity.xml
و res/layout/video_browser.xml
اضافه کنید:
<fragment
android:id="@+id/castMiniController"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone"
class="com.google.android.gms.cast.framework.media.widget.MiniControllerFragment"/>
کلیک بر روی دکمه را اجرا کنید تا برنامه را اجرا کنید و یک ویدیو بازی کنید. هنگامی که پخش روی گیرنده شروع می شود ، باید مشاهده کنید که Mini Controller در پایین هر فعالیت ظاهر می شود. می توانید پخش از راه دور را با استفاده از Mini Controller کنترل کنید. اگر بین فعالیت مرور و فعالیت پخش کننده محلی حرکت کنید ، وضعیت Mini Controller باید با وضعیت پخش رسانه گیرنده همگام بماند.
8. صفحه اعلان و قفل
چک لیست طراحی Google Cast برای اجرای کنترل رسانه ها از یک اعلان و صفحه قفل به یک برنامه فرستنده نیاز دارد.
Cast SDK برای کمک به برنامه فرستنده برای ایجاد کنترل رسانه برای صفحه اعلان و قفل ، یک MediaNotificationService
ارائه می دهد. این سرویس به طور خودکار توسط Gradle در مانیفست برنامه شما ادغام می شود.
MediaNotificationService
در هنگام ریخته گری فرستنده در پس زمینه اجرا می شود و با یک تصویر کوچک تصویر و ابرداده در مورد مورد ریخته گری فعلی ، یک دکمه پخش/مکث و یک دکمه توقف ، اعلان را نشان می دهد.
کنترل های صفحه نمایش اعلان و قفل را می توان با استفاده از CastOptions
هنگام اولیه سازی CastContext
فعال کرد. کنترل رسانه برای صفحه اعلان و قفل به طور پیش فرض روشن می شود. ویژگی صفحه قفل تا زمانی که اعلان روشن شود روشن می شود.
CastOptionsProvider
را ویرایش کرده و اجرای getCastOptions
را برای مطابقت با این کد تغییر دهید:
import com.google.android.gms.cast.framework.media.CastMediaOptions
import com.google.android.gms.cast.framework.media.NotificationOptions
override fun getCastOptions(context: Context): CastOptions {
val notificationOptions = NotificationOptions.Builder()
.setTargetActivityClassName(VideoBrowserActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.build()
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
کلیک بر روی دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید. یک ویدیو ریخته و از برنامه نمونه دور شوید. باید برای این ویدئویی که در حال حاضر در گیرنده پخش می شود ، اعلان وجود داشته باشد. دستگاه تلفن همراه خود را قفل کنید و صفحه قفل اکنون باید کنترل های پخش رسانه را در دستگاه بازیگران نشان دهد.
9. روکش مقدماتی
چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا دکمه بازیگران را به کاربران موجود معرفی کند تا به آنها اطلاع دهد که برنامه فرستنده اکنون از ریخته گری پشتیبانی می کند و همچنین به کاربران جدید در Google Cast کمک می کند.
Cast SDK نمای سفارشی ، IntroductoryOverlay
ارائه می دهد ، که می تواند برای برجسته کردن دکمه بازیگران در هنگام اولین بار به کاربران استفاده شود. کد زیر را به VideoBrowserActivity
اضافه کنید:
import com.google.android.gms.cast.framework.IntroductoryOverlay
import android.os.Looper
private var mIntroductoryOverlay: IntroductoryOverlay? = null
private fun showIntroductoryOverlay() {
mIntroductoryOverlay?.remove()
if (mediaRouteMenuItem?.isVisible == true) {
Looper.myLooper().run {
mIntroductoryOverlay = com.google.android.gms.cast.framework.IntroductoryOverlay.Builder(
this@VideoBrowserActivity, mediaRouteMenuItem!!)
.setTitleText("Introducing Cast")
.setSingleTime()
.setOnOverlayDismissedListener(
object : IntroductoryOverlay.OnOverlayDismissedListener {
override fun onOverlayDismissed() {
mIntroductoryOverlay = null
}
})
.build()
mIntroductoryOverlay!!.show()
}
}
}
اکنون ، یک CastStateListener
اضافه کنید و وقتی یک دستگاه ریخته گری با اصلاح روش onCreate
در دسترس است و روش های onResume
و onPause
را نادیده بگیرید ، با روش showIntroductoryOverlay
تماس بگیرید:
import com.google.android.gms.cast.framework.CastState
import com.google.android.gms.cast.framework.CastStateListener
private var mCastStateListener: CastStateListener? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.video_browser)
setupActionBar()
mCastStateListener = object : CastStateListener {
override fun onCastStateChanged(newState: Int) {
if (newState != CastState.NO_DEVICES_AVAILABLE) {
showIntroductoryOverlay()
}
}
}
mCastContext = CastContext.getSharedInstance(this)
}
override fun onResume() {
super.onResume()
mCastContext?.addCastStateListener(mCastStateListener!!)
}
override fun onPause() {
super.onPause()
mCastContext?.removeCastStateListener(mCastStateListener!!)
}
داده های برنامه را پاک کنید یا برنامه را از دستگاه خود حذف کنید. سپس ، روی کلیک کنید دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید و باید پوشش مقدماتی را مشاهده کنید (اگر پوشش داده نشود ، داده های برنامه را پاک کنید).
10. کنترلر گسترش یافته
چک لیست طراحی Google Cast به یک برنامه فرستنده نیاز دارد تا کنترلر گسترده ای را برای رسانه های بازیگران ارائه دهد. کنترلر گسترش یافته یک نسخه کامل از Mini Controller است.
بازیگران SDK ویجت را برای کنترلر گسترش یافته به نام ExpandedControllerActivity
فراهم می کند. این یک کلاس انتزاعی است که شما باید برای اضافه کردن یک دکمه بازیگران ، زیر کلاس داشته باشید.
در مرحله اول ، یک فایل منبع منو جدید به نام expanded_controller.xml
ایجاد کنید تا کنترلر گسترش یافته دکمه CAST را فراهم کند:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/media_route_menu_item"
android:title="@string/media_route_menu_title"
app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider"
app:showAsAction="always"/>
</menu>
یک بسته جدید expandedcontrols
در بسته com.google.sample.cast.refplayer
ایجاد کنید. در مرحله بعد ، یک فایل جدید به نام ExpandedControlsActivity.kt
در بسته com.google.sample.cast.refplayer.expandedcontrols
ایجاد کنید.
package com.google.sample.cast.refplayer.expandedcontrols
import android.view.Menu
import com.google.android.gms.cast.framework.media.widget.ExpandedControllerActivity
import com.google.sample.cast.refplayer.R
import com.google.android.gms.cast.framework.CastButtonFactory
class ExpandedControlsActivity : ExpandedControllerActivity() {
override fun onCreateOptionsMenu(menu: Menu): Boolean {
super.onCreateOptionsMenu(menu)
menuInflater.inflate(R.menu.expanded_controller, menu)
CastButtonFactory.setUpMediaRouteButton(this, menu, R.id.media_route_menu_item)
return true
}
}
اکنون در برچسب application
بالاتر از OPTIONS_PROVIDER_CLASS_NAME
ExpandedControlsActivity
در AndroidManifest.xml
اعلام کنید:
<application>
...
<activity
android:name="com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:theme="@style/Theme.CastVideosDark"
android:screenOrientation="portrait"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.google.sample.cast.refplayer.VideoBrowserActivity"/>
</activity>
...
</application>
برای تنظیم فعالیت هدف به فعالیت ExpandedControlsActivity
ویرایش CastOptionsProvider
و تغییر NotificationOptions
و CastMediaOptions
:
import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity
override fun getCastOptions(context: Context): CastOptions {
val notificationOptions = NotificationOptions.Builder()
.setTargetActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
val mediaOptions = CastMediaOptions.Builder()
.setNotificationOptions(notificationOptions)
.setExpandedControllerActivityClassName(ExpandedControlsActivity::class.java.name)
.build()
return CastOptions.Builder()
.setReceiverApplicationId(context.getString(R.string.app_id))
.setCastMediaOptions(mediaOptions)
.build()
}
روش LocalPlayerActivity
loadRemoteMedia
به روز کنید تا در هنگام بارگیری رسانه از راه دور ، ExpandedControlsActivity
نمایش دهید:
import com.google.sample.cast.refplayer.expandedcontrols.ExpandedControlsActivity
private fun loadRemoteMedia(position: Int, autoPlay: Boolean) {
if (mCastSession == null) {
return
}
val remoteMediaClient = mCastSession!!.remoteMediaClient ?: return
remoteMediaClient.registerCallback(object : RemoteMediaClient.Callback() {
override fun onStatusUpdated() {
val intent = Intent(this@LocalPlayerActivity, ExpandedControlsActivity::class.java)
startActivity(intent)
remoteMediaClient.unregisterCallback(this)
}
})
remoteMediaClient.load(MediaLoadRequestData.Builder()
.setMediaInfo(buildMediaInfo())
.setAutoplay(autoPlay)
.setCurrentTime(position.toLong()).build())
}
کلیک بر روی دکمه را اجرا کنید تا برنامه را روی دستگاه تلفن همراه خود اجرا کنید و یک ویدیو بازی کنید. شما باید کنترلر گسترش یافته را ببینید. دوباره به لیست فیلم ها بروید و هنگامی که روی Mini Controller کلیک می کنید ، کنترلر گسترش یافته دوباره بارگیری می شود. برای دیدن اعلان به دور از برنامه حرکت کنید. برای بارگیری کنترلر گسترش یافته روی تصویر اعلان کلیک کنید.
11. پشتیبانی COST Connect را اضافه کنید
کتابخانه Cast Connect به برنامه های ارسال کننده موجود اجازه می دهد تا از طریق پروتکل بازیگران با برنامه های تلویزیونی Android ارتباط برقرار کنند. Cast Connect در بالای زیرساخت های بازیگران ساخته شده است و برنامه تلویزیون Android شما به عنوان گیرنده عمل می کند.
وابستگی ها
توجه: برای اجرای CAST CONNECT ، play-services-cast-framework
باید 19.0.0
یا بالاتر باشد.
راه اندازی
برای راه اندازی برنامه Android TV ، همچنین به عنوان گیرنده Android نیز گفته می شود ، ما باید پرچم سازگار setAndroidReceiverCompatible
را در شیء LaunchOptions
تنظیم کنیم. این شیء LaunchOptions
نحوه راه اندازی گیرنده را نشان می دهد و به CastOptions
برگردانده شده توسط کلاس CastOptionsProvider
منتقل می شود. تنظیم پرچم ذکر شده در false
، گیرنده وب را برای شناسه برنامه تعریف شده در کنسول توسعه دهنده بازیگران راه اندازی می کند.
در پرونده CastOptionsProvider.kt
موارد زیر را به روش getCastOptions
اضافه کنید:
import com.google.android.gms.cast.LaunchOptions
...
val launchOptions = LaunchOptions.Builder()
.setAndroidReceiverCompatible(true)
.build()
return new CastOptions.Builder()
.setLaunchOptions(launchOptions)
...
.build()
اعتبار راه اندازی را تنظیم کنید
از طرف فرستنده ، می توانید CredentialsData
مشخص کنید تا نماینده چه کسی در جلسه باشد. credentials
رشته ای است که می تواند تعریف شده توسط کاربر باشد ، تا زمانی که برنامه ATV شما بتواند آن را درک کند. CredentialsData
فقط در هنگام راه اندازی یا پیوستن به برنامه Android TV شما منتقل می شود. اگر دوباره آن را تنظیم کنید در حالی که متصل هستید ، به برنامه تلویزیون Android شما منتقل نمی شود.
به منظور تنظیم اعتبارنامه های راه اندازی ، باید CredentialsData
تعریف شود و به شیء LaunchOptions
منتقل شود. کد زیر را به روش getCastOptions
در پرونده CastOptionsProvider.kt
خود اضافه کنید:
import com.google.android.gms.cast.CredentialsData
...
val credentialsData = CredentialsData.Builder()
.setCredentials("{\"userId\": \"abc\"}")
.build()
val launchOptions = LaunchOptions.Builder()
...
.setCredentialsData(credentialsData)
.build()
اعتبار را در LoadRequest تنظیم کنید
در صورتی که برنامه گیرنده وب و برنامه های Android TV شما به طور متفاوتی از credentials
استفاده کند ، ممکن است لازم باشد credentials
جداگانه ای را برای هر یک تعریف کنید. برای مراقبت از آن ، کد زیر را در پرونده LocalPlayerActivity.kt
خود در زیر عملکرد loadRemoteMedia
اضافه کنید:
remoteMediaClient.load(MediaLoadRequestData.Builder()
...
.setCredentials("user-credentials")
.setAtvCredentials("atv-user-credentials")
.build())
بسته به برنامه گیرنده فرستنده شما در حال ریخته گری است ، SDK اکنون به طور خودکار از کدام اعتبار برای جلسه فعلی استفاده می کند.
تست بازیگران اتصال
مراحل نصب Android TV APK در Chromecast با Google TV
- آدرس IP دستگاه تلویزیون Android خود را پیدا کنید. معمولاً تحت تنظیمات> شبکه و اینترنت> (نام شبکه ای که دستگاه شما به آن متصل است) در دسترس است. از طرف راست ، جزئیات و IP دستگاه شما را در شبکه نشان می دهد.
- از آدرس IP برای دستگاه خود استفاده کنید تا از طریق ADB با استفاده از ترمینال به آن وصل شوید:
$ adb connect <device_ip_address>:5555
- از پنجره ترمینال خود ، برای نمونه های CodeLab که در ابتدای این CodeLab بارگیری کرده اید ، به پوشه سطح بالا بروید. به عنوان مثال:
$ cd Desktop/android_codelab_src
- فایل .apk را در این پوشه در تلویزیون اندرویدی خود نصب کنید:
$ adb -s <device_ip_address>:5555 install android-tv-app.apk
- اکنون باید بتوانید برنامه ای را با نام فیلم های بازیگران در منوی برنامه های خود در دستگاه تلویزیون Android خود مشاهده کنید.
- به پروژه Android Studio خود برگردید و بر روی دکمه Run کلیک کنید تا برنامه Sender را در دستگاه تلفن همراه فیزیکی خود نصب و اجرا کنید. در گوشه سمت راست سمت راست ، روی نماد بازیگران کلیک کنید و دستگاه Android TV خود را از گزینه های موجود انتخاب کنید. اکنون باید برنامه Android TV را که در دستگاه Android TV خود راه اندازی شده است ، مشاهده کنید و در حال پخش یک ویدیو باید به شما امکان دهد با استفاده از Remote Android TV خود ، پخش ویدیویی را کنترل کنید.
12. ابزارک های بازیگران را سفارشی کنید
شما می توانید ابزارک های بازیگران را با تنظیم رنگ ها ، یک ظاهر طراحی دکمه ها ، متن و ظاهر کوچک و با انتخاب انواع دکمه ها برای نمایش ، سفارشی کنید.
به روزرسانی res/values/styles_castvideo.xml
<style name="Theme.CastVideosTheme" parent="Theme.AppCompat.Light.NoActionBar">
...
<item name="mediaRouteTheme">@style/CustomMediaRouterTheme</item>
<item name="castIntroOverlayStyle">@style/CustomCastIntroOverlay</item>
<item name="castMiniControllerStyle">@style/CustomCastMiniController</item>
<item name="castExpandedControllerStyle">@style/CustomCastExpandedController</item>
<item name="castExpandedControllerToolbarStyle">
@style/ThemeOverlay.AppCompat.ActionBar
</item>
...
</style>
مضامین سفارشی زیر را اعلام کنید:
<!-- Customize Cast Button -->
<style name="CustomMediaRouterTheme" parent="Theme.MediaRouter">
<item name="mediaRouteButtonStyle">@style/CustomMediaRouteButtonStyle</item>
</style>
<style name="CustomMediaRouteButtonStyle" parent="Widget.MediaRouter.Light.MediaRouteButton">
<item name="mediaRouteButtonTint">#EEFF41</item>
</style>
<!-- Customize Introductory Overlay -->
<style name="CustomCastIntroOverlay" parent="CastIntroOverlay">
<item name="castButtonTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Button</item>
<item name="castTitleTextAppearance">@style/TextAppearance.CustomCastIntroOverlay.Title</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Button" parent="android:style/TextAppearance">
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="TextAppearance.CustomCastIntroOverlay.Title" parent="android:style/TextAppearance.Large">
<item name="android:textColor">#FFFFFF</item>
</style>
<!-- Customize Mini Controller -->
<style name="CustomCastMiniController" parent="CastMiniController">
<item name="castShowImageThumbnail">true</item>
<item name="castTitleTextAppearance">@style/TextAppearance.AppCompat.Subhead</item>
<item name="castSubtitleTextAppearance">@style/TextAppearance.AppCompat.Caption</item>
<item name="castBackground">@color/accent</item>
<item name="castProgressBarColor">@color/orange</item>
</style>
<!-- Customize Expanded Controller -->
<style name="CustomCastExpandedController" parent="CastExpandedController">
<item name="castButtonColor">#FFFFFF</item>
<item name="castPlayButtonDrawable">@drawable/cast_ic_expanded_controller_play</item>
<item name="castPauseButtonDrawable">@drawable/cast_ic_expanded_controller_pause</item>
<item name="castStopButtonDrawable">@drawable/cast_ic_expanded_controller_stop</item>
</style>
13. تبریک می گویم
شما اکنون می دانید که چگونه یک برنامه ویدیویی را با استفاده از ابزارک های SDK Cast در Android قابل چاپ قرار دهید.
برای اطلاعات بیشتر ، به راهنمای توسعه دهنده Android Sender مراجعه کنید.