- 读取音视频数据
*/
fun readBuffer(byteBuffer: ByteBuffer): Int
/**
- 获取当前帧时间
*/
fun getCurrentTimestamp(): Long
/**
- Seek到指定位置,并返回实际帧的时间戳
*/
fun seek(pos: Long): Long
fun setStartPos(pos: Long)
/**
- 停止读取数据
*/
fun stop()
}
有了上面封装的工具,一切就变得很简单了,做一个代理转接就行了。
- 视频提取器
class VideoExtractor(path: String): IExtractor {
private val mMediaExtractor = MMExtractor(path)
override fun getFormat(): MediaFormat? {
return mMediaExtractor.getVideoFormat()
}
override fun readBuffer(byteBuffer: ByteBuffer): Int {
return mMediaExtractor.readBuffer(byteBuffer)
}
override fun getCurrentTimestamp(): Long {
return mMediaExtractor.getCurrentTimestamp()
}
override fun seek(pos: Long): Long {
return mMediaExtractor.seek(pos)
}
override fun setStartPos(pos: Long) {
return mMediaExtractor.setStartPos(pos)
}
override fun stop() {
mMediaExtractor.stop()
}
}
- 音频提取器
class AudioExtractor(path: String): IExtractor {
private val mMediaExtractor = MMExtractor(path)
override fun getFormat(): MediaFormat? {
return mMediaExtractor.getAudioFormat()
}
override fun readBuffer(byteBuffer: ByteBuffer): Int {
return mMediaExtractor.readBuffer(byteBuffer)
}
override fun getCurrentTimestamp(): Long {
return mMediaExtractor.getCurrentTimestamp()
}
override fun seek(pos: Long): Long {
return mMediaExtractor.seek(pos)
}
override fun setStartPos(pos: Long) {
return mMediaExtractor.setStartPos(pos)
}
override fun stop() {
mMediaExtractor.stop()
}
}
二、视频播放
我们先来定义一个视频解码器子类,继承BaseDecoder
class VideoDecoder(path: String,
sfv: SurfaceView?,
surface: Surface?): BaseDecoder(path) {
private val TAG = “VideoDecoder”
private val mSurfaceView = sfv
private var mSurface = surface
override fun check(): Boolean {
if (mSurfaceView == null && mSurface == null) {
Log.w(TAG, “SurfaceView和Surface都为空,至少需要一个不为空”)
mStateListener?.decoderError(this, “显示器为空”)
return false
}
return true
}
override fun initExtractor(path: String): IExtractor {
return VideoExtractor(path)
}
override fun initSpecParams(format: MediaFormat) {
}
override fun configCodec(codec: MediaCodec, format: MediaFormat): Boolean {
if (mSurface != null) {
codec.configure(format, mSurface , null, 0)
notifyDecode()
} else {
mSurfaceView?.holder?.addCallback(object : SurfaceHolder.Callback2 {
override fun surfaceRedrawNeeded(holder: SurfaceHolder) {
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
}
override fun surfaceCreated(holder: SurfaceHolder) {
mSurface = holder.surface
configCodec(codec, fo