
рд╕рдбрд╝рдХ рдкрд░, рдореИрдВ рдЕрдХреНрд╕рд░ рд╕реНрдорд╛рд░реНрдЯрдлреЛрди рд╕реЗ рдСрдбрд┐рдпреЛ рдкреБрд╕реНрддрдХреЗрдВ рдФрд░ рдкреЙрдбрдХрд╛рд╕реНрдЯ рд╕реБрдирддрд╛ рд╣реВрдВред рдЬрдм рдореИрдВ рдШрд░ рдЬрд╛рддрд╛ рд╣реВрдВ, рддреЛ рдореИрдВ рдЙрдиреНрд╣реЗрдВ рдПрдВрдбреНрд░реЙрдЗрдб рдЯреАрд╡реА рдпрд╛ Google рд╣реЛрдо рдкрд░ рд╕реБрдирдирд╛ рдЬрд╛рд░реА рд░рдЦрдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рд▓реЗрдХрд┐рди рд╕рднреА рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рдХрд╛ рд╕рдорд░реНрдерди рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВред рдФрд░ рдпрд╣ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред
рдкрд┐рдЫрд▓реЗ 3 рд╡рд░реНрд╖реЛрдВ рдореЗрдВ Google рдХреЗ рдЖрдВрдХрдбрд╝реЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдПрдВрдбреНрд░реЙрдЗрдб рдЯреАрд╡реА рдкрд░ рдЙрдкрдХрд░рдгреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ 4 рдЧреБрдирд╛ рдмрдврд╝ рдЧрдИ рд╣реИ, рдФрд░ рд╡рд┐рдирд┐рд░реНрдорд╛рдг рднрд╛рдЧреАрджрд╛рд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрд╣рд▓реЗ рд╣реА рд╕реМ рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рдЧрдИ рд╣реИ: "рд╕реНрдорд╛рд░реНрдЯ" рдЯреАрд╡реА, рд╕реНрдкреАрдХрд░, рд╕реЗрдЯ-рдЯреЙрдк рдмреЙрдХреНрд╕ред рдпреЗ рд╕рднреА Chromecast рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди рдмрд╛рдЬрд╛рд░ рдореЗрдВ рдЕрднреА рднреА рдХрдИ рдЕрдиреБрдкреНрд░рдпреЛрдЧ рд╣реИрдВ рдЬреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрд╕рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХреА рдХрдореА рд░рдЦрддреЗ рд╣реИрдВред
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдореИрдВ рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдВрдбреНрд░реЙрдЗрдб рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рдЕрдкрдиреЗ рдЕрдиреБрднрд╡ рдХреЛ рд╕рд╛рдЭрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред
рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ
рдпрджрд┐ рдпрд╣ рдЖрдкрдХрд╛ рдкрд╣рд▓реА рдмрд╛рд░ "Chromecast" рд╢рдмреНрдж рд╕реБрди рд░рд╣рд╛ рд╣реИ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдмрддрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдЙрдкрдпреЛрдЧ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ, рдпрд╣ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦрддрд╛ рд╣реИ:
- рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдпрд╛ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕рдВрдЧреАрдд рд╕реБрдирддрд╛ рд╣реИ рдпрд╛ рд╡реАрдбрд┐рдпреЛ рджреЗрдЦрддрд╛ рд╣реИред
- Chromecast рдбрд┐рд╡рд╛рдЗрд╕ рд╕реНрдерд╛рдиреАрдп рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ рджрд┐рдЦрд╛рдИ рджреЗрддрд╛ рд╣реИред
- рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдореЗрдВ рдПрдХ рд╕рдВрдмрдВрдзрд┐рдд рдмрдЯрди рджрд┐рдЦрд╛рдИ рджреЗрдирд╛ рдЪрд╛рд╣рд┐рдПред
- рдЙрд╕ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░рдХреЗ, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕реВрдЪреА рд╕реЗ рд╡рд╛рдВрдЫрд┐рдд рдбрд┐рд╡рд╛рдЗрд╕ рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдиреЗрдХреНрд╕рд╕ рдкреНрд▓реЗрдпрд░, рдПрдВрдбреНрд░реЙрдЗрдб рдЯреАрд╡реА рдпрд╛ рдПрдХ рд╕реНрдорд╛рд░реНрдЯ рд╕реНрдкреАрдХрд░ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
- рдЗрд╕ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рд╕рд╛рде рдЖрдЧреЗ рдкреНрд▓реЗрдмреИрдХ рдЬрд╛рд░реА рд╣реИред

