目錄
效果展示
視頻錄制
視頻播放
實現(xiàn)步驟
●實現(xiàn)自定義相機
這里代碼比較簡單就不多解釋了,另外自定義相機中實現(xiàn)了一個用于返回Camera和SurfaceHolder對象的VideoRecord接口,實現(xiàn)VideoRecord接口主要是MediaRecorder在視頻錄制時需要這兩個對象,代碼如下,另外相機代碼就不貼了,可以在案例源碼中查看。
interface VideoRecord {
/**
* 返回相機對象
*/
fun getCamera():Camera
/**
* 返回SurfaceHolder對象
*/
fun getSurfaceHolder():SurfaceHolder
}
●創(chuàng)建視頻錄制管理類
該類主要是解耦視頻錄制的代碼,該類在創(chuàng)建時需要傳入VideoRecord對象
class VideoRecordManager(private val videoRecord: VideoRecord) {
private var mRecorder: MediaRecorder? = null
/**
* 開始錄制
*/
fun start() {
if (mRecorder == null) {
mRecorder = MediaRecorder()
}
videoRecord.getCamera().unlock()
mRecorder!!.setCamera(videoRecord.getCamera())
// 這兩項需要放在setOutputFormat之前
mRecorder!!.setAudioSource(MediaRecorder.AudioSource.CAMCORDER)//聲音源
mRecorder!!.setVideoSource(MediaRecorder.VideoSource.CAMERA)//視頻源
// 設(shè)置輸出格式
mRecorder!!.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
// 這兩項需要放在setOutputFormat之后
mRecorder!!.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB)//聲音編碼格式
mRecorder!!.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP)//視頻編碼格式
//設(shè)置視頻的長寬
mRecorder!!.setVideoSize(640, 480)
mRecorder!!.setVideoFrameRate(30)
//設(shè)置比特率(比特率越高質(zhì)量越高同樣也越大)
mRecorder!!.setVideoEncodingBitRate(3 * 1024 * 1024)
//這里是調(diào)整旋轉(zhuǎn)角度(前置和后置的角度不一樣)
mRecorder!!.setOrientationHint(270)
//設(shè)置記錄會話的最大持續(xù)時間(毫秒)
mRecorder!!.setMaxDuration(10 * 1000)
//設(shè)置預(yù)覽對象
mRecorder!!.setPreviewDisplay(videoRecord.getSurfaceHolder().surface)
//設(shè)置輸出的文件路徑
mRecorder!!.setOutputFile(FileUtil.getVideoSavePath())
//預(yù)處理
mRecorder!!.prepare()
//開始錄制
mRecorder!!.start()
}
/**
* 停止錄制
*/
fun stop() {
mRecorder!!.stop()
mRecorder!!.reset()
mRecorder!!.release()
mRecorder = null
}
}
●創(chuàng)建文件工具類
該類目前用于返回視頻存儲的路徑
object FileUtil {
/**
* 獲取視頻保存路徑
*/
fun getVideoSavePath():String{
return Environment.getExternalStorageDirectory().path+File.separator+"test.mp4"
}
}
●創(chuàng)建視頻播放類
這里我用的是MediaPlayer進(jìn)行簡單的播放,當(dāng)然其他的一些播放視頻的SDK也可以。
class PlayerRecordActivity:AppCompatActivity(), SurfaceHolder.Callback {
override fun surfaceChanged(holder: SurfaceHolder?, format: Int, width: Int, height: Int) {
}
override fun surfaceDestroyed(holder: SurfaceHolder?) {
player.release()
}
override fun surfaceCreated(holder: SurfaceHolder?) {
//將播放器和SurfaceView關(guān)聯(lián)起來
player.setDisplay(holder)
//異步緩沖當(dāng)前視頻文件,也有一個同步接口
player.prepareAsync()
}
val player = MediaPlayer()
private var surfaceView:SurfaceView? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
surfaceView = SurfaceView(this)
//將布局設(shè)為SurfaceView
setContentView(surfaceView)
surfaceView!!.holder.addCallback(this@PlayerRecordActivity)
player.reset()
try {
player.setDataSource(FileUtil.getVideoSavePath())
} catch (e: Exception) {
e.printStackTrace()
}
//只有當(dāng)播放器準(zhǔn)備好了之后才能夠播放,所以播放的出發(fā)只能在觸發(fā)了prepare之后
player.setOnPreparedListener { player.start() }
}
}