Android視頻直播 ------ 1、數(shù)據(jù)采集之?dāng)z像頭

1、直播流程整體流程?

1.1 數(shù)據(jù)采集(通常是攝像頭和錄屏)

1.2 編碼,也叫視頻壓縮(采用H264?編解碼協(xié)議,格式AVC),H265壓縮比例更高,自行選擇,使用的MediaCodec,Android原生api

1.3 傳輸,使用的是Netty網(wǎng)絡(luò)通訊協(xié)議,基于socket封裝的非常好網(wǎng)絡(luò)框架,數(shù)據(jù)傳輸序列化用的protobuf(主要用與Android和ios跨平臺傳輸byte[]數(shù)據(jù),如果不涉及跨平臺,使用Netty即可)

1.4 解碼 網(wǎng)絡(luò)傳遞過來的byte數(shù)據(jù)流,解析出視頻數(shù)據(jù)流,由MediaCodec解碼

1.5 渲染顯示,自定義suface,交給MediaCodec渲染即可


2、首選,我們來看第一步,數(shù)據(jù)采集

2.1 啟動(dòng)相機(jī),此處使用的是camera1,camera2難使用,資料少,不會(huì)的還是建議用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","低端機(jī)相機(jī)尺寸二次適配");

????????}

????????????????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? 實(shí)現(xiàn)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);

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容