package Ġfr . gro g gy . race control . tv . ui . player Ċ Ċ import Ġandroid . util . Log Ċ import Ġandroid . view . View Ċ import Ġandroid . widget . TextView Ċ import Ġandroidx . core . content . Context Compat Ċ import Ġandroidx . fragment . app . Fragment Activity Ċ import Ġandroidx . lean back . media . Playback Transport Control Gl ue Ċ import Ġandroidx . lean back . media . Player Adapter Ċ import Ġandroidx . lean back . widget .* Ċ import Ġcom . google . android . ex op layer 2 . C Ċ import Ġcom . google . android . ex op layer 2 . Format Ċ import Ġcom . google . android . ex op layer 2 . Simple Exo Player Ċ import Ġcom . google . android . ex op layer 2 . analytics . Analytics Listener Ċ import Ġcom . google . android . ex op layer 2 . analytics . Analytics Listener . Event Time Ċ import Ġcom . google . android . ex op layer 2 . ext . lean back . Lean back Player Adapter Ċ import Ġcom . google . android . ex op layer 2 . source . Media Load Data Ċ import Ġcom . google . android . ex op layer 2 . source . Track Group Array Ċ import Ġcom . google . android . ex op layer 2 . text . Text Output Ċ import Ġcom . google . android . ex op layer 2 . track selection . Default Track Selector Ċ import Ġcom . google . android . ex op layer 2 . track selection . Track Selection Array Ċ import Ġfr . gro g gy . race control . tv . R Ċ import Ġkotlin . math . max Ċ import Ġkotlin . math . min Ċ import Ġkotlin . math . round ToInt Ċ Ċ class ĠEx o Player Playback Transport Control Gl ue ( ĊĠĠĠ Ġprivate Ġval Ġactivity : ĠFragment Activity , ĊĠĠĠ Ġprivate Ġval Ġplayer : ĠSimple Exo Player , ĊĠĠĠ Ġprivate Ġval Ġtrack Selector : ĠDefault Track Selector Ċ ) Ġ: ĠPlay back Transport Control Gl ue < Lean back Player Adapter >( ĊĠĠĠ Ġactivity , ĊĠĠĠ ĠLe an back Player Adapter ( activity , Ġplayer , Ġ 1 _ 0 0 0 ) Ċ ), ĠAnalytics Listener Ġ{ ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġprivate Ġval ĠTAG Ġ= ĠEx o Player Playback Transport Control Gl ue :: class . simple Name ĊĊĠĠĠĠĠĠĠ Ġprivate Ġconst Ġval ĠDEFAULT _ SEEK _ OFFSET Ġ= Ġ 1 5 _ 0 0 0 L ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġre wind Action Ġ= ĠPlay back Controls Row . Rew ind Action ( activity ) ĊĠĠĠ Ġprivate Ġval Ġfast Format Action Ġ= ĠPlay back Controls Row . Fast Forward Action ( activity ) ĊĠĠĠ Ġprivate Ġval Ġselect Audio Action Ġ= ĠAction ( ĊĠĠĠĠĠĠĠ ĠAction . NO _ ID , ĊĠĠĠĠĠĠĠ Ġactivity . getString ( R . string . audio _ selection _ dialog _ title ), ĊĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠ ĠContext Compat . get Drawable ( context , ĠR . drawable . lb _ ic _ search _ mic _ out ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġprivate Ġval Ġresolution Selection Action Ġ= ĠAction ( ĊĠĠĠĠĠĠĠ ĠAction . NO _ ID , ĊĠĠĠĠĠĠĠ Ġactivity . getText ( R . string . video _ selection _ dialog _ title ), ĊĠĠĠĠĠĠĠ Ġnull , ĊĠĠĠĠĠĠĠ ĠContext Compat . get Drawable ( context , ĠR . drawable . ic _ video _ settings ) ĊĠĠĠ Ġ) ĊĠĠĠ Ġprivate Ġval Ġclosed Caption Action Ġ= ĠPlay back Controls Row . Closed Caption ing Action ( activity ) ĊĊĠĠĠ Ġprivate Ġval Ġclosed Capt ions TextView : ĠTextView Ġby Ġlazy Ġ{ ĊĠĠĠĠĠĠĠ Ġactivity . findViewById ( R . id . closed _ capt ions ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġval Ġclosed Caption Text Output Ġ= ĠText Output Ġ{ Ġc ues Ġ-> ĊĠĠĠĠĠĠĠ Ġclosed Capt ions TextView . text Ġ= Ġc ues . join ToString Ġ{ Ġit . text Ġ?: Ġ"" Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġvar Ġcurrent Video Format : ĠFormat ? Ġ= Ġnull ĊĠĠĠ Ġprivate Ġvar Ġcurrent Audio Format : ĠFormat ? Ġ= Ġnull ĊĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġplayer . add Analytics Listener ( this ) ĊĠĠĠĠĠĠĠ Ġis Seek Enabled Ġ= Ġtrue ĊĠĠĠĠĠĠĠ Ġis Controls Overlay Auto Hide Enabled Ġ= Ġtrue ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun ĠonCreate Primary Actions ( adapter : ĠArray Object Adapter ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" onCreate Primary Actions ") ĊĠĠĠĠĠĠĠ Ġadapter . apply Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . onCreate Primary Actions ( this ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( rewind Action ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( fast Format Action ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( select Audio Action ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( resolution Selection Action ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġadd ( closed Caption Action ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Action Clicked ( action : ĠAction ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Action Clicked ") ĊĠĠĠĠĠĠĠ Ġwhen Ġ( action ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġre wind Action Ġ-> Ġplayer Adapter . seek Offset (- DEFAULT _ SEEK _ OFFSET ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfast Format Action Ġ-> Ġplayer Adapter . seek Offset ( DEFAULT _ SEEK _ OFFSET ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġselect Audio Action Ġ-> Ġopen Audio Selection Dialog () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed Caption Action Ġ-> Ġtoggle Closed Capt ions () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġresolution Selection Action Ġ-> Ġopen Resolution Selection Dialog () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġsuper . on Action Clicked ( action ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġopen Resolution Selection Dialog () Ġ{ ĊĠĠĠĠĠĠĠ Ġtrack Selector . current Mapped Track Info ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ ĠResolution Selection Dialog ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Resolution Selected Listener Ġ{ Ġwidth , Ġheight Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnew Params Ġ= Ġtrack Selector . build Up on Parameters () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. setMax Video Size ( width , Ġheight ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrack Selector . set Parameters ( new Params ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ}. show ( activity . support FragmentManager , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġtoggle Closed Capt ions () Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( closed Caption Action . index Ġ== ĠPlay back Controls Row . Closed Caption ing Action . INDEX _ OFF ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed Caption Action . index Ġ= ĠPlay back Controls Row . Closed Caption ing Action . INDEX _ ON ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed Capt ions TextView . visibility Ġ= ĠView . VISIBLE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplayer . add Text Output ( closed Caption Text Output ) ĊĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed Caption Action . index Ġ= ĠPlay back Controls Row . Closed Caption ing Action . INDEX _ OFF ĊĠĠĠĠĠĠĠĠĠĠĠ Ġclosed Capt ions TextView . visibility Ġ= ĠView . GONE ĊĠĠĠĠĠĠĠĠĠĠĠ Ġplayer . remove Text Output ( closed Caption Text Output ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġopen Audio Selection Dialog () Ġ{ ĊĠĠĠĠĠĠĠ Ġtrack Selector . current Mapped Track Info ?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaudio Ġ= Ġit . get Track Groups ( C . TRACK _ TYPE _ AUDIO ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġdialog Ġ= ĠAudio Selection Dialog Fragment ( audio ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdialog . on Audio Language Selected Ġ{ Ġlanguage Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparameters Ġ= Ġtrack Selector . build Up on Parameters () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Preferred Audio Language ( language ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. set Preferred Text Language ( language ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtrack Selector . set Parameters ( parameters ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdialog . show ( activity . support FragmentManager , Ġnull ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Tracks Changed ( event Time : ĠEvent Time , Ġtrack Groups : ĠTrack Group Array , Ġtrack Selections : ĠTrack Selection Array ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Tracks Changed ") ĊĠĠĠĠĠĠĠ Ġval Ġaudio Ġ= Ġtrack Selections [ 1 ] ĊĠĠĠĠĠĠĠ Ġif Ġ( audio Ġ!= Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Audio Format Ġ= Ġaudio . get Format ( C . TRACK _ TYPE _ DEFAULT ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Subtitle () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġon Down stream Format Changed ( event Time : ĠEvent Time , Ġmedia Load Data : ĠMedia Load Data ) Ġ{ ĊĠĠĠĠĠĠĠ ĠLog . d ( TAG , Ġ" on Down stream Format Changed ") ĊĠĠĠĠĠĠĠ Ġval Ġtrack Format Ġ= Ġmedia Load Data . track Format ĊĠĠĠĠĠĠĠ Ġif Ġ( media Load Data . dataType Ġ!= ĠC . DATA _ TYPE _ MEDIA Ġ|| Ġtrack Format Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( media Load Data . track Type Ġ== ĠC . TRACK _ TYPE _ DEFAULT Ġ|| Ġmedia Load Data . track Type Ġ== ĠC . TRACK _ TYPE _ VIDEO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġcurrent Video Format Ġ= Ġtrack Format ĊĠĠĠĠĠĠĠĠĠĠĠ Ġupdate Subtitle () ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġupdate Subtitle () Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġvideo Quality Ġ= Ġcurrent Video Format ?. let Ġ{ Ġcontext . getString ( R . string . video _ quality , Ġit . height , Ġit . frame Rate . round ToInt ()) Ġ} ĊĠĠĠĠĠĠĠ Ġval Ġaudio Language Ġ= Ġcurrent Audio Format ?. label ĊĠĠĠĠĠĠĠ Ġsubtitle Ġ= ĠlistOf NotNull ( video Quality , Ġaudio Language ). join ToString ( separator Ġ= Ġ" Ġ/ Ġ") ĊĠĠĠ Ġ} Ċ Ċ } Ċ Ċ private Ġfun ĠPlayer Adapter . seek Offset ( offset : ĠLong ) Ġ{ ĊĠĠĠ Ġval Ġposition Ġ= Ġmax ( min ( current Position Ġ+ Ġoffset , Ġduration ), Ġ 0 ) ĊĠĠĠ Ġseek To ( position ) Ċ } Ċ