Media-Android的相关知识 一. 调用系统相机,拍照,录像 调用系统相机,无论是拍照还是录像,首先要判断是否有权限(包括外存储权限)。 如果没有的话,需要申请;如果已经申请过了但是没有授权,那么提示; 权限通过之后,要通过隐式Intent调用,来唤起系统相机。拍照和录像的Intent的Action是不一样的。 另外一般要加EXTRA_OUTPUT用于指定拍照或录像的文件;对于Android7.0以下的,直接Uri.fromFile(),其他的一律要使用EXTERNAL_CONTENT_URI来操作。 后面会有ActivityForResult回来,然后根据返回的数据进行继续的处理。 调用起系统相机的时候,最好是先resolveActivity一下,遇到过有的机型没有这个的功能的, 另外也需要捕获异常。 二. 简单的自定义相机,拍照,录像 有时候需要自定义相机,但不涉及美颜变换之类的,那么就可以简单的方式来自定义相机。 这个时候,用到了camera的setPreviewDisplay接口,对接一个GLSurfaceview的SurfaceHolder进去. 当然还需要对camera配置一些参数, 比如预览大小,旋转角度等。 然后Camera就在这个GLSurfaceView上完成预览。当需要拍照的时候,调用takePicutre接口。 如果是自定义录像,则需要首先创建一个MediaRecorder,然后stop preview, unlock camera,并且设置camera到Recorder上. 然后MediaRecorder设置previewDisplay到Holder上。 除了MediaRecorder,还可以用MediaCodec,以及AudioRecord+MediaMuxer。由于我们是简单的自定义相机, 多数情况下,是为了定制UI, 那么仅仅用MediaRecorder就能完成任务了。 三. 美颜相机,拍照,录像 这种需求的自定义相机比较复杂.不能如简单自定义那样,一般我们寻求开源的库,然后基于 它们做定制。但是原理都是通用的: 都是利用了setPreviewTexture的方式(setPreviewFrame少见)。让相机预览到SurfaceTexture上。然后借助 SufraceTexture 的onFrameAvalible的通知,进行自定义渲染。这个时候,有两个选择,一个是使用 GLSurfaceView,这个类包装了OpenGLES的一些配置初始化管理,并且有Render可以设置,我们只需要 再Render的回调的地方做一些扩展工作就可以了。比如onDrawFrame的时候,先更新下纹理,然后Draw到一个 FBO上,自定义处理之后,再Draw到GL的屏幕帧缓冲里即可。 参考OpenCV的Android相机模块。 另外一个选择就是如WebRTC那样,不用GLSurfaceView,直接用SufraceView,自己管理GL的环境。优点是更加灵活 多变,缺点就是变得比较复杂。 这种方式下,无论是拍照还是录像,都有不少的方案,可以选择适合需求的。 四. 录屏(MediaRecorder,MediaCodec) 简单的录屏就是直接用MediaRecorder对接VirtualDisplay。调用MR的getSurface获取输入sufrace,MediaProjection创建display的时候,作为参数设置 进去。后面recorder.start()即可。 而且MediaRecorder也可以配置音源,一般是MIC。这样,录屏出来的,就是个完整的MP4了。 有时候,MediaRecorder满足不了需求,比如录屏还要混合某个音源的时候,那么就只能用MediaCodec来做了。用MeidaCodec的时候, 就要有MediaMuxer,如果要读取音视频文件的话,那么还要用到MediaExtrator。 WebRTC的录屏,依旧是用了自己管理GL的模式,创建出SufraceTexture,然后new一个Sufrace(stex),传给VirtualDisplay, 最后走的跟Camera类似的流程。 五. 录音(MediaRecorder,AudioRecord) 最简单的录音方式就是MediaRecorder,直接设置音源为MIC,设置输出格式与文件名称(一般amr)。 调用start()就开始录音了。 注意权限一定要提前申请。 另外一个比较底层的方式,就是AudioRecord,它录制的是原始的裸音频。播放它的只有AudioTrack以及一些PCM文件播放器。 对原始的音频数据可以做各种处理,操作之后,可以继续调用MediaCodec进行硬件编码成其它的主流音频格式比如(mp3), 也可以继续使用MediaMuxer与视频流进行合并输出到文件。 六. 图片压缩 图片压缩的库,有很多,简单实用的就是compressor。它的基本原理有两个步骤: 一个是压缩宽度高度,对图片进行一个宽度高度上的缩放, API是Bitmap.createBitmap。 一个是有损压缩,一般是JPEG的格式,API是Bitmap.compress。 一般经过这两个步骤,图片的大小就符合要求了。 另外还有一个开源的叫luban的库,比较复杂,据说效果比较好,在高要求的情况下,可 以拿来使用。 七. 视频压缩 视频压缩比较复杂,一般直接用开源的库。存在软解与硬解。 软解的代表是FFMPEG,需要编辑.so然后通过JNI来使用,效率比较低。 硬解的是直接用MediaCodec+MediaExtractor+EGL这种方式,代表是videocompressor。 如果效果不好的话,则需要在这些开源库的基础上进行优化。 八. 图片裁剪、预览、视频播放、Audio播放 裁剪:com.github.yalantis:ucrop 预览: PhotoView 视频播放: MediaPlayer/VideoView Audio播放: AudioTrack/MediaPlayer/SoundPool 九. WebRTC相关(采集、Render) 自己管理EGLBase环境,通过SurfaceTexture以及对应的Surface来采集摄像头\媒体文件\屏幕来的视频源。播放的时候, 使用EG渲染到SurfaceView上。
Media-Android的相关知识
最新推荐文章于 2023-04-06 13:59:29 发布