前言
因?yàn)镸ediaRecorder和MediaPlayer都是比較常用的API,比較簡(jiǎn)單恩商,只需要寫好對(duì)應(yīng)的配置就實(shí)現(xiàn)了音視頻的錄制功能变逃,對(duì)于音頻錄制要求不高的話,基本滿足日常開(kāi)發(fā)的需求怠堪。
正文
首先我們添加需要使用到的權(quán)限:攝像頭揽乱,讀寫內(nèi)存卡和錄音,千萬(wàn)不要忘記粟矿。
錄制
/**
* @author li.zhipeng
*
* 錄制視頻頁(yè)面
* */
class MediaRecorderActivity : AppCompatActivity(), SurfaceHolder.Callback {
private val videoRecorderFile: String
init {
val fileDir = File("${Environment.getExternalStorageDirectory().absolutePath}/test")
fileDir.mkdirs()
// 創(chuàng)建要保存的錄音文件的路徑
videoRecorderFile = "$fileDir/video_record.mp4"
}
private var camera: Camera? = null
// 需要自己維護(hù)錄制的狀態(tài)
private var isRecording = false
private var mediaRecorder: MediaRecorder? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
setContentView(R.layout.activity_media_recorder)
surface_view.holder.addCallback(this)
// 新版本可以忽略設(shè)置下面的屬性
// surface_view.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS)
video_record.setOnClickListener {
if (isRecording) {
stopVideoRecord()
} else {
startVideoRecord()
}
}
}
override fun surfaceCreated(holder: SurfaceHolder?) {
// 開(kāi)啟攝像頭
if (camera == null) {
camera = Camera.open()
}
// 雖然關(guān)閉了提示音凰棉,但是是沒(méi)有作用的
camera!!.enableShutterSound(false)
camera!!.setDisplayOrientation(90)
// 綁定顯示的SurfaceHolder
camera!!.setPreviewDisplay(holder)
// 開(kāi)啟預(yù)覽
camera!!.startPreview()
}
override fun surfaceChanged(holder: SurfaceHolder, format: Int, width: Int, height: Int) {
if (holder.surface == null) {
return
}
camera!!.stopPreview()
camera!!.setPreviewDisplay(holder)
camera!!.startPreview()
}
override fun surfaceDestroyed(holder: SurfaceHolder?) {
}
private fun startVideoRecord() {
mediaRecorder = MediaRecorder().apply {
camera!!.unlock()
setCamera(camera!!)
// 設(shè)置錄制的角度,如果與攝像頭不符陌粹,會(huì)出現(xiàn)視頻角度不對(duì)的問(wèn)題
setOrientationHint(90);
// 設(shè)置錄音和錄制視頻的來(lái)源
setAudioSource(MediaRecorder.AudioSource.CAMCORDER)
setVideoSource(MediaRecorder.VideoSource.CAMERA)
// 還可以設(shè)置其他的信息
// 輸出的視頻格式
// setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
// 設(shè)置編碼的格式
// setVideoEncoder(MediaRecorder.VideoEncoder.H264)
// 設(shè)置視頻的大小撒犀,必須要在設(shè)置視頻格式之后設(shè)置,否則會(huì)報(bào)錯(cuò)
// setVideoSize()
//視頻的幀率
// setVideoFrameRate(25)
// 設(shè)置錄制的質(zhì)量
setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH))
// 設(shè)置文件的輸出路徑
setOutputFile(videoRecorderFile)
setPreviewDisplay(surface_view.holder.surface)
prepare()
// 開(kāi)始錄制
start()
}
isRecording = true
video_record.text = "停止錄制"
}
private fun stopVideoRecord() {
mediaRecorder?.let {
it.stop()
it.release()
mediaRecorder = null
}
camera!!.lock()
isRecording = false
video_record.text = "開(kāi)始錄制"
// 跳轉(zhuǎn)播放
startActivity(Intent(this, MediaPlayerActivity::class.java))
}
}
非常的簡(jiǎn)單掏秩,值得一提的是這種錄制方式有一個(gè)特別大的缺陷:開(kāi)始錄制的時(shí)候有“滴”的提示音;蛭琛!蒙幻!
可能不同的手機(jī)有不一樣的表現(xiàn)映凳,但是這個(gè)提示音是無(wú)法消除的,這也是為了防止用戶的隱私泄露邮破,所以為了用戶體驗(yàn)诈豌,大部分的軟件都沒(méi)有使用MediaRecorder。
播放
/**
* @author li.zhipeng
*
* MediaPlayer播放視頻
* */
class MediaPlayerActivity : AppCompatActivity(), MediaPlayer.OnPreparedListener {
private val videoRecorderFile: String
init {
val fileDir = File("${Environment.getExternalStorageDirectory().absolutePath}/test")
fileDir.mkdirs()
// 創(chuàng)建要保存的錄音文件的路徑
videoRecorderFile = "$fileDir/video_record.mp4"
}
private lateinit var mediaPlayer: MediaPlayer
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_media_player)
}
override fun onResume() {
super.onResume()
if (this::mediaPlayer.isInitialized) {
mediaPlayer.start()
} else {
createMediaPlayer()
}
}
private fun createMediaPlayer() {
mediaPlayer = MediaPlayer().apply {
setDataSource(videoRecorderFile)
setOnPreparedListener(this@MediaPlayerActivity)
prepare()
start()
}
}
override fun onPrepared(mp: MediaPlayer?) {
mediaPlayer.setDisplay(surface_view.holder)
}
override fun onStop() {
super.onStop()
mediaPlayer.pause()
}
override fun onDestroy() {
super.onDestroy()
mediaPlayer.stop()
mediaPlayer.release()
}
}
播放同樣也非常的簡(jiǎn)單抒和,只需要把MediaPlayer和SurfaceHolder綁定起來(lái)矫渔,畫面就會(huì)自己顯示上去。
總結(jié)
MediaRecoder和MediaPlayer非常的簡(jiǎn)單摧莽,下一篇我們使用AudioRecoder錄制PCM音頻和播放庙洼,看看他們之間有什么樣的區(qū)別。