Android视频直播 ------ 1、数据采集之摄像头

1、直播流程整体流程 

1.1 数据采集(通常是摄像头和录屏)

1.2 编码,也叫视频压缩(采用H264 编解码协议,格式AVC),H265压缩比例更高,自行选择,使用的MediaCodec,Android原生api

1.3 传输,使用的是Netty网络通讯协议,基于socket封装的非常好网络框架,数据传输序列化用的protobuf(主要用与Android和ios跨平台传输byte[]数据,如果不涉及跨平台,使用Netty即可)

1.4 解码 网络传递过来的byte数据流,解析出视频数据流,由MediaCodec解码

1.5 渲染显示,自定义suface,交给MediaCodec渲染即可


2、首选,我们来看第一步,数据采集

2.1 启动相机,此处使用的是camera1,camera2难使用,资料少,不会的还是建议用camera1

private void startCamera(int type) {

    releaseCamera();

if (mTextureView.getSurfaceTexture() ==null){

        return;

}

cameraType = type;

try {

    mCamera =Camera.open(type);

    mCamera.setPreviewCallback(this);

    mCamera.setDisplayOrientation(90);

    Camera.Parameters parameters =mCamera.getParameters();

    parameters.setPreviewFormat(ImageFormat.NV21);

    if (cameraType ==CAMERA_FACING_BACK){

        LogUtils.i("fangzhi","CAMERA_FACING_BACK FOCUS_MODE_CONTINUOUS_VIDEO");

        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);

    }

if (size ==null) {

        size =CameraManager.getOptimalSize(parameters.getSupportedPreviewSizes(),mWidth,mHeight);

        float diff = (float)size.height /size.width - (float)ScreenUtils.getScreenWidth()         /ScreenUtils.getScreenHeight();

        if (diff >=0.05 &&Build.VERSION.SDK_INT

                mWidth =640;

                mHeight =360;

                  size =CameraManager.getOptimalSize(parameters.getSupportedPreviewSizes(),mWidth,mHeight);

        LogUtils.i("fangzhi","低端机相机尺寸二次适配");

        }

                mWidth =size.width;

                mHeight =size.height;

        }

      LogUtils.e("fangzhi","mWH : " +mWidth +" : " +mHeight);

        parameters.setPreviewSize(mWidth,mHeight);

        mCamera.setParameters(parameters);

        mCamera.setPreviewTexture(mTextureView.getSurfaceTexture());

        mCamera.startPreview();

        }catch (Exception e) {

        e.printStackTrace();

        LogUtils.e("fangzhi","err : " + e.getMessage());

    }

}

2.2  实现Camera.PreviewCallback 接口,重写onPreviewFrame()方法

@Override

public void onPreviewFrame(byte[] data,Camera camera) {

        if (avcEncoder ==null) {

            / /Log.e("fangzhi", "avcEncoder  == null " + data.length);

            return;

        }

        if (avcEncoder.nv21Queue.size() >=10) {

            avcEncoder.nv21Queue.poll();

        }

        avcEncoder.nv21Queue.add(data);

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容