工作这么久,一直都很忙,好不容易闲下来就不习惯了。突然觉得应该做点有意义的事情,这几天研究了一下视屏直播方面的知识,使用camara,surfaceview,MediaRecorder录制音视频,surfaceview提供camara的预览。好了废话不多说了首先了解api吧。
1.使用camara录制视频有两种方式:一是借助Intent和MediaStroe调用系统Camera App程序来实现拍照和摄像功能,二是根据Camera API自写Camera程序。
第一种使用系统录制视频的方法:
对mediaStore有兴趣的同学可以看一篇文章 http://www.xuebuyuan.com/2038576.html;
- Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
- //在这里的QUALITY参数,值为两个,一个是0,一个是1,代表录制视频的清晰程度,0最不清楚,1最清楚
- //没有0-1的中间值,另外,使用1也是比较占内存的,测试了一下,录制1分钟,大概内存是43M多
- //使用0,录制1分钟大概内存是几兆
- intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
- // 限制时长 ,参数61代表61秒,可以根据需求自己调,最高应该是2个小时。
- //当在这里设置时长之后,录制到达时间,系统会自动保存视频,停止录制
- intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 61);
- // 限制大小 限制视频的大小,这里是100兆。当大小到达的时候,系统会自动停止录制
- intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024 * 1024 * 100);
- //在这里有录制完成之后的操作,系统会默认把视频放到照片的文件夹中
- startActivityForResult(intent, 11);
- 第二种调用camara的api的方法 本文中使用的是第二种方法
一。首先初始化camara
camara主要的几个api
open():通过open方法获取Camera实例。 CameraInfo.CAMERA_FACING_BACK//后置摄像头,CameraInfo.CAMERA_FACING_FRONT前置摄像头
setPreviewDisplay(SurfaceHolder):设置预览拍照mCamera.setPreviewCallback(null)//预览回调 停止预览
startPreview():开始预览
stopPreview():停止预览mCamera.lock();// 默认Camera都是锁定的
mCamera.unlock();解锁摄像头 camara默认是lock状态所以在camara初始化的时候一定要调用mCamera.lock();
release():释放Camera实例 记住,在应用程序使用完Camera对象后,一定要调用Camera.release()方法来释放Camera对象。
mCamera.setParameters(params); 传入的是paramas对象 这里可以设置一些camara参数 // 设置旋转代码
params.setRotation(90); params.set("orientation", "portrait");//设置屏幕方向 params.setJpegQuality()//设置图像输出质量 params.setPictureFormat//设置图片输出格式 params.setPictureSize设置图片大小 params.setPreviewFormat设置图像预览格式 params.setPreviewSize设置预览画面大小
上面调用系统Camera App,我们压根不需要任何权限,但是这里用Camera API,就必须在manifest内声明使用权限,通常由以下三项
<uses-permission android:name = "android.permission.CAMERA" />
<uses-feature android:name = "android.hardware.camera" />
<uses-feature android:name = "android.hardware.camera.autofocus" />
一般拍照和摄像的时候需要写到sd卡上,所以还有一向权限声明如下
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
真做摄像功能时,需要音频录制和视频录制功能,所以又需要下面两项权限声明
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
另外使用Camera API拍照或摄像,都需要用到预览,预览就要用到SurfaceView,为此Activity的布局中必须有SurfaceView。
二。接下来是surfaceview作为camara提供预览 这里介绍一下surfaceview的几个重要的API
-
SurfaceView是View的子类,它内嵌了一个专门用于绘制的Surface,你可以控制这个Surface的格式和尺寸,Surfaceview控制这个Surface的绘制位置。surface是纵深排序(Z-ordered)的,说明它总在自己所在窗口的后面。SurfaceView提供了一个可见区域,只有在这个可见区域内的surface内容才可见。surface的排版显示受到视图层级关系的影响,它的兄弟视图结点会在顶端显示。这意味者 surface的内容会被它的兄弟视图遮挡,这一特性可以用来放置遮盖物(overlays)(例如,文本和按钮等控件)。注意,如果surface上面有透明控件,那么每次surface变化都会引起框架重新计算它和顶层控件的透明效果,这会影响性能。
SurfaceView默认使用双缓冲技术的,它支持在子线程中绘制图像,这样就不会阻塞主线程了,所以它更适合于游戏的开发。2. SurfaceView的使用
首先继承SurfaceView,并实现SurfaceHolder.Callback接口,实现它的三个方法:surfaceCreated,surfaceChanged,surfaceDestroyed。
-
SurfaceView.getHolder();//获取surfaceholder对象为访问surface提供访问的接口 surface控制器,用来操纵surface
surfaceCreated(SurfaceHolder holder):surface创建的时候调用,一般在该方法中启动绘图的线程。
surfaceChanged(SurfaceHolder holder, int format, int width,int height):surface尺寸发生改变的时候调用,如横竖屏切换。
surfaceDestroyed(SurfaceHolder holder) :surface被销毁的时候调用,如退出游戏画面,一般在该方法中停止绘图线程。
还需要获得SurfaceHolder,并添加回调函数,这样这三个方法才会执行。 - 三,mediarecoder
-
说明:
与MediaPlayer类非常相似MediaRecorder也有它自己的状态图。下面是关于MediaRecorder的各个状态的介绍:
Initial:初始状态,当使用new()方法创建一个MediaRecorder对象或者调用了reset()方法时,该MediaRecorder对象处于Initial状态。在设定视频源或者音频源之后将转换为Initialized状态。另外,在除Released状态外的其它状态通过调用reset()方法都可以使MediaRecorder进入该状态。
Initialized:已初始化状态,可以通过在Initial状态调用setAudioSource()或setVideoSource()方法进入该状态。在这个状态可以通过setOutputFormat()方法设置输出格式,此时MediaRecorder转换为DataSourceConfigured状态。另外,通过reset()方法进入Initial状态。
DataSourceConfigured:数据源配置状态,这期间可以设定编码方式、输出文件、屏幕旋转、预览显示等等。可以在Initialized状态通过setOutputFormat()方法进入该状态。另外,可以通过reset()方法回到Initial状态,或者通过prepare()方法到达Prepared状态。
Prepared:就绪状态,在DataSourceConfigured状态通过prepare()方法进入该状态。在这个状态可以通过start()进入录制状态。另外,可以通过reset()方法回到Initialized状态。
Recording:录制状态,可以在Prepared状态通过调用start()方法进入该状态。另外,它可以通过stop()方法或reset()方法回到Initial状态。
Released:释放状态(官方文档给出的词叫做Idle state 空闲状态),可以通过在Initial状态调用release()方法来进入这个状态,这时将会释放所有和MediaRecorder对象绑定的资源。
Error:错误状态,当错误发生的时候进入这个状态,它可以通过reset()方法进入Initial状态。
提示:与MediaPlayer相似使用MediaRecorder录音录像时需要严格遵守状态图说明中的函数调用先后顺序,在不同的状态调用不同的函数,否则会出现异常。
final static int
getAudioSourceMax()
获取音频源的最大值。
int
getMaxAmplitude()
获取在前一次调用此方法之后录音中出现的最大振幅。
void
prepare()
准备录制。
void
release()
释放资源。
void
reset()
将MediaRecorder设为空闲状态,即Initial状态。
void
setAudioChannels(int numChannels)
设置录制的音频通道数。
void
setAudioEncoder(int audio_encoder)
设置所录制的声音的编码格式。
void
setAudioEncodingBitRate(int bitRate)
设置所录制的声音的编码位率。
void
setAudioSamplingRate(int samplingRate)
设置所录制的声音的采样率。
void
setAudioSource(int audio_source)
设置声音来源,一般传入 MediaRecorder. AudioSource.MIC参数指定录制来自麦克风的声音。
void
setCamera(Camera c)
设置一个摄像头用于录制。
void
setCaptureRate(double fps)
设置视频帧捕获率。
void
setLocation(float latitude, float longitude)
设置并存储在输出文件中的地理数据(经度和纬度)。
void
setMaxDuration(int max_duration_ms)
设置录制会话的最长持续时间(以ms为单位)。
void
setMaxFileSize(long max_filesize_bytes)
设置录制文件的最大文件大小。
void
setOnErrorListener(MediaRecorder.OnErrorListener l)
注册一个用于记录录制时出现的错误的监听器。
void
setOnInfoListener(MediaRecorder.OnInfoListener listener)
注册一个用于记录录制时出现的信息事件。
void
setOrientationHint(int degrees)
设置输出的视频播放的方向提示。
void
setOutputFile(FileDescriptor fd)
设置录制的音频文件的保存位置。
void
setOutputFile(String path)
设置录制的音频文件的保存位置。
void
setOutputFormat(int output_format)
设置所录制的音视频文件的格式。
void
setPreviewDisplay(Surface sv)
设置使用哪个SurfaceV