Skip to content

Commit

Permalink
Update ExoPlayer usage (home-assistant#3760)
Browse files Browse the repository at this point in the history
* Switch to StyledPlayerView for migration

* Migrate to media3 for ExoPlayer

* Replace deprecated code

* Restore/customize layout to ExoPlayer v2
  • Loading branch information
jpelgrom authored Aug 5, 2023
1 parent 77141c2 commit 49f3080
Show file tree
Hide file tree
Showing 13 changed files with 186 additions and 183 deletions.
8 changes: 3 additions & 5 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -159,11 +159,9 @@ dependencies {
implementation(libs.biometric)
implementation(libs.webkit)

implementation(libs.exoplayer.core)
implementation(libs.exoplayer.hls)
implementation(libs.exoplayer.ui)
"fullImplementation"(libs.extension.cronet)
"minimalImplementation"(libs.extension.cronet) {
implementation(libs.bundles.media3)
"fullImplementation"(libs.media3.datasource.cronet)
"minimalImplementation"(libs.media3.datasource.cronet) {
exclude(group = "com.google.android.gms", module = "play-services-cronet")
}
"minimalImplementation"(libs.cronet.embedded)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
import android.widget.FrameLayout
import android.widget.ImageView
import android.widget.ImageButton
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.OptIn
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.getSystemService
import androidx.core.content.res.ResourcesCompat
import androidx.core.graphics.ColorUtils
Expand All @@ -59,17 +59,17 @@ import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.VideoSize
import androidx.media3.datasource.cronet.CronetDataSource
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.source.DefaultMediaSourceFactory
import androidx.media3.ui.AspectRatioFrameLayout
import androidx.media3.ui.PlayerView
import androidx.webkit.WebViewCompat
import androidx.webkit.WebViewFeature
import com.google.android.exoplayer2.DefaultLoadControl
import com.google.android.exoplayer2.MediaItem
import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.SimpleExoPlayer
import com.google.android.exoplayer2.ext.cronet.CronetDataSource
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.ui.AspectRatioFrameLayout
import com.google.android.exoplayer2.ui.PlayerView
import com.google.android.exoplayer2.video.VideoSize
import dagger.hilt.android.AndroidEntryPoint
import eightbitlab.com.blurview.RenderScriptBlur
import io.homeassistant.companion.android.BaseActivity
Expand All @@ -85,7 +85,6 @@ import io.homeassistant.companion.android.database.authentication.Authentication
import io.homeassistant.companion.android.database.authentication.AuthenticationDao
import io.homeassistant.companion.android.databinding.ActivityWebviewBinding
import io.homeassistant.companion.android.databinding.DialogAuthenticationBinding
import io.homeassistant.companion.android.databinding.ExoPlayerViewBinding
import io.homeassistant.companion.android.launch.LaunchActivity
import io.homeassistant.companion.android.matter.MatterFrontendCommissioningStatus
import io.homeassistant.companion.android.nfc.WriteNfcTag
Expand Down Expand Up @@ -118,6 +117,7 @@ import java.util.concurrent.Executors
import javax.inject.Inject
import io.homeassistant.companion.android.common.R as commonR

@OptIn(androidx.media3.common.util.UnstableApi::class)
@AndroidEntryPoint
class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webview.WebView {

Expand Down Expand Up @@ -196,7 +196,6 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private lateinit var myCustomView: View
private lateinit var authenticator: Authenticator
private lateinit var exoPlayerView: PlayerView
private lateinit var playerBinding: ExoPlayerViewBinding
private lateinit var windowInsetsController: WindowInsetsControllerCompat

private var mFilePathCallback: ValueCallback<Array<Uri>>? = null
Expand All @@ -208,13 +207,13 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
private var firstAuthTime: Long = 0
private var resourceURL: String = ""
private var appLocked = true
private var exoPlayer: SimpleExoPlayer? = null
private var exoPlayer: ExoPlayer? = null
private var isExoFullScreen = false
private var exoTop: Int = 0 // These margins are from the DOM and scaled to screen
private var exoLeft: Int = 0
private var exoRight: Int = 0
private var exoBottom: Int = 0
private var exoMute: Boolean = true
private var exoTop = 0 // These margins are from the DOM and scaled to screen
private var exoLeft = 0
private var exoRight = 0
private var exoBottom = 0
private var exoMute = true
private var failedConnection = "external"
private var clearHistory = false
private var moreInfoEntity = ""
Expand Down Expand Up @@ -253,12 +252,8 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoPlayerView.visibility = View.GONE
exoPlayerView.setBackgroundColor(Color.BLACK)
exoPlayerView.alpha = 1f
exoPlayerView.setShowBuffering(PlayerView.SHOW_BUFFERING_ALWAYS)
exoPlayerView.controllerHideOnTouch = true
exoPlayerView.controllerShowTimeoutMs = 2000

playerBinding = ExoPlayerViewBinding.bind(exoPlayerView)

appLocked = presenter.isAppLocked()
binding.blurView.setBlurEnabled(appLocked)

Expand Down Expand Up @@ -852,7 +847,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
val uri = Uri.parse(payload.getString("url"))
exoMute = payload.optBoolean("muted")
runOnUiThread {
exoPlayer = SimpleExoPlayer.Builder(applicationContext).setMediaSourceFactory(
exoPlayer = ExoPlayer.Builder(applicationContext).setMediaSourceFactory(
DefaultMediaSourceFactory(
CronetDataSource.Factory(
CronetEngine.Builder(applicationContext).enableQuic(true).build(),
Expand All @@ -872,6 +867,7 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoPlayer?.addListener(object : Player.Listener {
override fun onVideoSizeChanged(videoSize: VideoSize) {
super.onVideoSizeChanged(videoSize)
if (videoSize.height == 0 || videoSize.width == 0) return
exoBottom =
exoTop + ((exoRight - exoLeft) * videoSize.height / videoSize.width)
runOnUiThread {
Expand All @@ -880,16 +876,15 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
}
})
exoPlayer?.prepare()
exoMute = !exoMute
exoMute = !exoMute // Invert because exoToggleMute() will invert again
exoToggleMute()
exoPlayerView.player = exoPlayer
exoPlayerView.visibility = View.VISIBLE

findViewById<ImageView>(R.id.exo_fullscreen_icon).setOnClickListener {
isExoFullScreen = !isExoFullScreen
exoPlayerView.setFullscreenButtonClickListener { isFullScreen ->
isExoFullScreen = isFullScreen
exoResizeLayout()
}
findViewById<ImageView>(R.id.exo_mute_icon).setOnClickListener { exoToggleMute() }
exoPlayerView.player = exoPlayer
exoPlayerView.visibility = View.VISIBLE
findViewById<ImageButton>(R.id.exo_ha_mute)?.setOnClickListener { exoToggleMute() }
}
webView.externalBus(
id = json.get("id"),
Expand Down Expand Up @@ -932,43 +927,27 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
exoMute = !exoMute
if (exoMute) {
exoPlayer?.volume = 0f
findViewById<ImageView>(R.id.exo_mute_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_volume_off_24
)
)
findViewById<ImageButton>(R.id.exo_ha_mute)?.setImageResource(R.drawable.ic_baseline_volume_off_24)
} else {
exoPlayer?.volume = 1f
findViewById<ImageView>(R.id.exo_mute_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_volume_up_24
)
)
findViewById<ImageButton>(R.id.exo_ha_mute)?.setImageResource(R.drawable.ic_baseline_volume_up_24)
}
}

fun exoResizeLayout() {
val exoLayoutParams = exoPlayerView.layoutParams as FrameLayout.LayoutParams
if (isExoFullScreen) {
if (resources.configuration.orientation == Configuration.ORIENTATION_LANDSCAPE) {
playerBinding.exoContentFrame.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
} else {
playerBinding.exoContentFrame.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FIXED_WIDTH
}
exoLayoutParams.setMargins(0, 0, 0, 0)
exoPlayerView.layoutParams.height = FrameLayout.LayoutParams.MATCH_PARENT
exoPlayerView.layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT
findViewById<ImageView>(R.id.exo_fullscreen_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_fullscreen_exit_24
)
)
hideSystemUI()
} else {
playerBinding.exoContentFrame.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
exoPlayerView.resizeMode = AspectRatioFrameLayout.RESIZE_MODE_FILL
exoPlayerView.layoutParams.height = FrameLayout.LayoutParams.WRAP_CONTENT
exoPlayerView.layoutParams.width = FrameLayout.LayoutParams.MATCH_PARENT
val screenWidth: Int = resources.displayMetrics.widthPixels
Expand All @@ -979,12 +958,6 @@ class WebViewActivity : BaseActivity(), io.homeassistant.companion.android.webvi
maxOf(screenWidth - exoRight, 0),
maxOf(screenHeight - exoBottom, 0)
)
findViewById<ImageView>(R.id.exo_fullscreen_icon).setImageDrawable(
ContextCompat.getDrawable(
applicationContext,
R.drawable.ic_baseline_fullscreen_24
)
)
showSystemUI()
}
exoPlayerView.requestLayout()
Expand Down
10 changes: 0 additions & 10 deletions app/src/main/res/drawable/ic_baseline_fullscreen_24.xml

This file was deleted.

10 changes: 0 additions & 10 deletions app/src/main/res/drawable/ic_baseline_fullscreen_exit_24.xml

This file was deleted.

3 changes: 1 addition & 2 deletions app/src/main/res/drawable/ic_baseline_volume_off_24.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v2.21l2.45,2.45c0.03,-0.2 0.05,-0.41 0.05,-0.63zM19,12c0,0.94 -0.2,1.82 -0.54,2.64l1.51,1.51C20.63,14.91 21,13.5 21,12c0,-4.28 -2.99,-7.86 -7,-8.77v2.06c2.89,0.86 5,3.54 5,6.71zM4.27,3L3,4.27 7.73,9L3,9v6h4l5,5v-6.73l4.25,4.25c-0.67,0.52 -1.42,0.93 -2.25,1.18v2.06c1.38,-0.31 2.63,-0.95 3.69,-1.81L19.73,21 21,19.73l-9,-9L4.27,3zM12,4L9.91,6.09 12,8.18L12,4z"/>
Expand Down
3 changes: 1 addition & 2 deletions app/src/main/res/drawable/ic_baseline_volume_up_24.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z"/>
Expand Down
7 changes: 4 additions & 3 deletions app/src/main/res/layout/activity_webview.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,12 @@
android:id="@+id/exoviewGroup"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.exoplayer2.ui.PlayerView
<androidx.media3.ui.PlayerView
android:id="@+id/exoplayerView"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</com.google.android.exoplayer2.ui.PlayerView>
android:layout_height="wrap_content"
app:show_buffering="always">
</androidx.media3.ui.PlayerView>
</FrameLayout>

</RelativeLayout>
Loading

0 comments on commit 49f3080

Please sign in to comment.