From 0ab52e8f4d3b54a1d44782cfbdf9ed38faf8dd8c Mon Sep 17 00:00:00 2001 From: Koen <koen@pop-os.localdomain> Date: Wed, 13 Dec 2023 10:34:14 +0100 Subject: [PATCH] Fixed notification implementation. --- app/build.gradle | 2 +- .../platformplayer/downloads/VideoDownload.kt | 2 +- .../mainactivity/main/VideoDetailView.kt | 11 +- .../platformplayer/helpers/VideoHelper.kt | 25 +++- .../services/MediaPlaybackService.kt | 128 ++++++++++-------- .../futo/platformplayer/states/StatePlayer.kt | 4 +- .../platformplayer/video/PlayerManager.kt | 11 ++ .../platformplayer/views/casting/CastView.kt | 16 ++- .../main/res/layout/fragview_video_detail.xml | 2 +- .../main/res/layout/thumbnail_player_ui.xml | 2 +- .../main/res/layout/thumbnail_video_view.xml | 4 +- app/src/main/res/layout/video_player_ui.xml | 4 +- .../main/res/layout/video_player_ui_bar.xml | 2 +- .../res/layout/video_player_ui_fullscreen.xml | 2 +- app/src/main/res/layout/video_view.xml | 8 +- app/src/main/res/layout/view_cast.xml | 2 +- app/src/main/res/values/strings.xml | 1 + 17 files changed, 140 insertions(+), 86 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 8214f0b6..68c7e905 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -175,13 +175,13 @@ dependencies { implementation 'androidx.media3:media3-exoplayer:1.2.0' implementation 'androidx.media3:media3-exoplayer-dash:1.2.0' implementation 'androidx.media3:media3-ui:1.2.0' - implementation 'androidx.media3:media3-session:1.2.0' implementation 'androidx.media3:media3-exoplayer-hls:1.2.0' implementation 'androidx.media3:media3-exoplayer-rtsp:1.2.0' implementation 'androidx.media3:media3-exoplayer-smoothstreaming:1.2.0' implementation 'androidx.media3:media3-transformer:1.2.0' implementation 'androidx.navigation:navigation-fragment-ktx:2.7.5' implementation 'androidx.navigation:navigation-ui-ktx:2.7.5' + implementation 'androidx.media:media:1.7.0' //Other implementation 'org.jmdns:jmdns:3.5.1' diff --git a/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt b/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt index 7f2b20ee..fe1dad58 100644 --- a/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt +++ b/app/src/main/java/com/futo/platformplayer/downloads/VideoDownload.kt @@ -67,7 +67,7 @@ class VideoDownload { val videoEither: IPlatformVideo get() = videoDetails ?: video ?: throw IllegalStateException("Missing video?"); val id: PlatformID get() = videoEither.id val name: String get() = videoEither.name; - val thumbnail: String? get() = videoDetails?.thumbnails?.getHQThumbnail() ?: video?.thumbnails?.getHQThumbnail(); + val thumbnail: String? get() = videoDetails?.thumbnails?.getHQThumbnail(); var targetPixelCount: Long? = null; var targetBitrate: Long? = null; diff --git a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt index 4be113ed..66f01215 100644 --- a/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt +++ b/app/src/main/java/com/futo/platformplayer/fragment/mainactivity/main/VideoDetailView.kt @@ -12,6 +12,7 @@ import android.graphics.drawable.BitmapDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.Icon import android.net.Uri +import android.support.v4.media.session.PlaybackStateCompat import android.text.Spanned import android.util.AttributeSet import android.util.Log @@ -571,9 +572,9 @@ class VideoDetailView : ConstraintLayout { } _playerProgress.player = _player.exoPlayer?.player; - _playerProgress.setProgressUpdateListener { _, _ -> - StatePlayer.instance.updateMediaSessionPlaybackState(); - } + _playerProgress.setProgressUpdateListener { position, _ -> + StatePlayer.instance.updateMediaSessionPlaybackState(_player.exoPlayer?.getPlaybackStateCompat() ?: PlaybackStateCompat.STATE_NONE, position); + }; StatePlayer.instance.onQueueChanged.subscribe(this) { if(!_destroyed) { @@ -1358,11 +1359,9 @@ class VideoDetailView : ConstraintLayout { } } - StatePlayer.instance.startOrUpdateMediaSession(context, video); StatePlayer.instance.setCurrentlyPlaying(video); - if(video.isLive && video.live != null) { loadLiveChat(video); } @@ -1791,7 +1790,7 @@ class VideoDetailView : ConstraintLayout { _cast.setIsPlaying(playing); } else { StatePlayer.instance.updateMediaSession( null); - StatePlayer.instance.updateMediaSessionPlaybackState(); + StatePlayer.instance.updateMediaSessionPlaybackState(_player.exoPlayer?.getPlaybackStateCompat() ?: PlaybackStateCompat.STATE_NONE, _player.exoPlayer?.player?.currentPosition ?: 0); } if(playing) { diff --git a/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt b/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt index 7cf603ec..44045431 100644 --- a/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt +++ b/app/src/main/java/com/futo/platformplayer/helpers/VideoHelper.kt @@ -2,6 +2,13 @@ package com.futo.platformplayer.helpers import android.net.Uri import androidx.annotation.OptIn +import androidx.media3.common.MediaItem +import androidx.media3.common.MediaMetadata +import androidx.media3.common.util.UnstableApi +import androidx.media3.datasource.ResolvingDataSource +import androidx.media3.exoplayer.dash.DashMediaSource +import androidx.media3.exoplayer.dash.manifest.DashManifestParser +import androidx.media3.exoplayer.source.MediaSource import com.futo.platformplayer.api.media.models.streams.IVideoSourceDescriptor import com.futo.platformplayer.api.media.models.streams.VideoUnMuxedSourceDescriptor import com.futo.platformplayer.api.media.models.streams.sources.IAudioSource @@ -14,12 +21,6 @@ import com.futo.platformplayer.api.media.models.video.IPlatformVideoDetails import com.futo.platformplayer.api.media.platforms.js.models.sources.JSAudioUrlRangeSource import com.futo.platformplayer.api.media.platforms.js.models.sources.JSVideoUrlRangeSource import com.futo.platformplayer.logging.Logger -import androidx.media3.common.MediaItem -import androidx.media3.common.util.UnstableApi -import androidx.media3.datasource.ResolvingDataSource -import androidx.media3.exoplayer.dash.DashMediaSource -import androidx.media3.exoplayer.dash.manifest.DashManifestParser -import androidx.media3.exoplayer.source.MediaSource import kotlin.math.abs class VideoHelper { @@ -146,6 +147,18 @@ class VideoHelper { })).createMediaSource(manifest, MediaItem.Builder().setUri(Uri.parse(videoSource.getVideoUrl())).build()) } + fun getMediaMetadata(media: IPlatformVideoDetails): MediaMetadata { + val builder = MediaMetadata.Builder() + .setArtist(media.author.name) + .setTitle(media.name) + + media.thumbnails.getHQThumbnail()?.let { + builder.setArtworkUri(Uri.parse(it)) + } + + return builder.build() + } + @OptIn(UnstableApi::class) fun convertItagSourceToChunkedDashSource(audioSource: JSAudioUrlRangeSource) : MediaSource { val manifestConfig = ProgressiveDashManifestCreator.fromAudioProgressiveStreamingUrl(audioSource.getAudioUrl(), diff --git a/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt b/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt index 437fb960..4a205283 100644 --- a/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt +++ b/app/src/main/java/com/futo/platformplayer/services/MediaPlaybackService.kt @@ -13,14 +13,15 @@ import android.graphics.drawable.Drawable import android.media.AudioFocusRequest import android.media.AudioManager import android.media.AudioManager.OnAudioFocusChangeListener +import android.media.MediaMetadata import android.os.Build import android.os.IBinder +import android.os.SystemClock +import android.support.v4.media.MediaMetadataCompat +import android.support.v4.media.session.MediaSessionCompat +import android.support.v4.media.session.PlaybackStateCompat import android.util.Log -import androidx.annotation.OptIn import androidx.core.app.NotificationCompat -import androidx.media3.common.util.UnstableApi -import androidx.media3.session.MediaSession -import androidx.media3.session.MediaStyleNotificationHelper import com.bumptech.glide.Glide import com.bumptech.glide.request.target.CustomTarget import com.bumptech.glide.request.transition.Transition @@ -50,7 +51,7 @@ class MediaPlaybackService : Service() { private var _audioManager: AudioManager? = null; private var _notificationManager: NotificationManager? = null; private var _notificationChannel: NotificationChannel? = null; - private var _mediaSession: MediaSession? = null; + private var _mediaSession: MediaSessionCompat? = null; private var _hasFocus: Boolean = false; private var _focusRequest: AudioFocusRequest? = null; private var _audioFocusLossTime_ms: Long? = null @@ -81,7 +82,6 @@ class MediaPlaybackService : Service() { return START_STICKY; } - @OptIn(UnstableApi::class) fun setupNotificationRequirements() { _audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager; _notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager; @@ -91,54 +91,47 @@ class MediaPlaybackService : Service() { }; _notificationManager!!.createNotificationChannel(_notificationChannel!!); - _mediaSession = MediaSession.Builder(this, StatePlayer.instance.getPlayerOrCreate(this).player) - - .setCallback(object: MediaSession.Callback { - override fun onMediaButtonEvent(session: MediaSession, controllerInfo: MediaSession.ControllerInfo, intent: Intent): Boolean { - //TODO: Reimplement - return super.onMediaButtonEvent(session, controllerInfo, intent) - } - - /*override fun onSeekTo(pos: Long) { - super.onSeekTo(pos) - Logger.i(TAG, "Media session callback onSeekTo(pos = $pos)"); - MediaControlReceiver.onSeekToReceived.emit(pos); - } + _mediaSession = MediaSessionCompat(this, "PlayerState"); + _mediaSession?.setPlaybackState(PlaybackStateCompat.Builder() + .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1f) + .build()); + _mediaSession?.setCallback(object: MediaSessionCompat.Callback() { + override fun onSeekTo(pos: Long) { + super.onSeekTo(pos) + Logger.i(TAG, "Media session callback onSeekTo(pos = $pos)"); + MediaControlReceiver.onSeekToReceived.emit(pos); + } - override fun onPlay() { - super.onPlay(); - Logger.i(TAG, "Media session callback onPlay()"); - MediaControlReceiver.onPlayReceived.emit(); - } + override fun onPlay() { + super.onPlay(); + Logger.i(TAG, "Media session callback onPlay()"); + MediaControlReceiver.onPlayReceived.emit(); + } - override fun onPause() { - super.onPause(); - Logger.i(TAG, "Media session callback onPause()"); - MediaControlReceiver.onPauseReceived.emit(); - } + override fun onPause() { + super.onPause(); + Logger.i(TAG, "Media session callback onPause()"); + MediaControlReceiver.onPauseReceived.emit(); + } - override fun onStop() { - super.onStop(); - Logger.i(TAG, "Media session callback onStop()"); - MediaControlReceiver.onCloseReceived.emit(); - } + override fun onStop() { + super.onStop(); + Logger.i(TAG, "Media session callback onStop()"); + MediaControlReceiver.onCloseReceived.emit(); + } - override fun onSkipToPrevious() { - super.onSkipToPrevious(); - Logger.i(TAG, "Media session callback onSkipToPrevious()"); - MediaControlReceiver.onPreviousReceived.emit(); - } + override fun onSkipToPrevious() { + super.onSkipToPrevious(); + Logger.i(TAG, "Media session callback onSkipToPrevious()"); + MediaControlReceiver.onPreviousReceived.emit(); + } - override fun onSkipToNext() { - super.onSkipToNext() - Logger.i(TAG, "Media session callback onSkipToNext()"); - MediaControlReceiver.onNextReceived.emit(); - }*/ - }) - .build(); - /*_mediaSession?.setPlaybackState(PlaybackStateCompat.Builder() - .setState(PlaybackStateCompat.STATE_PLAYING, 0, 1f) - .build());*/ + override fun onSkipToNext() { + super.onSkipToNext() + Logger.i(TAG, "Media session callback onSkipToNext()"); + MediaControlReceiver.onNextReceived.emit(); + } + }); } override fun onCreate() { @@ -193,7 +186,15 @@ class MediaPlaybackService : Service() { if(_notificationChannel == null || _mediaSession == null) setupNotificationRequirements(); + _mediaSession?.setMetadata( + MediaMetadataCompat.Builder() + .putString(MediaMetadata.METADATA_KEY_ARTIST, video.author.name) + .putString(MediaMetadata.METADATA_KEY_TITLE, video.name) + .putLong(MediaMetadata.METADATA_KEY_DURATION, video.duration * 1000) + .build()); + val thumbnail = video.thumbnails.getHQThumbnail(); + _notif_last_video = video; if(isUpdating) @@ -220,7 +221,6 @@ class MediaPlaybackService : Service() { private fun generateMediaAction(icon: Int, title: String, intent: PendingIntent) : NotificationCompat.Action { return NotificationCompat.Action.Builder(icon, title, intent).build(); } - @OptIn(UnstableApi::class) private fun notifyMediaSession(video: IPlatformVideo?, desiredBitmap: Bitmap?) { val channel = _notificationChannel ?: return; val session = _mediaSession ?: return; @@ -249,9 +249,14 @@ class MediaPlaybackService : Service() { .setOngoing(true) .setSilent(true) .setContentIntent(PendingIntent.getActivity(this, 5, bringUpIntent, PendingIntent.FLAG_IMMUTABLE)) - .setStyle( - if(hasQueue) MediaStyleNotificationHelper.MediaStyle(session)//.setShowActionsInCompactView(0, 1, 2) - else MediaStyleNotificationHelper.MediaStyle(session))//.setShowActionsInCompactView(0)) + .setStyle(if(hasQueue) + androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(session.sessionToken) + .setShowActionsInCompactView(0, 1, 2) + else + androidx.media.app.NotificationCompat.MediaStyle() + .setMediaSession(session.sessionToken) + .setShowActionsInCompactView(0)) .setDeleteIntent(deleteIntent) .setChannelId(channel.id) @@ -298,7 +303,7 @@ class MediaPlaybackService : Service() { val notif = builder.build(); notif.flags = notif.flags or NotificationCompat.FLAG_ONGOING_EVENT or NotificationCompat.FLAG_NO_CLEAR; - Logger.i(TAG, "Updating notification bitmap=${if (bitmap != null) "yes" else "no."} channelId=${channel.id} icon=${icon} video=${video?.name ?: ""} playWhenReady=${playWhenReady} session.sessionToken=${session.token}"); + Logger.i(TAG, "Updating notification bitmap=${if (bitmap != null) "yes" else "no."} channelId=${channel.id} icon=${icon} video=${video?.name ?: ""} playWhenReady=${playWhenReady} session.sessionToken=${session.sessionToken}"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // For API 29 and above @@ -311,7 +316,20 @@ class MediaPlaybackService : Service() { _notif_last_bitmap = bitmap; } - fun updateMediaSessionPlaybackState() { + fun updateMediaSessionPlaybackState(state: Int, pos: Long) { + _mediaSession?.setPlaybackState( + PlaybackStateCompat.Builder() + .setActions( + PlaybackStateCompat.ACTION_SEEK_TO or + PlaybackStateCompat.ACTION_PLAY or + PlaybackStateCompat.ACTION_PAUSE or + PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS or + PlaybackStateCompat.ACTION_SKIP_TO_NEXT or + PlaybackStateCompat.ACTION_PLAY_PAUSE + ) + .setState(state, pos, 1f, SystemClock.elapsedRealtime()) + .build()); + if(_focusRequest == null) setAudioFocus(); } diff --git a/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt b/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt index 6f2ed300..7d642ac4 100644 --- a/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt +++ b/app/src/main/java/com/futo/platformplayer/states/StatePlayer.kt @@ -107,8 +107,8 @@ class StatePlayer { fun updateMediaSession(videoUpdated: IPlatformVideoDetails?) { MediaPlaybackService.getService()?.updateMediaSession(videoUpdated); } - fun updateMediaSessionPlaybackState() { - MediaPlaybackService.getService()?.updateMediaSessionPlaybackState(); + fun updateMediaSessionPlaybackState(state: Int, pos: Long) { + MediaPlaybackService.getService()?.updateMediaSessionPlaybackState(state, pos); } fun closeMediaSession() { MediaPlaybackService.getService()?.closeMediaSession(); diff --git a/app/src/main/java/com/futo/platformplayer/video/PlayerManager.kt b/app/src/main/java/com/futo/platformplayer/video/PlayerManager.kt index 05a6eef0..22926841 100644 --- a/app/src/main/java/com/futo/platformplayer/video/PlayerManager.kt +++ b/app/src/main/java/com/futo/platformplayer/video/PlayerManager.kt @@ -1,5 +1,7 @@ package com.futo.platformplayer.video +import android.media.session.PlaybackState +import android.support.v4.media.session.PlaybackStateCompat import androidx.media3.common.Player import androidx.media3.exoplayer.ExoPlayer import androidx.media3.ui.PlayerView @@ -21,6 +23,15 @@ class PlayerManager { this.player = exoPlayer; } + + fun getPlaybackStateCompat() : Int { + return when(player.playbackState) { + ExoPlayer.STATE_READY -> if(player.playWhenReady) PlaybackStateCompat.STATE_PLAYING else PlaybackStateCompat.STATE_PAUSED; + ExoPlayer.STATE_BUFFERING -> PlaybackState.STATE_BUFFERING; + else -> PlaybackState.STATE_NONE + } + } + @Synchronized fun attach(view: PlayerView, stateName: String) { if(view != _currentView) { diff --git a/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt b/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt index 52106dd6..aeca7334 100644 --- a/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt +++ b/app/src/main/java/com/futo/platformplayer/views/casting/CastView.kt @@ -1,6 +1,8 @@ package com.futo.platformplayer.views.casting import android.content.Context +import android.media.session.PlaybackState +import android.support.v4.media.session.PlaybackStateCompat import android.util.AttributeSet import android.util.TypedValue import android.view.LayoutInflater @@ -147,9 +149,10 @@ class CastView : ConstraintLayout { _buttonPlay.visibility = View.VISIBLE; } + val position = StateCasting.instance.activeDevice?.expectedCurrentTime?.times(1000.0)?.toLong(); if(StatePlayer.instance.hasMediaSession()) { StatePlayer.instance.updateMediaSession(null); - StatePlayer.instance.updateMediaSessionPlaybackState(); + StatePlayer.instance.updateMediaSessionPlaybackState(getPlaybackStateCompat(), (position ?: 0)); } } @@ -195,7 +198,7 @@ class CastView : ConstraintLayout { fun setTime(ms: Long) { _textPosition.text = ms.toHumanTime(true); _timeBar.setPosition(ms / 1000); - StatePlayer.instance.updateMediaSessionPlaybackState(); + StatePlayer.instance.updateMediaSessionPlaybackState(getPlaybackStateCompat(), ms); } fun cleanup() { @@ -205,4 +208,13 @@ class CastView : ConstraintLayout { _updateTimeJob = null; _scope.cancel(); } + + private fun getPlaybackStateCompat(): Int { + val d = StateCasting.instance.activeDevice ?: return PlaybackState.STATE_NONE; + + return when(d.isPlaying) { + true -> PlaybackStateCompat.STATE_PLAYING; + else -> PlaybackStateCompat.STATE_PAUSED; + } + } } \ No newline at end of file diff --git a/app/src/main/res/layout/fragview_video_detail.xml b/app/src/main/res/layout/fragview_video_detail.xml index 607de6ed..7652198e 100644 --- a/app/src/main/res/layout/fragview_video_detail.xml +++ b/app/src/main/res/layout/fragview_video_detail.xml @@ -39,7 +39,7 @@ android:elevation="4dp" android:layout_marginBottom="6dp" /> - <com.google.android.exoplayer2.ui.PlayerControlView + <androidx.media3.ui.PlayerControlView android:id="@+id/videodetail_progress" android:layout_width="match_parent" android:layout_height="12dp" diff --git a/app/src/main/res/layout/thumbnail_player_ui.xml b/app/src/main/res/layout/thumbnail_player_ui.xml index 8ce8ba99..adfc7e9d 100644 --- a/app/src/main/res/layout/thumbnail_player_ui.xml +++ b/app/src/main/res/layout/thumbnail_player_ui.xml @@ -103,7 +103,7 @@ android:textStyle="normal" /> </LinearLayout> - <com.google.android.exoplayer2.ui.DefaultTimeBar + <androidx.media3.ui.DefaultTimeBar android:id="@id/exo_progress" android:layout_width="match_parent" android:layout_height="16dp" diff --git a/app/src/main/res/layout/thumbnail_video_view.xml b/app/src/main/res/layout/thumbnail_video_view.xml index b63e6715..e553e385 100644 --- a/app/src/main/res/layout/thumbnail_video_view.xml +++ b/app/src/main/res/layout/thumbnail_video_view.xml @@ -4,7 +4,7 @@ android:layout_height="wrap_content" android:background="@color/transparent" xmlns:app="http://schemas.android.com/apk/res-auto"> - <com.google.android.exoplayer2.ui.PlayerView + <androidx.media3.ui.PlayerView android:id="@+id/video_player" android:layout_width="match_parent" android:layout_height="match_parent" @@ -15,7 +15,7 @@ app:resize_mode="fit" app:show_buffering="when_playing" android:layout_marginBottom="6dp" /> - <com.google.android.exoplayer2.ui.PlayerControlView + <androidx.media3.ui.PlayerControlView android:id="@+id/video_player_controller" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/app/src/main/res/layout/video_player_ui.xml b/app/src/main/res/layout/video_player_ui.xml index 15c78f2a..ae797f0f 100644 --- a/app/src/main/res/layout/video_player_ui.xml +++ b/app/src/main/res/layout/video_player_ui.xml @@ -198,12 +198,12 @@ </TextView> - <com.google.android.exoplayer2.ui.SubtitleView + <androidx.media3.ui.SubtitleView android:id="@id/exo_subtitles" android:layout_width="match_parent" android:layout_height="match_parent" /> - <com.google.android.exoplayer2.ui.DefaultTimeBar + <androidx.media3.ui.DefaultTimeBar android:id="@id/exo_progress" android:layout_width="match_parent" android:layout_height="16dp" diff --git a/app/src/main/res/layout/video_player_ui_bar.xml b/app/src/main/res/layout/video_player_ui_bar.xml index 33766bb4..2bd2f277 100644 --- a/app/src/main/res/layout/video_player_ui_bar.xml +++ b/app/src/main/res/layout/video_player_ui_bar.xml @@ -16,7 +16,7 @@ app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent"> - <com.google.android.exoplayer2.ui.DefaultTimeBar + <androidx.media3.ui.DefaultTimeBar android:id="@id/exo_progress" android:layout_width="match_parent" android:layout_height="12dp" diff --git a/app/src/main/res/layout/video_player_ui_fullscreen.xml b/app/src/main/res/layout/video_player_ui_fullscreen.xml index 7fa4e188..57b663af 100644 --- a/app/src/main/res/layout/video_player_ui_fullscreen.xml +++ b/app/src/main/res/layout/video_player_ui_fullscreen.xml @@ -227,7 +227,7 @@ </TextView> - <com.google.android.exoplayer2.ui.DefaultTimeBar + <androidx.media3.ui.DefaultTimeBar android:id="@id/exo_progress" android:layout_width="match_parent" android:layout_height="12dp" diff --git a/app/src/main/res/layout/video_view.xml b/app/src/main/res/layout/video_view.xml index 3cb0bc59..0a35c2f7 100644 --- a/app/src/main/res/layout/video_view.xml +++ b/app/src/main/res/layout/video_view.xml @@ -6,7 +6,7 @@ android:id="@+id/videoview_root" android:background="@color/transparent" xmlns:app="http://schemas.android.com/apk/res-auto"> - <com.google.android.exoplayer2.ui.PlayerView + <androidx.media3.ui.PlayerView android:id="@+id/video_player" android:layout_width="match_parent" android:layout_height="match_parent" @@ -16,7 +16,7 @@ app:show_buffering="always" android:layout_marginBottom="6dp" /> <!-- - <com.google.android.exoplayer2.ui.PlayerControlView + <androidx.media3.ui.PlayerControlView android:id="@+id/video_player_bar" android:layout_width="match_parent" android:layout_height="match_parent" @@ -48,7 +48,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <com.google.android.exoplayer2.ui.PlayerControlView + <androidx.media3.ui.PlayerControlView android:id="@+id/video_player_controller" android:layout_width="match_parent" android:layout_height="match_parent" @@ -56,7 +56,7 @@ android:layout_marginRight="-6dp" app:show_timeout="-1" app:controller_layout_id="@layout/video_player_ui" /> - <com.google.android.exoplayer2.ui.PlayerControlView + <androidx.media3.ui.PlayerControlView android:id="@+id/video_player_controller_fullscreen" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/app/src/main/res/layout/view_cast.xml b/app/src/main/res/layout/view_cast.xml index bab3ec6f..9253b3e3 100644 --- a/app/src/main/res/layout/view_cast.xml +++ b/app/src/main/res/layout/view_cast.xml @@ -143,7 +143,7 @@ app:layout_constraintTop_toTopOf="@id/text_position" app:layout_constraintBottom_toBottomOf="@id/text_position"/> - <com.google.android.exoplayer2.ui.DefaultTimeBar + <androidx.media3.ui.DefaultTimeBar android:id="@+id/time_progress" android:layout_width="match_parent" android:layout_height="16dp" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d60f4d4e..893729c3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -712,6 +712,7 @@ <string name="fcast_technical_documentation">FCast Technical Documentation</string> <string name="login_to_view_your_comments">Login to view your comments</string> <string name="polycentric_is_disabled">Polycentric is disabled</string> + <string name="play_pause">Play Pause</string> <string-array name="home_screen_array"> <item>Recommendations</item> <item>Subscriptions</item> -- GitLab