安卓实现播放器app

安卓给app提供了:

MediaPlayer:播放视频或音频功能,详见谷歌MediaPlayer文档

借助MediaPlayer,我们可以轻松的实现一个简单的播放器app。一般来说app显示内容放在Activity中。但是试想一般的播放器要求app进入后台后可以继续播放声音,app回到前台后可以继续播放视频。因此其实MediaPlayer更适合放在Service中来播放视频,而我们的Activity仅显示视频即可。接下来我们依次实现MediaService和MediaActivity。

首先实现我们的核心类MediaService:

class MediaService : Service() {
   
    val mMediaPlayer = MediaPlayer()  // 播放媒体文件的对象
    val mMediaBinder = MediaBinder()  // 传给Activity,使得Activity可以与我们这个Service通信
    var mIsForeground = false  // 为true时变成前台服务,为false时停止前台服务成为一般的后台服务
    var mMediaListener: MediaListener? = null  // mMediaPlayer的相关回调
    var mTimer: Timer? = null  // 用来定时调用mMediaListener.onProgress回调方法的定时器
    var mTimerTask = object : TimerTask() {
     // 定时调用mMediaListener.onProgress回调方法的任务
        override fun run() {
   
            mMediaListener?.onProgress(mMediaPlayer.currentPosition, mMediaPlayer.duration)
        }
    }

    // 此类的方法都是从Activity调用的
    inner class MediaBinder : Binder() {
   
        // 设置显示视频的surfaceHolder
        fun setDisplay(surfaceHolder: SurfaceHolder?) {
   
            mMediaPlayer.setDisplay(surfaceHolder)
        }

        // 设置一个额外的媒体播放完毕时回调
        fun setMediaListener(mediaListener: MediaListener?) {
   
            mMediaListener = mediaListener
            mMediaPlayer.setOnVideoSizeChangedListener(mMediaListener)
            if (mMediaListener == null) {
   
                mTimer?.cancel()
                mTimer = null
            } else if (mTimer == null) {
   
                mTimer = Timer().apply {
    schedule(mTimerTask, 0, 100) }
            }
        }

        // 打开媒体文件
        fun open(uri: Uri) {
   
            mMediaPlayer.reset()
            mMediaPlayer.setDataSource(this@MediaService, uri)
            mMediaPlayer.prepareAsync()
        }

        // 继续或暂停播放媒体,返回true代表继续播放了,返回false代表暂停播放了
        fun playOrPause(): Boolean {
   
            if (mMediaPlayer.isPlaying) mMediaPlayer.pause()
            else mMediaPlayer.start()
            updateServiceState()
            return mMediaPlayer.isPlaying
        }

        // 停止播放媒体
        fun stop() {
   
            mMediaPlayer.stop()
            updateServiceState()
        }

        // 调整播放进度
        fun seekTo(millisecond: Int) {
   
            mMediaPlayer.seekTo(millisecond)
        }
    }

    override fun onBind(intent: Intent): IBinder {
   
        return mMediaBinder
    }

    override fun onCreate() {
   
        super.onCreate()

        mMediaPlayer.setOnPreparedListener {
   
            mMediaPlayer.start()
            updateServiceState()
        }
        mMediaPlayer.setOnCompletionListener {
   
            mMediaListener?.onCompletion(it)
            updateServiceState()
        }
        mMediaPlayer.setOnErrorListener {
    mp, what, extra ->
            Log.e(TAG, "MediaPlayer error! mediaPlayer=$mp, what=$what, extra=$extra")
            updateServiceState()
            true
        }
    }

    // 如果正在播放媒体文件,则变成前台服务,否则变成一般的后台服务
    private fun updateServiceState() {
   
        if (mMediaPlayer.isPlaying != mIsForeground) {
   
            mIsForeground = !mIsForeground
            
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值