рддрдХрдиреАрдХреА рд░реВрдк рд╕реЗ, рдирд┐рдореНрди рдЬреИрд╕рд╛ рдХреБрдЫ рд╣реЛрддрд╛ рд╣реИ:
- Google рд╕реЗрд╡рд╛ рдкреНрд░рд╕рд╛рд░рдг рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╕реНрдерд╛рдиреАрдп рдиреЗрдЯрд╡рд░реНрдХ рдкрд░ Chromecast рдЙрдкрдХрд░рдгреЛрдВ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреА рдирд┐рдЧрд░рд╛рдиреА рдХрд░рддреА рд╣реИред
- рдпрджрд┐ MediaRouter рдЖрдкрдХреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╕реЗ рдЬреБрдбрд╝рд╛ рд╣реИ, рддреЛ рдЖрдкрдХреЛ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдШрдЯрдирд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛрдЧреАред
- рдЬрдм рдХреЛрдИ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдПрдХ рдХрд╛рд╕реНрдЯ рдбрд┐рд╡рд╛рдЗрд╕ рдХрд╛ рдЪрдпрди рдХрд░рддрд╛ рд╣реИ рдФрд░ рдЙрд╕рд╕реЗ рдХрдиреЗрдХреНрдЯ рд╣реЛрддрд╛ рд╣реИ, рддреЛ рдПрдХ рдирдпрд╛ рдореАрдбрд┐рдпрд╛ рд╕рддреНрд░ (CastSession) рдЦреБрд▓рддрд╛ рд╣реИред
- рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрдирд╛рдП рдЧрдП рд╕рддреНрд░ рдореЗрдВ, рд╣рдо рдкреНрд▓реЗрдмреИрдХ рдХреЗ рд▓рд┐рдП рд╕рд╛рдордЧреНрд░реА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВрдЧреЗред
рдпрд╣ рдмрд╣реБрдд рд╕рд░рд▓ рд▓рдЧрддрд╛ рд╣реИред
рдПрдХреАрдХрд░рдг
Google рдХреЗ рдкрд╛рд╕ рдЕрдкрдирд╛ Chromecast SDK рд╣реИ , рд▓реЗрдХрд┐рди рдпрд╣ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝реАрдХрд░рдг рдореЗрдВ рдЦрд░рд╛рдм рд░реВрдк рд╕реЗ рдХрд╡рд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдХреЛрдб рдХреЛ рдмрд╛рдзрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕рд▓рд┐рдП, рдХрдИ рдЪреАрдЬреЛрдВ рдХреЛ рдЯрд╛рдЗрдк рдХрд░рдХреЗ рдЬрд╛рдВрдЪрдирд╛ рдкрдбрд╝рддрд╛ рдерд╛ред рдЪрд▓реЛ рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рдорд┐рд▓рддрд╛ рд╣реИред
рдкреНрд░рд╛рд░рдВрдн
рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ рд╣рдореЗрдВ рдХрд╛рд╕реНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдлреНрд░реЗрдорд╡рд░реНрдХ рдФрд░ рдореАрдбрд┐рдпрд╛ рд░рд╛рдЙрдЯрд░ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
implementation "com.google.android.gms:play-services-cast-framework:16.1.0" implementation "androidx.mediarouter:mediarouter:1.0.0"
рдлрд┐рд░ рдХрд╛рд╕реНрдЯ рдлреНрд░реЗрдорд╡рд░реНрдХ рдХреЛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ (рдЙрд╕ рдкрд░ рдмрд╛рдж рдореЗрдВ), рдФрд░ рд╕рдорд░реНрдерд┐рдд рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдХреЗ рдкреНрд░рдХрд╛рд░ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред рдпрд╣реА рд╣реИ, рдЕрдЧрд░ рд╣рдорд╛рд░рд╛ рдЖрд╡реЗрджрди рдХреЗрд╡рд▓ рд╡реАрдбрд┐рдпреЛ рдЪрд▓рд╛рддрд╛ рд╣реИ, рддреЛ Google рд╣реЛрдо рдХреЙрд▓рдо рдкрд░ рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХрд░рдирд╛ рдЕрд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рдФрд░ рдпрд╣ рдЙрдкрдХрд░рдгреЛрдВ рдХреА рд╕реВрдЪреА рдореЗрдВ рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, OptionsProvider рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдмрдирд╛рдПрдВ:
class CastOptionsProvider: OptionsProvider { override fun getCastOptions(context: Context): CastOptions { return CastOptions.Builder() .setReceiverApplicationId(BuildConfig.CHROMECAST_APP_ID) .build() } override fun getAdditionalSessionProviders(context: Context): MutableList<SessionProvider>? { return null } }
рдФрд░ рдЗрд╕реЗ рдШреЛрд╖рдгрд╛рдкрддреНрд░ рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд░реЗрдВ:
<meta-data android:name="com.google.android.gms.cast.framework.OPTIONS_PROVIDER_CLASS_NAME" android:value="your.app.package.CastOptionsProvider" />
рдЖрд╡реЗрджрди рд░рдЬрд┐рд╕реНрдЯрд░ рдХрд░реЗрдВ
Chromecast рдХреЛ рд╣рдорд╛рд░реЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЗрд╕реЗ Google рдХрд╛рд╕реНрдЯ рдПрд╕рдбреАрдХреЗ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдХрдВрд╕реЛрд▓ рдореЗрдВ рдкрдВрдЬреАрдХреГрдд рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред рдЗрд╕рдХреЗ рд▓рд┐рдП Chromecast рдбреЗрд╡рд▓рдкрд░ рдЦрд╛рддреЗ (Google Play рдбреЗрд╡рд▓рдкрд░ рдЦрд╛рддреЗ рдХреЗ рд╕рд╛рде рднреНрд░рдорд┐рдд рди рд╣реЛрдирд╛) рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдкрдВрдЬреАрдХрд░рдг рдХрд░рддреЗ рд╕рдордп, рдЖрдкрдХреЛ $ 5 рдХрд╛ рдПрдХ рдмрд╛рд░ рд╢реБрд▓реНрдХ рджреЗрдирд╛ рд╣реЛрдЧрд╛ред рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЛ рдкреНрд░рдХрд╛рд╢рд┐рдд рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдЖрдкрдХреЛ рдереЛрдбрд╝рд╛ рдЗрдВрддрдЬрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред
рдХрдВрд╕реЛрд▓ рдореЗрдВ, рдЖрдк рд╕реНрдХреНрд░реАрди рдХреЗ рд╕рд╛рде рдЙрдкрдХрд░рдгреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рд╕реНрдЯ рдкреНрд▓реЗрдпрд░ рдХреА рдЙрдкрд╕реНрдерд┐рддрд┐ рдХреЛ рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдХреЗ рднреАрддрд░ рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдПрдирд╛рд▓рд┐рдЯрд┐рдХреНрд╕ рджреЗрдЦ рд╕рдХрддреЗ рд╣реИрдВред
MediaRouteFramework рдПрдХ рддрдВрддреНрд░ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдкрд╛рд╕ рд╕рднреА рджреВрд░рд╕реНрде рдкреНрд▓реЗрдмреИрдХ рдЙрдкрдХрд░рдгреЛрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдпрд╣ рди рдХреЗрд╡рд▓ рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдмрд▓реНрдХрд┐ рддреАрд╕рд░реЗ рдкрдХреНрд╖ рдХреЗ рдкреНрд░реЛрдЯреЛрдХреЙрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджреВрд░рд╕реНрде рдбрд┐рд╕реНрдкреНрд▓реЗ рдФрд░ рд╕реНрдкреАрдХрд░ рднреА рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ Chromecast рдХреА рдХрд┐рддрдиреА рд░реБрдЪрд┐ рд╣реИред

