diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaPlayerController.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaPlayerController.kt new file mode 100644 index 0000000..b384f85 --- /dev/null +++ b/AndroidMedia/src/main/java/com/frank/androidmedia/controller/MediaPlayerController.kt @@ -0,0 +1,94 @@ +package com.frank.androidmedia.controller + +import android.media.MediaPlayer +import android.view.Surface +import com.frank.androidmedia.listener.PlayerCallback +import java.io.IOException + +/** + * @author xufulong + * @date 3/18/22 1:53 PM + * @desc The controller of MediaPlayer + */ +open class MediaPlayerController(playerCallback: PlayerCallback) { + + private var mediaPlayer: MediaPlayer? = null + private var renderFirstFrame: Boolean = false + private var playerCallback: PlayerCallback? = null + + init { + this.playerCallback = playerCallback + } + + fun initPlayer(filePath :String, surface :Surface) { + if (mediaPlayer != null) { + releasePlayer() + } + try { + renderFirstFrame = false + mediaPlayer = MediaPlayer() + mediaPlayer!!.setOnPreparedListener { + mediaPlayer!!.start() + playerCallback?.onPrepare() + } + mediaPlayer!!.setOnErrorListener { + mp: MediaPlayer?, what: Int, extra: Int -> + return@setOnErrorListener playerCallback?.onError(what, extra)!! + } + mediaPlayer!!.setOnCompletionListener { + playerCallback?.onCompleteListener() + } + mediaPlayer!!.setOnInfoListener { + mp, what, extra -> ( + if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) { + if (!renderFirstFrame) { + renderFirstFrame = true + playerCallback?.onRenderFirstFrame() + } + }) + return@setOnInfoListener true + } + mediaPlayer!!.setDataSource(filePath) + mediaPlayer!!.setSurface(surface) + mediaPlayer!!.prepareAsync() + } catch (e: IOException) { + e.printStackTrace() + } + } + + fun currentPosition() : Int { + if (mediaPlayer == null) + return 0 + return mediaPlayer!!.currentPosition + } + + fun duration() : Int { + if (mediaPlayer == null) + return 0 + return mediaPlayer!!.duration + } + + fun seekTo(position :Int) { + mediaPlayer?.seekTo(position) + } + + fun togglePlay() { + if (mediaPlayer == null) + return + + if (mediaPlayer!!.isPlaying) { + mediaPlayer!!.pause() + } else { + mediaPlayer!!.start() + } + } + + fun releasePlayer() { + if (mediaPlayer != null) { + mediaPlayer!!.stop() + mediaPlayer!!.release() + mediaPlayer = null + } + } + +} \ No newline at end of file diff --git a/AndroidMedia/src/main/java/com/frank/androidmedia/listener/PlayerCallback.kt b/AndroidMedia/src/main/java/com/frank/androidmedia/listener/PlayerCallback.kt new file mode 100644 index 0000000..c71de48 --- /dev/null +++ b/AndroidMedia/src/main/java/com/frank/androidmedia/listener/PlayerCallback.kt @@ -0,0 +1,18 @@ +package com.frank.androidmedia.listener + +/** + * @author xufulong + * @date 3/18/22 2:25 PM + * @desc + */ +interface PlayerCallback { + + fun onPrepare() + + fun onError(what :Int, extra :Int) :Boolean + + fun onRenderFirstFrame() + + fun onCompleteListener() + +} \ No newline at end of file diff --git a/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.kt b/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.kt index be98d15..aa7559f 100644 --- a/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.kt +++ b/app/src/main/java/com/frank/ffmpeg/activity/VideoPreviewActivity.kt @@ -1,7 +1,6 @@ package com.frank.ffmpeg.activity import android.annotation.SuppressLint -import android.media.MediaPlayer import android.os.Bundle import android.os.Handler import android.os.Message @@ -11,12 +10,12 @@ import android.view.Surface import android.view.SurfaceHolder import android.view.SurfaceView import android.view.View +import com.frank.androidmedia.controller.MediaPlayerController +import com.frank.androidmedia.listener.PlayerCallback import com.frank.ffmpeg.R import com.frank.ffmpeg.view.VideoPreviewBar -import java.io.IOException - import com.frank.ffmpeg.handler.FFmpegHandler.MSG_TOAST /** @@ -24,9 +23,9 @@ import com.frank.ffmpeg.handler.FFmpegHandler.MSG_TOAST * Created by frank on 2019/11/16. */ -class VideoPreviewActivity : BaseActivity(), VideoPreviewBar.PreviewBarCallback { +class VideoPreviewActivity : BaseActivity(), VideoPreviewBar.PreviewBarCallback, PlayerCallback { - private var mediaPlayer: MediaPlayer? = null + private var playerController: MediaPlayerController? = null private var surfaceVideo: SurfaceView? = null private var videoPreviewBar: VideoPreviewBar? = null @@ -35,8 +34,8 @@ class VideoPreviewActivity : BaseActivity(), VideoPreviewBar.PreviewBarCallback override fun handleMessage(msg: Message) { super.handleMessage(msg) if (msg.what == MSG_UPDATE) { - if (videoPreviewBar != null && mediaPlayer != null) { - videoPreviewBar!!.updateProgress(mediaPlayer!!.currentPosition) + if (videoPreviewBar != null && playerController != null) { + videoPreviewBar!!.updateProgress(playerController!!.currentPosition()) } this.sendEmptyMessageDelayed(MSG_UPDATE, TIME_UPDATE.toLong()) } else if (msg.what == MSG_TOAST) { @@ -53,6 +52,7 @@ class VideoPreviewActivity : BaseActivity(), VideoPreviewBar.PreviewBarCallback initView() mHandler.sendEmptyMessageDelayed(MSG_TOAST, 500) + playerController = MediaPlayerController(this) } private fun initView() { @@ -76,32 +76,11 @@ class VideoPreviewActivity : BaseActivity(), VideoPreviewBar.PreviewBarCallback }) } - private fun setPrepareListener() { - if (mediaPlayer == null) { - return - } - mediaPlayer!!.setOnPreparedListener { - Log.i(TAG, "onPrepared...") - mediaPlayer!!.start() - mHandler.sendEmptyMessage(MSG_UPDATE) - } - } - private fun doPlay(filePath: String, surface: Surface?) { if (surface == null || TextUtils.isEmpty(filePath)) { return } - releasePlayer() - try { - mediaPlayer = MediaPlayer() - setPrepareListener() - mediaPlayer!!.setDataSource(filePath) - mediaPlayer!!.setSurface(surface) - mediaPlayer!!.prepareAsync() - } catch (e: IOException) { - e.printStackTrace() - } - + playerController?.initPlayer(filePath, surface) } override fun onViewClick(view: View) { @@ -114,28 +93,39 @@ class VideoPreviewActivity : BaseActivity(), VideoPreviewBar.PreviewBarCallback } override fun onStopTracking(progress: Long) { - if (mediaPlayer != null) { - Log.i(TAG, "onStopTracking progress=$progress") - mediaPlayer!!.seekTo(progress.toInt()) - } - } - - private fun releasePlayer() { - if (mediaPlayer != null) { - mediaPlayer!!.stop() - mediaPlayer!!.release() - mediaPlayer = null + if (playerController != null) { + playerController!!.seekTo(progress.toInt()) } } override fun onDestroy() { super.onDestroy() - releasePlayer() + playerController?.releasePlayer() if (videoPreviewBar != null) { videoPreviewBar!!.release() } } + /// player callback + + override fun onPrepare() { + Log.i(TAG, "onPrepare...") + mHandler.sendEmptyMessage(MSG_UPDATE) + } + + override fun onRenderFirstFrame() { + Log.i(TAG, "onRenderFirstFrame...") + } + + override fun onError(what: Int, extra: Int): Boolean { + Log.e(TAG, "onError...") + return true + } + + override fun onCompleteListener() { + Log.i(TAG, "onCompleteListener...") + } + companion object { private val TAG = VideoPreviewActivity::class.java.simpleName