pri*_*imo 3 android exoplayer android-jetpack
我一直在尝试在后台使用 exoplayer media3 lib 播放音频。到目前为止,我能够播放音频并且它也在后台播放,但我将 url 保留为静态的测试 url。现在,我想将 url 传递给我的服务类,但我无法理解该怎么做。
在这里附上我的代码文件..
class PlaybackService : MediaSessionService() {
// Create your Player and MediaSession in the onCreate lifecycle event
lateinit var player: Player
private var mediaSession: MediaSession? = null
override fun onCreate() {
super.onCreate()
player = ExoPlayer.Builder(this).build()
mediaSession = MediaSession.Builder(this, player).build()
player.prepare()
player.playWhenReady = true
player.seekTo(0, 0)
val mediaItem =
MediaItem.fromUri("https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4")
player.setMediaItem(mediaItem)
}
// Return a MediaSession to link with the MediaController that is making
// this request.
override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? =
mediaSession
override fun onDestroy() {
mediaSession?.run {
player.release()
release()
mediaSession = null
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的片段
class MusicPlayerFragment : BaseFragment() {
private lateinit var controllerFuture: ListenableFuture<MediaController>
private val controller: MediaController?
get() = if (controllerFuture.isDone) controllerFuture.get() else null
private val currentWindow = 0
var playerStopped = true
private val playbackPosition: Long = 0
override fun onStart() {
super.onStart()
playMedia()
}
private fun playMedia() {
val sessionToken = SessionToken(
requireContext(),
ComponentName(requireContext(), PlaybackService::class.java)
)
controllerFuture =
MediaController.Builder(requireContext(), sessionToken)
.buildAsync()
controllerFuture.addListener({
fragmentMusicPlayerBinding.playerView.player = controllerFuture.get()
fragmentMusicPlayerBinding.controls.player = controllerFuture.get()
}, MoreExecutors.directExecutor())
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
fragmentMusicPlayerBinding.imgPlay.setOnClickListener {
if (playerStopped) {
playerStopped = false
playMedia()
}
}
fragmentMusicPlayerBinding.imgStop.setOnClickListener {
stopMediaPlayer()
}
fragmentMusicPlayerBinding.imgPause.setOnClickListener {
fragmentMusicPlayerBinding.playerView.player?.pause()
}
fragmentMusicPlayerBinding.imgRewind.setOnClickListener {
fragmentMusicPlayerBinding.playerView.player?.seekTo(0)
}
}
private fun stopMediaPlayer() {
controllerFuture.get().stop()
controllerFuture.get().playWhenReady = false
MediaController.releaseFuture(controllerFuture)
playerStopped = true
fragmentMusicPlayerBinding.playerView.player = null
}
Run Code Online (Sandbox Code Playgroud)
}
我面临的问题
我想动态设置从 api 获取的媒体 uri。那么,该怎么做呢?
使用此代码,我在通知中心收到 mediapplayer 通知,当我从那里播放或暂停时,音乐会停止或播放,但同时当我停止通知并从片段播放时,音乐不会播放。
每当我停止片段中的音乐时,音乐也会在后台继续播放,并且通知仍然存在
当我从通知中心清除音乐通知时,音乐也会继续播放。
如果有人遇到过任何问题,请帮助我解决我所面临的问题。TIA
经过多次尝试和大量研究,我找到了自己问题的答案。发布答案可以帮助社区中的其他人找到相同的答案。没有什么不好的感觉,但三天后我发布了我自己问题的答案,但这里没有人来帮助我。
注意:我的代码中使用的 Exoplayer(Mediaplayer) 是处于 beta 模式的 media3 lib。代码在 android 11 和 android 12 中进行了测试,运行良好。所以,继续使用它吧。
这个YouTube 视频对我的回答帮助很大。
我按照视频中的说明稍微修改了我的代码,这是我的最终代码。
class MusicPlayerActivity : BaseActivity() {
lateinit var musicPlayerBinding: ActivityMusicPlayerBinding
var player: Player? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
musicPlayerBinding = ActivityMusicPlayerBinding.inflate(layoutInflater)
setContentView(musicPlayerBinding.root)
bindMusicService()
}
override fun onBackPressed() {
unbindService(playerServiceConnection)
if (player?.isPlaying!!) {
player?.stop()
}
player?.release()
player = null
super.onBackPressed()
}
private fun bindMusicService() {
val intent = Intent(this, PlayerService::class.java)
bindService(intent, playerServiceConnection, Context.BIND_AUTO_CREATE)
}
private val playerServiceConnection = object : ServiceConnection {
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
val binder = service as PlayerService.ServiceBinder
player = binder.getPlayerService().player!!
player?.prepare()
player?.playWhenReady = false
player?.seekTo(0, 0)
val mediaMetaData = MediaMetadata.Builder()
.setAlbumTitle(MusicPlayerData.audioTitle)
.build()
val mediaItem =
MediaItem.Builder().setMediaMetadata(mediaMetaData)
.setUri(MusicPlayerData.audioUri)
.build()
player?.setMediaItem(mediaItem)
setPlayerControls()
}
override fun onServiceDisconnected(name: ComponentName?) {
TODO("Not yet implemented")
}
}
private fun setPlayerControls() {
musicPlayerBinding.playerView.player = player
musicPlayerBinding.controls.player = player
player?.addListener(object : Player.Listener {
override fun onPlaybackStateChanged(playbackState: Int) {
super.onPlaybackStateChanged(playbackState)
when (playbackState) {
Player.STATE_BUFFERING -> show(musicPlayerBinding.progressCircular)
Player.STATE_READY -> {
player?.playWhenReady = true
hide(musicPlayerBinding.progressCircular)
}
}
}
})
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的服务等级
class PlayerService : Service() {
private val iBinder = ServiceBinder()
var player: Player? = null
private var mediaSession: MediaSession? = null
lateinit var notificationManager: PlayerNotificationManager
inner class ServiceBinder : Binder() {
fun getPlayerService(): PlayerService = this@PlayerService
}
override fun onBind(intent: Intent?): IBinder {
return iBinder
}
override fun onCreate() {
super.onCreate()
player = ExoPlayer.Builder(this).build()
mediaSession =
MediaSession.Builder(this, player!!).setSessionActivity(pendingIntent()!!).setId(Random(5).toString())
.build()
notificationManager = PlayerNotificationManager.Builder(this, 111, "Music Channel")
.setChannelImportance(IMPORTANCE_HIGH)
.setSmallIconResourceId(R.drawable.music)
.setChannelDescriptionResourceId(R.string.app_name)
.setChannelNameResourceId(R.string.app_name)
.setMediaDescriptionAdapter(audioDescriptor)
.setNotificationListener(notificationListener)
.build()
notificationManager.setPlayer(player)
notificationManager.setPriority(PRIORITY_MAX)
notificationManager.setUseRewindAction(true)
notificationManager.setUseFastForwardAction(false)
notificationManager.setUsePreviousAction(false)
notificationManager.setUsePlayPauseActions(true)
}
override fun onDestroy() {
if (player?.isPlaying!!) {
player?.stop()
}
notificationManager.setPlayer(null)
player?.release()
player = null
stopForeground(true)
stopSelf()
super.onDestroy()
}
private val notificationListener = object : PlayerNotificationManager.NotificationListener {
override fun onNotificationCancelled(notificationId: Int, dismissedByUser: Boolean) {
super.onNotificationCancelled(notificationId, dismissedByUser)
stopForeground(true)
if (player?.isPlaying!!) {
player?.stop()
player?.release()
}
}
override fun onNotificationPosted(
notificationId: Int,
notification: Notification,
ongoing: Boolean
) {
super.onNotificationPosted(notificationId, notification, ongoing)
startForeground(notificationId, notification)
}
}
private val audioDescriptor = object : PlayerNotificationManager.MediaDescriptionAdapter {
override fun getCurrentContentTitle(player: Player): CharSequence {
return player.currentMediaItem?.mediaMetadata?.albumTitle!!
}
override fun createCurrentContentIntent(player: Player): PendingIntent? {
return pendingIntent()
}
override fun getCurrentContentText(player: Player): CharSequence? {
return ""
}
override fun getCurrentLargeIcon(
player: Player,
callback: PlayerNotificationManager.BitmapCallback
): Bitmap? {
val bitmapDrawable: BitmapDrawable =
ContextCompat.getDrawable(
applicationContext,
R.drawable.cma_logo_render
) as BitmapDrawable
return bitmapDrawable.bitmap
}
}
private fun pendingIntent(): PendingIntent? {
val intent = Intent(applicationContext, MusicPlayerActivity::class.java)
return PendingIntent.getActivity(
applicationContext,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
)
}
Run Code Online (Sandbox Code Playgroud)
我面临的问题
我想动态设置从 api 获取的媒体 uri。那么,该怎么做呢? -----> 无需在服务类中设置媒体 uri,我们可以从活动中的服务类获取播放器的实例,并仅执行活动类中的所有功能
使用此代码,我在通知中心收到 mediapplayer 通知,当我从那里播放或暂停时,音乐会停止或播放,但同时当我停止通知并从片段播放时,音乐不会播放。 ----->修改我的服务类后问题解决
每当我停止片段中的音乐时,音乐也会在后台继续播放,并且通知仍然存在 -----> 修改我的服务类后问题得到解决
当我从通知中心清除音乐通知时,音乐也会继续播放。
-----> 为此,我已将会话活动设置为从当前播放状态打开活动
执行完上面的事情后,
归档时间: |
|
查看次数: |
3461 次 |
最近记录: |