android流媒体初探索(一)----获取视频数据

最近在做一个项目,简单说一下需求吧:

android手机做前端视频采集入口,能捕获实时的视频流并传到服务器并且分发到pc客户端实时的进行视频的观看。

就这个看似简单的需求,由于我之前对流媒体全无了解,也因为接入了XX平台进行数据中转,导致开发过程一再受阻。

但就目前已基本将该项目流程走通,所以必须在这里来作个小结。

在这里有几个关键点:

a、视频数据如何获取。

b、获取到的数据如何重新编码,以何种形式编码。

c、以什么协议进行传输。

d、视频最后的解码播放。

android充当摄像头,进行流媒体传输的开源项目有spydroid。这个项目是研究android流媒体处理目前来说最好的切入点。网上也有很多对该项目源码解析的文章,这里不再多说。我就上面提到的几个关键点简单说一下做法。

a获取视频数据

用android来实现还算是简单。毕竟有丰富的sdk封装。那么就会用到MediaRecorder。跟它相关的几个类还有Camera、SurfaceHolder。

MediaRecorder用于录像,相关设置如下:

 

if (mMediaRecorder == null) {
mMediaRecorder
= new MediaRecorder(); } else { mMediaRecorder.reset(); } camera = getCamera();
 

      camera.startPreview();
      camera.unlock();


    mMediaRecorder.setCamera(camera);

mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
<!--以上和以下顺序不能颠倒,否则出错>
mMediaRecorder.setVideoSize(reX, reY);
mMediaRecorder.setVideoFrameRate(fr);
mMediaRecorder.setMaxDuration(0);
mMediaRecorder.setMaxFileSize(Integer.MAX_VALUE);
mMediaRecorder.setVideoEncodingBitRate(bit * 1000);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());
mMediaRecorder.setOrientationHint(90);//竖屏播放,但貌似只有在android手机上播放有效,在pc上播放无效。
mMediaRecorder.setOutputFile(sender.getFileDescriptor());//设置输出为本地socket

然后就是Camera的获取和设置:

 1 public Camera getCamera(){
 2         if(camera==null){
 3             try{
 4                 camera = Camera.open();
 5                 Parameters paramters = camera.getParameters();
 6                 paramters.setPreviewSize(Integer.parseInt(getPreferences().resolution.split("×")[0]),Integer.parseInt(getPreferences().resolutio           n.split("×")[1]));
 7             }catch(Exception e){
 8                 e.printStackTrace();
 9                 try {
10                     if(camera!=null){
11                         camera.reconnect();
12                     }else{
13                         Toast.makeText(this, "连接摄像头服务失败!请重启手机后再试。", Toast.LENGTH_SHORT).show();
14                     }
15                 } catch (IOException e1) {
16                     e1.printStackTrace();
17                 }
18             }
19             if (camera!=null) {
20                 camera.setDisplayOrientation(90);
           camera.setPreviewDisplay(mSurfaceHolder);
21 } 22 } 23 return camera; 24 }

负责预览的SurfaceView和SurfaceHolder:

    /**
     * 初始化surfaceView
     */
    private void InitSurfaceView() {
        mSurfaceView = (SurfaceView) this.findViewById(R.id.surface_camera);
        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.setKeepScreenOn(true);
        mSurfaceHolder.addCallback(this);
        mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//兼容低版本
    }

打开录像:

try {
            mMediaRecorder.prepare();
            mMediaRecorder.start();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
            releaseMediaRecorder();
        }

到这里,已经可以在本地socket中拿到摄像头获取的流了。当然根据我的参数设置,获得的流是系统MP4、h264编码后的码流。

 

 

 

 

posted @ 2013-11-12 16:29  小change  阅读(6130)  评论(0编辑  收藏  举报