• 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编码后的码流。

  • 相关阅读:
    tabhost切换标签:Log中出现You must supply a layout_width attribute的解决方法
    listview去掉底部多出的边框黑色
    使用fragmenttabhost后,子fragment怎么获取ID?怎么用getSharedPreferences
    android用shape给linearLayout设置边框,怎样只保留底部或顶部的边框,把其它三个方向的边框去掉呢?
    linux删除文件未释放空间问题处理
    mount: unknown filesystem type 'LVM2_member'解决方案【转】
    centos系统lvm的安装
    一个或多个音频服务未运行 win7 错误1079:此服务的账户不同于运行于同一进程上的其他服务账户
    php SimpleXML
    new JSONObject(str)无法解析 报错:org.json.JSONException: Value of type java.lang.String cannot be converted to JSONObject
  • 原文地址:https://www.cnblogs.com/changewu/p/3419772.html
Copyright © 2020-2023  润新知