找回密码
 立即注册
查看: 446|回复: 0

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

[复制链接]
发表于 2022-2-26 10:02 | 显示全部楼层 |阅读模式
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);

}
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2025-6-6 02:55 , Processed in 0.188120 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表