Merge pull request #342 from Bnyro/notification

Notification while playing videos
This commit is contained in:
Bnyro 2022-06-01 08:56:01 +02:00 committed by GitHub
commit 2c175cde7d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 477 additions and 418 deletions

View File

@ -2,6 +2,7 @@ package com.github.libretube
import android.Manifest import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.NotificationManager
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
import android.content.Intent import android.content.Intent
@ -13,6 +14,7 @@ import android.os.Build
import android.os.Build.VERSION.SDK_INT import android.os.Build.VERSION.SDK_INT
import android.os.Bundle import android.os.Bundle
import android.os.Environment import android.os.Environment
import android.support.v4.media.session.MediaSessionCompat
import android.text.Html import android.text.Html
import android.text.TextUtils import android.text.TextUtils
import android.util.Log import android.util.Log
@ -47,6 +49,7 @@ import com.github.libretube.adapters.TrendingAdapter
import com.github.libretube.obj.PipedStream import com.github.libretube.obj.PipedStream
import com.github.libretube.obj.Segment import com.github.libretube.obj.Segment
import com.github.libretube.obj.Segments import com.github.libretube.obj.Segments
import com.github.libretube.obj.Streams
import com.github.libretube.obj.Subscribe import com.github.libretube.obj.Subscribe
import com.github.libretube.util.CronetHelper import com.github.libretube.util.CronetHelper
import com.google.android.exoplayer2.C import com.google.android.exoplayer2.C
@ -57,10 +60,12 @@ import com.google.android.exoplayer2.MediaItem.fromUri
import com.google.android.exoplayer2.Player import com.google.android.exoplayer2.Player
import com.google.android.exoplayer2.audio.AudioAttributes import com.google.android.exoplayer2.audio.AudioAttributes
import com.google.android.exoplayer2.ext.cronet.CronetDataSource import com.google.android.exoplayer2.ext.cronet.CronetDataSource
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector
import com.google.android.exoplayer2.source.DefaultMediaSourceFactory import com.google.android.exoplayer2.source.DefaultMediaSourceFactory
import com.google.android.exoplayer2.source.MediaSource import com.google.android.exoplayer2.source.MediaSource
import com.google.android.exoplayer2.source.MergingMediaSource import com.google.android.exoplayer2.source.MergingMediaSource
import com.google.android.exoplayer2.source.ProgressiveMediaSource import com.google.android.exoplayer2.source.ProgressiveMediaSource
import com.google.android.exoplayer2.ui.PlayerNotificationManager
import com.google.android.exoplayer2.ui.StyledPlayerView import com.google.android.exoplayer2.ui.StyledPlayerView
import com.google.android.exoplayer2.upstream.DataSource import com.google.android.exoplayer2.upstream.DataSource
import com.google.android.exoplayer2.upstream.DefaultDataSource import com.google.android.exoplayer2.upstream.DefaultDataSource
@ -105,6 +110,11 @@ class PlayerFragment : Fragment() {
private lateinit var relDownloadVideo: LinearLayout private lateinit var relDownloadVideo: LinearLayout
private lateinit var mediaSession: MediaSessionCompat
private lateinit var mediaSessionConnector: MediaSessionConnector
private lateinit var playerNotification: PlayerNotificationManager
private val notificationId = 1
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
arguments?.let { arguments?.let {
@ -308,6 +318,11 @@ class PlayerFragment : Fragment() {
super.onDestroy() super.onDestroy()
try { try {
exoPlayer.release() exoPlayer.release()
// kill notification
val nManager = context?.getSystemService(
Context.NOTIFICATION_SERVICE
) as NotificationManager
nManager.cancel(notificationId)
} catch (e: Exception) { } catch (e: Exception) {
} }
} }
@ -386,7 +401,13 @@ class PlayerFragment : Fragment() {
} }
} }
} }
initializePlayerView(view, response)
}
}
run()
}
private fun initializePlayerView(view: View, response: Streams) {
isLoading = false isLoading = false
var videosNameArray: Array<CharSequence> = arrayOf() var videosNameArray: Array<CharSequence> = arrayOf()
videosNameArray += "HLS" videosNameArray += "HLS"
@ -405,32 +426,14 @@ class PlayerFragment : Fragment() {
) )
} }
val cronetEngine: CronetEngine = CronetHelper.getCronetEngine() createExoPlayer(view)
val cronetDataSourceFactory: CronetDataSource.Factory =
CronetDataSource.Factory(cronetEngine, Executors.newCachedThreadPool())
val dataSourceFactory = DefaultDataSource.Factory(
requireContext(),
cronetDataSourceFactory
)
val audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MOVIE)
.build()
exoPlayer = ExoPlayer.Builder(view.context)
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))
.setSeekBackIncrementMs(5000)
.setSeekForwardIncrementMs(5000)
.build()
exoPlayerView.setShowSubtitleButton(true) exoPlayerView.setShowSubtitleButton(true)
exoPlayerView.setShowNextButton(false) exoPlayerView.setShowNextButton(false)
exoPlayerView.setShowPreviousButton(false) exoPlayerView.setShowPreviousButton(false)
exoPlayerView.setRepeatToggleModes(RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL) exoPlayerView.setRepeatToggleModes(RepeatModeUtil.REPEAT_TOGGLE_MODE_ALL)
// exoPlayerView.controllerShowTimeoutMs = 1500 // exoPlayerView.controllerShowTimeoutMs = 1500
exoPlayerView.controllerHideOnTouch = true exoPlayerView.controllerHideOnTouch = true
exoPlayer.setAudioAttributes(audioAttributes, true)
exoPlayerView.player = exoPlayer exoPlayerView.player = exoPlayer
val sharedPreferences = val sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(requireContext()) PreferenceManager.getDefaultSharedPreferences(requireContext())
@ -825,8 +828,53 @@ class PlayerFragment : Fragment() {
} }
} }
} }
private fun createExoPlayer(view: View) {
val cronetEngine: CronetEngine = CronetHelper.getCronetEngine()
val cronetDataSourceFactory: CronetDataSource.Factory =
CronetDataSource.Factory(cronetEngine, Executors.newCachedThreadPool())
val dataSourceFactory = DefaultDataSource.Factory(
requireContext(),
cronetDataSourceFactory
)
val audioAttributes = AudioAttributes.Builder()
.setUsage(C.USAGE_MEDIA)
.setContentType(C.CONTENT_TYPE_MOVIE)
.build()
exoPlayer = ExoPlayer.Builder(view.context)
.setMediaSourceFactory(DefaultMediaSourceFactory(dataSourceFactory))
.setSeekBackIncrementMs(5000)
.setSeekForwardIncrementMs(5000)
.build()
exoPlayer.setAudioAttributes(audioAttributes, true)
setMediaItem(requireContext())
initializePlayerNotification(requireContext())
} }
run()
private fun setMediaItem(c: Context) {
mediaSession = MediaSessionCompat(c, this.javaClass.name)
mediaSession.isActive = true
/* might be useful for setting the notification title
mediaSession.setMetadata(MediaMetadataCompat.Builder()
.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, "")
.putString(MediaMetadataCompat.METADATA_KEY_ALBUM_ARTIST, "")
.build()
)
*/
mediaSessionConnector = MediaSessionConnector(mediaSession)
mediaSessionConnector.setPlayer(exoPlayer)
}
private fun initializePlayerNotification(c: Context) {
playerNotification = PlayerNotificationManager.Builder(c, notificationId, "background_mode")
.build()
playerNotification.setPlayer(exoPlayer)
playerNotification.setMediaSessionToken(mediaSession.sessionToken)
} }
private fun isSubscribed(button: MaterialButton, channel_id: String) { private fun isSubscribed(button: MaterialButton, channel_id: String) {

View File

@ -1,6 +1,7 @@
package com.github.libretube package com.github.libretube
import android.Manifest import android.Manifest
import android.app.NotificationManager
import android.content.ContentResolver import android.content.ContentResolver
import android.content.Context import android.content.Context
import android.content.DialogInterface import android.content.DialogInterface
@ -389,6 +390,9 @@ class SettingsActivity :
.unregisterOnSharedPreferenceChangeListener(this) .unregisterOnSharedPreferenceChangeListener(this)
if (requireMainActivityRestart) { if (requireMainActivityRestart) {
requireMainActivityRestart = false requireMainActivityRestart = false
// kill player notification
val nManager = this.getSystemService(NOTIFICATION_SERVICE) as NotificationManager
nManager.cancelAll()
restartMainActivity(this) restartMainActivity(this)
finishAffinity() finishAffinity()
} else { } else {

View File

@ -1,9 +1,11 @@
package com.github.libretube package com.github.libretube
import android.app.NotificationManager
import android.content.ComponentName import android.content.ComponentName
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.PackageManager import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate import androidx.appcompat.app.AppCompatDelegate
import androidx.preference.PreferenceManager import androidx.preference.PreferenceManager
import java.util.* import java.util.*
@ -79,6 +81,11 @@ fun changeIcon(context: Context, newLogoActivityAlias: String) {
// Needed due to different MainActivity Aliases because of the app icons // Needed due to different MainActivity Aliases because of the app icons
fun restartMainActivity(context: Context) { fun restartMainActivity(context: Context) {
// kill player notification
val nManager = context
.getSystemService(AppCompatActivity.NOTIFICATION_SERVICE) as NotificationManager
nManager.cancelAll()
// restart to MainActivity
val pm: PackageManager = context.packageManager val pm: PackageManager = context.packageManager
val intent = pm.getLaunchIntentForPackage(context.packageName) val intent = pm.getLaunchIntentForPackage(context.packageName)
intent?.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK intent?.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK