我一直试图在后台使用系外播放器media3库播放音频。因此,到目前为止,我能够播放音频,它也是在后台播放,但我一直保持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
}
}
}
这是我的碎片
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
}
}
我所面临的问题
如果有人遇到过问题,请帮助我解决问题。提亚
发布于 2022-07-23 14:59:47
经过多次尝试和大量研究,我找到了我自己问题的答案。发布答案,因为它可以帮助社区中的人找到同样的答案。没有什么不好的感觉,但三天后,我发布了我自己的问题的答案,但这里没有人来帮助我。
注意:我的代码中使用的Exoplayer(Mediaplayer)是media3库,它处于beta模式。代码在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)
}
}
}
})
}
}
这是我的服务班
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
)
}
我所面临的问题
在实现了上面这样的事情之后,
https://stackoverflow.com/questions/73052245
复制相似问题