MediaRouteFramework рдореЗрдВ рдПрдХ рджреГрд╢реНрдп рд╣реИ рдЬреЛ рдореАрдбрд┐рдпрд╛ рд╕реНрдХреВрдЯрд░ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИред рдЗрд╕реЗ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рджреЛ рддрд░реАрдХреЗ рд╣реИрдВ:
1) рдореЗрдиреВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ:
<?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/menu_media_route" android:title="@string/cast" app:actionProviderClass="androidx.mediarouter.app.MediaRouteActionProvider" app:showAsAction="always"/> ... </menu>
2) рд╡рд╛рдпрд╛ рд▓реЗрдЖрдЙрдЯ:
<androidx.mediarouter.app.MediaRouteButton android:id="@+id/mediaRouteButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:mediaRouteTypes="user"/>
рдФрд░ рдХреЛрдб рд╕реЗ рдЖрдкрдХреЛ рдмрд╕ CastButtonFactory рдореЗрдВ рдмрдЯрди рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рддрдм рдореАрдбрд┐рдпрд╛ рд╕реНрдХреВрдЯрд░ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХреЛ рдЗрд╕рдореЗрдВ рдбрд╛рд▓рд╛ рдЬрд╛рдПрдЧрд╛:
CastButtonFactory.setUpMediaRouteButton(applicationContext, view.mediaRouteButton)
рдЕрдм рдЬрдм рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрдВрдЬреАрдХреГрдд рд╣реЛ рдЧрдпрд╛ рд╣реИ рдФрд░ MediaRouter рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдЖрдк рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рдбрд┐рд╡рд╛рдЗрд╕реЛрдВ рд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдиреНрд╣реЗрдВ рд╕рддреНрд░ рдЦреЛрд▓ рд╕рдХрддреЗ рд╣реИрдВред
рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рддреАрди рдореБрдЦреНрдп рдкреНрд░рдХрд╛рд░ рдХреА рд╕рд╛рдордЧреНрд░реА рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рддрд╛ рд╣реИ:
- рдСрдбрд┐рдпреЛ;
- рд╡реАрдбрд┐рдпреЛ;
- рдлреЛрдЯреЛред
рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рд╕реЗрдЯрд┐рдВрдЧреНрд╕, рдЬреИрд╕реЗ рдХрд┐ рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдФрд░ рдХрд╛рд╕реНрдЯ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рдЦрд┐рд▓рд╛рдбрд╝реА рдХрд╛ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
CastSession
рдЗрд╕рд▓рд┐рдП, рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рд╡рд╛рдВрдЫрд┐рдд рдбрд┐рд╡рд╛рдЗрд╕ рдХрд╛ рдЪрдпрди рдХрд┐рдпрд╛, CastFramework рдиреЗ рдПрдХ рдирдпрд╛ рд╕рддреНрд░ рдЦреЛрд▓рд╛ред рдЕрдм рд╣рдорд╛рд░рд╛ рдХрд╛рдо рдЗрд╕ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рджреЗрдирд╛ рдФрд░ рдкреНрд▓реЗрдмреИрдХ рдХреЗ рд▓рд┐рдП рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рдЬрд╛рдирдХрд╛рд░реА рджреЗрдирд╛ рд╣реИред
рд╕рддреНрд░ рдХреА рд╡рд░реНрддрдорд╛рди рд╕реНрдерд┐рддрд┐ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдФрд░ рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рд╛рдЗрди рдЕрдк рдХрд░реЗрдВ, SessionManager рдСрдмреНрдЬреЗрдХреНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ:
private val mediaSessionListener = object : SessionManagerListener<CastSession> { override fun onSessionStarted(session: CastSession, sessionId: String) { currentSession = session
рдФрд░ рд╣рдо рдпрд╣ рднреА рдкрддрд╛ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ рдХреНрдпрд╛ рдЗрд╕ рд╕рдордп рдПрдХ рдЦреБрд▓рд╛ рд╕рддреНрд░ рд╣реИ:
val currentSession: CastSession? = sessionManager.currentCastSession
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рджреЛ рдореБрдЦреНрдп рд╢рд░реНрддреЗрдВ рд╣реИрдВ рдЬрд┐рдирдХреЗ рддрд╣рдд рд╣рдо рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рд╢реБрд░реВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- рд╕рддреНрд░ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЦреБрд▓рд╛ рд╣реИред
- рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╕рд╛рдордЧреНрд░реА рд╣реИред
рдЗрди рджреЛ рдШрдЯрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдкрд░, рд╣рдо рд╕реНрдерд┐рддрд┐ рдХреА рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ рдпрджрд┐ рд╕рдм рдХреБрдЫ рдХреНрд░рдо рдореЗрдВ рд╣реИ, рддреЛ рдХрд╛рд╕реНрдЯрд┐рдВрдЧ рд╢реБрд░реВ рдХрд░реЗрдВред
рдврд▓рд╛рдИ
рдЕрдм рдЬрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдХреНрдпрд╛ рдбрд╛рд▓рдирд╛ рд╣реИ рдФрд░ рдХрд╣рд╛рдВ рдбрд╛рд▓рдирд╛ рд╣реИ, рд╣рдо рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд рдкрд░ рдЖрдЧреЗ рдмрдврд╝ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдиреНрдп рдмрд╛рддреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, CastSession рдореЗрдВ рдПрдХ RemoteMediaClient рдСрдмреНрдЬреЗрдХреНрдЯ рд╣реИ рдЬреЛ рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдХреА рдкреНрд▓реЗрдмреИрдХ рд╕реНрдерд┐рддрд┐ рдХреЗ рд▓рд┐рдП рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИред рд╣рдо рдЙрд╕рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред
рдЪрд▓рд┐рдП MediaMetadata рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬрд╣рд╛рдБ рд▓реЗрдЦрдХ, рдПрд▓реНрдмрдо, рдЖрджрд┐ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд╕рдВрдЧреНрд░рд╣реАрдд рдХреА рдЬрд╛рдПрдЧреАред рдпрд╣ рдмрд╣реБрдд рд╣рдж рддрдХ рд╡реИрд╕рд╛ рд╣реА рд╣реИ рдЬреИрд╕рд╛ рд╣рдо рд╕реНрдерд╛рдиреАрдп рдкреНрд▓реЗрдмреИрдХ рд╢реБрд░реВ рдХрд░рдиреЗ рдкрд░ MediaSession рдХреЛ рд╣рд╕реНрддрд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВред
val mediaMetadata = MediaMetadata(MediaMetadata.MEDIA_TYPE_MUSIC_TRACK ).apply { putString(MediaMetadata.KEY_TITLE, тАЬIn CтАЭ) putString(MediaMetadata.KEY_ARTIST, тАЬTerry RileyтАЭ) mediaContent?.metadata?.posterUrl?.let { poster -> addImage(WebImage(Uri.parse(тАЬhttps:
MediaMetadata рдореЗрдВ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдкреИрд░рд╛рдореАрдЯрд░ рд╣реИрдВ, рдФрд░ рдЙрдиреНрд╣реЗрдВ рдкреНрд░рд▓реЗрдЦрди рдореЗрдВ рджреЗрдЦрдирд╛ рдмреЗрд╣рддрд░ рд╣реИред рдореБрдЭреЗ рд╕реБрдЦрдж рдЖрд╢реНрдЪрд░реНрдп рд╣реБрдЖ рдХрд┐ рдЖрдк рдмрд┐рдЯрдореИрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ WebImage рдХреЗ рдЕрдВрджрд░ рд▓рд┐рдВрдХ рджреНрд╡рд╛рд░рд╛ рдПрдХ рдЫрд╡рд┐ рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВред
MediaInfo рдСрдмреНрдЬреЗрдХреНрдЯ рд╕рд╛рдордЧреНрд░реА рдореЗрдЯрд╛рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рд░рдЦрддрд╛ рд╣реИ рдФрд░ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░реЗрдЧрд╛ рдХрд┐ рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдХрд╣рд╛рдБ рд╕реЗ рдЖрддреА рд╣реИ, рдпрд╣ рдХрд┐рд╕ рдкреНрд░рдХрд╛рд░ рдХреА рд╣реИ, рдЗрд╕реЗ рдХреИрд╕реЗ рдЦреЗрд▓реЗрдВ:
val mediaInfo = MediaInfo.Builder(тАЬhttps:
рдЖрдкрдХреЛ рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВ рдХрд┐ MIME рд╡рд┐рдирд┐рд░реНрджреЗрд╢рди рдХреЗ рдЕрдиреБрд╕рд╛рд░ contentType рдПрдХ рдкреНрд░рдХрд╛рд░ рдХреА рд╕рд╛рдордЧреНрд░реА рд╣реИред
рдЖрдк рд╡рд┐рдЬреНрдЮрд╛рдкрди рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдХреЛ MediaInfo рдореЗрдВ рднреА рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
- setAdBreakClips - AdBreakClipInfo рд╡рд┐рдЬреНрдЮрд╛рдкрдиреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рд╕рд╛рдордЧреНрд░реА, рд╢реАрд░реНрд╖рдХ, рд╕рдордп рдФрд░ рдЙрд╕ рд▓рд┐рдВрдХ рдХреЗ рд╕рд╛рде рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ рдЬрд┐рд╕рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╡рд┐рдЬреНрдЮрд╛рдкрди рдЫреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИред
- setAdBreaks - рд╡рд┐рдЬреНрдЮрд╛рдкрди рдЖрд╡реЗрд╖рдг рдХреЗ рд▓реЗрдЖрдЙрдЯ рдФрд░ рд╕рдордп рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реАред
MediaLoadOptions рдореЗрдВ рд╣рдо рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рдореАрдбрд┐рдпрд╛ рд╕реНрдЯреНрд░реАрдо (рдЧрддрд┐, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╕реНрдерд┐рддрд┐) рдХреЛ рдХреИрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░реЗрдВрдЧреЗред рдкреНрд░рд▓реЗрдЦрди рдпрд╣ рднреА рдХрд╣рддрд╛ рд╣реИ рдХрд┐ setCredentials рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЖрдк рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рд╢реАрд░реНрд╖ рд▓реЗрдЦ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди Chromecast рдХреЗ рдореЗрд░реЗ рдЕрдиреБрд░реЛрдзреЛрдВ рдореЗрдВ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рд▓рд┐рдП рдШреЛрд╖рд┐рдд рдлрд╝реАрд▓реНрдб рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдереЗред
val mediaLoadOptions = MediaLoadOptions.Builder() .setPlayPosition(position!!) .setAutoplay(true) .setPlaybackRate(playbackSpeed) .setCredentials(context.getString(R.string.bearer_token, authGateway.authState.accessToken!!)) .setCredentialsType(context.getString(R.string.authorization_header_key)) .build()
рдПрдХ рдмрд╛рд░ рд╕рдм рдХреБрдЫ рддреИрдпрд╛рд░ рд╣реЛ рдЬрд╛рдиреЗ рдкрд░, рд╣рдо рд╕рднреА рдбреЗрдЯрд╛ рдХреЛ RemoteMediaClient рдХреЛ рджреЗ рд╕рдХрддреЗ рд╣реИрдВ, рдФрд░ Chromecast рдЦреЗрд▓рдирд╛ рд╢реБрд░реВ рдХрд░ рджреЗрдЧрд╛ред рд╕реНрдерд╛рдиреАрдп рдкреНрд▓реЗрдмреИрдХ рдХреЛ рд░реЛрдХрдирд╛ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣реИред
val remoteMediaClient = currentSession!!.remoteMediaClient remoteMediaClient.load(mediaInfo, mediaLoadOptions)
рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд┐рдВрдЧ
рд╡реАрдбрд┐рдпреЛ рдЪрд▓рдирд╛ рд╢реБрд░реВ рд╣реБрдЖ рдФрд░ рдлрд┐рд░ рдХреНрдпрд╛? рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЯреАрд╡реА рдХреЛ рд░реЛрдХ рджреЗрддрд╛ рд╣реИ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛? Chromecast рдХреА рдУрд░ рд╕реЗ рдШрдЯрдирд╛рдУрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдиреЗ рдХреЗ рд▓рд┐рдП, RemoteMediaClient рдореЗрдВ рдХреЙрд▓рдмреИрдХ рд╣реИрдВ:
private val castStatusCallback = object : RemoteMediaClient.Callback() { override fun onStatusUpdated() {
рд╡рд░реНрддрдорд╛рди рдкреНрд░рдЧрддрд┐ рдХреЛ рдЬрд╛рдирдирд╛ рднреА рд╕рд░рд▓ рд╣реИ:
val periodMills = 1000L remoteMediaClient.addProgressListener( RemoteMediaClient.ProgressListener { progressMills, durationMills ->
рдореМрдЬреВрджрд╛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд╕рд╛рде рдПрдХреАрдХрд░рдг рдХрд╛ рдЕрдиреБрднрд╡
рдЬрд┐рд╕ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░ рдореИрдВ рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рдерд╛, рдЙрд╕рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рддреИрдпрд╛рд░ рдореАрдбрд┐рдпрд╛ рдкреНрд▓реЗрдпрд░ рдерд╛ред рд▓рдХреНрд╖реНрдп рдЗрд╕рдореЗрдВ Chromecast рд╕рдорд░реНрдерди рдХреЛ рдПрдХреАрдХреГрдд рдХрд░рдирд╛ рдерд╛ред рдореАрдбрд┐рдпрд╛ рдкреНрд▓реЗрдпрд░ рд╕реНрдЯреЗрдЯ рдорд╢реАрди рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдерд╛, рдФрд░ рдкрд╣рд▓рд╛ рд╡рд┐рдЪрд╛рд░ рдПрдХ рдирдП рд░рд╛рдЬреНрдп рдХреЛ рдЬреЛрдбрд╝рдирд╛ рдерд╛: "рдХрд╛рд╕реНрдЯрд┐рдВрдЧрд╕реНрдЯреИрдЯ"ред рд▓реЗрдХрд┐рди рдЗрд╕ рд╡рд┐рдЪрд╛рд░ рдХреЛ рддреБрд░рдВрдд рдЕрд╕реНрд╡реАрдХрд╛рд░ рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдХреНрдпреЛрдВрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЦрд┐рд▓рд╛рдбрд╝реА рд░рд╛рдЬреНрдп рдкреНрд▓реЗрдмреИрдХ рд╕реНрдерд┐рддрд┐ рдХреЛ рджрд░реНрд╢рд╛рддрд╛ рд╣реИ, рдФрд░ рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ ExoPlayer рдпрд╛ ChromeCast рдХреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд░реВрдк рдореЗрдВ рдХреНрдпрд╛ рдХрд╛рд░реНрдп рдХрд░рддрд╛ рд╣реИред
рдлрд┐рд░ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ "рдЬреАрд╡рди рдЪрдХреНрд░" рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдФрд░ рдкреНрд░рд╕рдВрд╕реНрдХрд░рдг рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреА рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рдкреНрд░рдгрд╛рд▓реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╡рд┐рдЪрд╛рд░ рдЖрдпрд╛ред рд╕рднреА рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреЛ рдЦрд┐рд▓рд╛рдбрд╝реА рдХрд╛ рджрд░реНрдЬрд╛ рдкреНрд░рд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ: рдкреНрд▓реЗ, рдкреЙрдЬрд╝ рдЖрджрд┐ред - рд▓реЗрдХрд┐рди рдХреЗрд╡рд▓ рдкреНрд░рдореБрдЦ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдХреЛ рдЦреЗрд▓реЗрдВрдЧреЗред

рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЗрд╕ рдЦрд┐рд▓рд╛рдбрд╝реА рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рдЬреИрд╕рд╛ рдХреБрдЫ рд╣реИ:
interface Player { val isPlaying: Boolean val isReleased: Boolean val duration: Long var positionInMillis: Long var speed: Float var volume: Float var loop: Boolean fun addListener(listener: PlayerCallback) fun removeListener(listener: PlayerCallback): Boolean fun getListeners(): MutableSet<PlayerCallback> fun prepare(mediaContent: MediaContent) fun play() fun pause() fun release() interface PlayerCallback { fun onPlaying(currentPosition: Long) fun onPaused(currentPosition: Long) fun onPreparing() fun onPrepared() fun onLoadingChanged(isLoading: Boolean) fun onDurationChanged(duration: Long) fun onSetSpeed(speed: Float) fun onSeekTo(fromTimeInMillis: Long, toTimeInMillis: Long) fun onWaitingForNetwork() fun onError(error: String?) fun onReleased() fun onPlayerProgress(currentPosition: Long) } }
рдЗрд╕рдХреЗ рдЕрдВрджрд░ рдЗрддрдиреЗ рд╕рд╛рд░реЗ рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рд╕реНрдЯреЗрдЯ рдорд╢реАрди рд╣реЛрдЧреА:
- рдЦрд╛рд▓реА - рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛ рдореЗрдВ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗред
- рддреИрдпрд╛рд░реА - рдЦрд┐рд▓рд╛рдбрд╝реА рдореАрдбрд┐рдпрд╛ рд╕рд╛рдордЧреНрд░реА рдХреЗ рдкреНрд▓реЗрдмреИрдХ рдХреА рд╢реБрд░реБрдЖрдд рдХрд░рддрд╛ рд╣реИред
- рддреИрдпрд╛рд░ - рдореАрдбрд┐рдпрд╛ рдЕрдкрд▓реЛрдб рд╣реИ рдФрд░ рдЦреЗрд▓рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред
- рдмрдЬрд╛рдирд╛
- рд░реЛрдХрд╛ рдЧрдпрд╛
- рдкреНрд░рддреАрдХреНрд╖рд╛рд░рдд рдиреЗрдЯрд╡рд░реНрдХ
- рддреНрд░реБрдЯрд┐

рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рд╕реНрдерд╛ рдХреЗ рджреМрд░рд╛рди рдкреНрд░рддреНрдпреЗрдХ рд░рд╛рдЬреНрдп рдиреЗ рдПрдХреНрд╕реЛрдкреНрд▓реЗрдпрд░ рдореЗрдВ рдПрдХ рдЖрджреЗрд╢ рдЬрд╛рд░реА рдХрд┐рдпрд╛ рдерд╛ред рдЕрдм рдпрд╣ рдЦреЗрд▓рдиреЗ рд╡рд╛рд▓реЗ рдкреНрд░рддрд┐рдирд┐рдзрд┐рдпреЛрдВ рдХреА рд╕реВрдЪреА рдХреЛ рдХрдорд╛рдВрдб рдЬрд╛рд░реА рдХрд░реЗрдЧрд╛, рдФрд░ "рд▓реАрдб" рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдЗрд╕реЗ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдЧрд╛ред рдЪреВрдВрдХрд┐ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рд╕рднреА рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЗ рдЗрдВрдЯрд░рдлрд╝реЗрд╕ рд╕реЗ рднреА рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рд▓рд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ рддреЛ рдЕрд▓рдЧ рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рддрдм рд╕рд╛рд░ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
abstract class PlayingDelegate( protected val playerCallback: Player.PlayerCallback, var isLeading: Boolean = false ) : Player { fun setIsLeading(isLeading: Boolean, positionMills: Long, isPlaying: Boolean) { this.isLeading = isLeading if (isLeading) { onLeading(positionMills, isPlaying) } else { onDormant() } } final override fun addListener(listener: Player.PlayerCallback) {
рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЗрдВрдЯрд░рдлреЗрд╕ рдХреЛ рд╕рд░рд▓ рдмрдирд╛рдпрд╛ред рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдХреБрдЫ рдФрд░ рдШрдЯрдирд╛рдПрдБ рд╣реИрдВред
рдкреНрд░рдЬрдирди рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреЗ рд░реВрдк рдореЗрдВ рдХрдИ рдкреНрд░рддрд┐рдирд┐рдзрд┐ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред Chromecast рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦ рд╕рдХрддрд╛ рд╣реИ:
ChromeCastDelegate.kt class ChromeCastDelegate( private val context: Context, private val castCallback: ChromeCastListener, playerCallback: Player.PlayerCallback ) : PlayingDelegate(playerCallback) { companion object { private const val CONTENT_TYPE_VIDEO = "videos/mp4" private const val CONTENT_TYPE_AUDIO = "audio/mp3" private const val PROGRESS_DELAY_MILLS = 500L } interface ChromeCastListener { fun onCastStarted() fun onCastStopped() } private var sessionManager: SessionManager? = null private var currentSession: CastSession? = null private var mediaContent: MediaContent? = null private var currentPosition: Long = 0 private val mediaSessionListener = object : SessionManagerListener<CastSession> { override fun onSessionStarted(session: CastSession, sessionId: String) { currentSession = session castCallback.onCastStarted() } override fun onSessionEnding(session: CastSession) { currentPosition = session.remoteMediaClient?.approximateStreamPosition ?: currentPosition stopCasting() } override fun onSessionResumed(session: CastSession, wasSuspended: Boolean) { currentSession = session castCallback.onCastStarted() } override fun onSessionStartFailed(session: CastSession, p1: Int) { stopCasting() } override fun onSessionEnded(session: CastSession, p1: Int) {
рдкреНрд░рдЬрдирди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдПрдХ рдЖрджреЗрд╢ рджреЗрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рд╣рдореЗрдВ рдЕрдЧреНрд░рдгреА рдкреНрд░рддрд┐рдирд┐рдзрд┐ рдкрд░ рдирд┐рд░реНрдгрдп рд▓реЗрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЙрдиреНрд╣реЗрдВ рдЦрд┐рд▓рд╛рдбрд╝реА рдХреА рдкреНрд░рд╛рдердорд┐рдХрддрд╛ рдХреЗ рдХреНрд░рдо рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдЙрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рд░реЗрдбреАрдлреНрд▓реЛрд░рд┐рдВрдЧ () рд╡рд┐рдзрд┐ рдореЗрдВ рдЕрдкрдиреА рддрддреНрдкрд░рддрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рджреЗ рд╕рдХрддрд╛ рд╣реИред рдкреВрд░рд╛ рдирдореВрдирд╛ рдХреЛрдб GitHub рдкрд░ рджреЗрдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ ред
рдХреНрдпрд╛ рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рдХреЗ рдмрд╛рдж рдЬреАрд╡рди рд╣реИ

рдЬрдм рдореИрдВрдиреЗ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рдХреНрд░реЛрдордХрд╛рд╕реНрдЯ рд╕рдорд░реНрдерди рдХреЛ рдПрдХреАрдХреГрдд рдХрд┐рдпрд╛, рддреЛ рдореЗрд░реЗ рд▓рд┐рдП рдШрд░ рдкрд░ рдЖрдирд╛ рдФрд░ рд╣реЗрдбрдлреЛрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рди рдХреЗрд╡рд▓ Google рдкреБрд╕реНрддрдХреЛрдВ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ, рдмрд▓реНрдХрд┐ рдСрдбрд┐рдпреЛ рдкреБрд╕реНрддрдХреЛрдВ рдХрд╛ рдЖрдирдВрдж рд▓реЗрдирд╛ рдЕрдзрд┐рдХ рд╕реБрдЦрдж рд╣реЛ рдЧрдпрд╛ред рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд▓рд┐рдП, рд╡рд┐рднрд┐рдиреНрди рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдореЗрдВ рдЦрд┐рд▓рд╛рдбрд╝рд┐рдпреЛрдВ рдХрд╛ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рд░ рдЬрдЧрд╣ рдЙрдЪрд┐рдд рдирд╣реАрдВ рд╣реЛрдЧрд╛ред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реА рд╡рд╛рд╕реНрддреБрдХрд▓рд╛ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдКрдкрд░ рдЖрдпрд╛ред рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рд▓реЗрдЦ рдЙрдкрдпреЛрдЧреА рдерд╛, рдФрд░ рдирд┐рдХрдЯ рднрд╡рд┐рд╖реНрдп рдореЗрдВ рдФрд░ рдЕрдзрд┐рдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рд╣реЛрдВрдЧреЗ рдЬреЛ рдбрд┐рдЬрд┐рдЯрд▓ рд╡рд╛рддрд╛рд╡рд░рдг рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ!