概述
踩坑血泪史
- MediaCodec
- MediaRecoder
- 状态机
- 保存到本地文件
- 上传到服务器
MediaCodec
MediaCodec是Android原生提供的API,用于编解码操作,相信很多小伙伴都玩过。相对于其他API接口,MediaCodec的Java层代码较浅,主要逻辑都使用C++实现,一旦出现问题,报错信息不能充分的说明问题所在,所以在此记录鄙人使用过程种遇到的各种问题,供后来人参考。
本文主要涉及音视频编码流程。
MediaRecoder
状态机
MediaRecorder的生命周期比较重要,不同的生命周期对应不同的状态,不同的状态对应不同的可操作性方法。不按状态调用错误方法都会导致运行时错误。状态转换图可以在官网找到。
保存到本地文件
MediaRecorder可以很方便的将录制文件保存为本地文件,只要在设置outputFile为一个可用的路径即可。
注意两个点:
- 确保应用有权限写入目标文件
- 遵守参数设置顺序,参考如下javadoc
/**
* Pass in the file object to be written. Call this after setOutputFormat() but before prepare().
* File should be seekable. After setting the next output file, application should not use the
* file until {@link #stop}. Application is responsible for cleaning up unused files after
* {@link #stop} is called.
*
* @param file the file object to be written into.
*/
public void setOutputFile(File file)
mMediaRecorder.setOutputFile(mLocalFile)
PS: 方法setNextOutputFile
,用于设置下一输出的文件,当你通过android.media.MediaRecorder#setMaxFileSize
方法设置了最大的文件大小时,并且设置了android.media.MediaRecorder.OnInfoListener
后,假如文件大小到达预设值,则InfoListener会收到android.media.MediaRecorder#MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED
消息,便可以设置下一个文件路径。
mMediaRecorder.setNextOutputFile(mLocalNextFilePath + index++);
当第一个文件写满的时候,
上传到服务器
使用过MediaRecorder的同学可能都想过让其输出直接实时上传到服务器上,这里直接说我的结论,目前尝试过得方案都没有成功,这条路很难实现。有这个需求的同学还是老老实实的使用MediaCodec编码上传吧。
下面是我尝试过的失败方案,大家有成功的方案也可以拿出来分享下。
- 方案1
将SAMBA共享文件夹挂载到安卓磁盘
mount -t cifs -o username=test,passwd=123456,iocharset=utf8 //ip/workfile /mnt/cifs/mountname
然后直接设置本地路径作为输出。
mMediaRecorder.setOutputFile("/mnt/cifs/share-file.mp4");
经尝试在Android Q版本上会报SELinux错误,MediaRecorder服务无权访问该挂载点,只有Root用户才可以访问,所以对于一般应用来说,这条路行不通。
- 方案2
通过Socket获取FileDescriptor,网上有帖子说能够上传,但是我实现的时候发现接收端套接字总是在MediaRecorder启动后录制后直接断开连接,无法真正实现上传功能。
最后
以上就是大气百合为你收集整理的MediaCodec踩坑记录MediaCodecMediaRecoder的全部内容,希望文章能够帮你解决MediaCodec踩坑记录MediaCodecMediaRecoder所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复