Android实现mediaPlayer+surface+seekbar自定义视频播放器

本来已经被放弃的场景,应甲方要求又加回来了,还加了个视频播放功能 orz 哭晕了

mediaPlayer+surface+seekbar还原抖音视频播放器 自定义视频播放器kotlin实现

本代码实现一个自定义的视频播放器,进度条可拖动,实现效果(因为开了2k图有点大)
请添加图片描述

0.视频存放位置

在res下创建raw文件夹,放视频文件video.mp4

1.关键代码

项目里有很多其他交互代码,下面我放一些主要的代码
几个关键点:

  • mediaPlayer的start需要在onPrepare的监听方法中调用,否则初始化视频资源会出问题
  • 实现seekbar和视频播放进度同步:使用Thread,sbThread继承runable,重写run方法
  • 实现拖动进度条,改变视频播放进度:重写进度条的监听onProgressChanged,onStartTrackingTouch,onStopTrackingTouch
class TiktokActivity : AppCompatActivity(), SeekBar.OnSeekBarChangeListener {
    private lateinit var sb_tiktok: SeekBar
    private lateinit var surfaceView: SurfaceView
    var mediaPlayer = MediaPlayer()
    private  lateinit var binding: ActivityTiktokBinding
    private var position = 0
    
    private var touchSB = false
    
    override fun onCreate(savedInstanceState: Bundle?) {
        
        super.onCreate(savedInstanceState)

        binding = ActivityTiktokBinding.inflate(layoutInflater)
        setContentView(binding.root)
        sb_tiktok = findViewById<SeekBar>(R.id.sb_tiktok)

        surfaceView = findViewById(R.id.suf_tiktok)
        surfaceView.holder.setKeepScreenOn(true)
        surfaceView.holder.addCallback(object : SurfaceHolder.Callback {
            override fun surfaceCreated(p0: SurfaceHolder) {

            }

            override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {

            }

            override fun surfaceDestroyed(p0: SurfaceHolder) {
                if (mediaPlayer != null && mediaPlayer.isPlaying()){
                    position = mediaPlayer.currentPosition
                    mediaPlayer.stop()
                }
            }
        })


        sb_tiktok.setOnSeekBarChangeListener(this)
        
        play()
    }
    fun play() {
        try {
            mediaPlayer.reset()
            mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC)
            mediaPlayer.setDataSource(this,
                Uri.parse("android.resource://"+this.packageName+"/"+R.raw.vedio))

        }catch (e: IOException){
            e.printStackTrace()

        }
        try {
            mediaPlayer.prepare()
        }catch (e: IOException){
            e.printStackTrace()
        }

        mediaPlayer.setOnPreparedListener {
            mediaPlayer.setDisplay(surfaceView.holder)
            mediaPlayer.start()
            sb_tiktok.max = mediaPlayer.duration
            val th = Thread(sbThread)
            th.start()
        }
        mediaPlayer.setOnCompletionListener {

        }
    }

    override fun onProgressChanged(p0: SeekBar?, p1: Int, p2: Boolean) {
        if (touchSB == true){
            var process = p0?.progress
            if (process != null) {
                mediaPlayer.seekTo(process)
            }
        }

    }

    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onStartTrackingTouch(p0: SeekBar?) {
        touchSB = true
        if (p0 != null) {
            p0.maxHeight = 45
            p0.minHeight = 45
//            position = p0.progress
            var process = p0.progress
            mediaPlayer.seekTo(process)
        }
    }

    @RequiresApi(Build.VERSION_CODES.Q)
    override fun onStopTrackingTouch(p0: SeekBar?) {
        touchSB = false
        if (p0 != null) {
            p0.maxHeight = 10
            p0.minHeight = 10
            var process = p0.progress
            mediaPlayer.seekTo(process)
            mediaPlayer.start()

        }
    }

    val sbThread:Runnable = object : Runnable {
        override fun run() {
            while (mediaPlayer.isPlaying){
                sb_tiktok.max = mediaPlayer.duration
                sb_tiktok.progress = mediaPlayer.currentPosition
                println(mediaPlayer.currentPosition)
                try {
                    Thread.sleep(100)

                }catch (e: InterruptedIOException){
                    e.printStackTrace()
                }
            }
        }
    }
}

3.自定义seekbar可以看我的另一篇博客

写的比较详细
自定义seekbar

有问题可以在评论区问我

4.布局layout中只需要放一个surface

忘记写了,补进来

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值