如今各大網絡的直播平臺但是很多,可是你們知道視頻直播是怎麼作的嗎?不懂的人可能認爲應該和視頻錄製差很少。可是作android上面實現仍是有很大的差異的。java
在android上錄製本地視頻能夠用MediaRecord傳入相關參數,寫入錄製的地址,基本就ok了。可是對於視頻直播就難一些,首先須要取到視頻的數據,再通過硬件的編碼,最後再上傳。下面看看簡單的實現步驟:android
1.首先要進行視頻的預覽,通常預覽有三個控件:surfaceview
,GLSurfaceView
,TextureView
,這三個雖然使用方式上全部差異,可是最終都是要從surface上取數據的。因爲android版本對camera部分的改版,在android21以前使用android.hardware.Camera
,以後又加了android.hardware.camera2
,實現起來有多種組合:網絡
a.Camera+Surfaceapp
package com.example.amei.cameraexample; import android.Manifest; import android.content.pm.PackageManager; import android.graphics.ImageFormat; import android.hardware.Camera; import android.hardware.Camera.Size; import android.os.Build; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import java.io.IOException; import java.util.List; public class camera_surface_Activity extends AppCompatActivity { private static final String TAG = "camera_surface_Activity"; private SurfaceView mSurfaceView = null; private Camera mCamera = null; private Camera.Parameters mParameters = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); checkPermission(); setContentView(R.layout.activity_camera_surface); mSurfaceView = (SurfaceView)findViewById(R.id.surface_id); SurfaceHolder surfaceHolder = mSurfaceView.getHolder(); surfaceHolder.addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder surfaceHolder) { Log.i(TAG,"surfaceCreated"); openCamera(); try { mCamera.setPreviewDisplay(surfaceHolder); } catch (IOException e) { e.printStackTrace(); } mCamera.startPreview(); } @Override public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { Log.i(TAG,"surfaceChanged"); } @Override public void surfaceDestroyed(SurfaceHolder surfaceHolder) { Log.i(TAG,"surfaceDestroyed"); if(mCamera != null) { mCamera.release(); mCamera = null; } } }); } private void openCamera() { if(mCamera == null){ mCamera = android.hardware.Camera.open(0); mParameters = mCamera.getParameters(); List<Camera.Size> list = mParameters.getSupportedPreviewSizes(); mParameters.setPreviewFormat(ImageFormat.NV21); int PreviewWidth = list.get(0).width; int PreviewHeight = list.get(0).height; Log.i(TAG,"PreviewWidth = "+PreviewWidth+" PreviewHeight = "+PreviewHeight); mParameters.setPreviewSize(PreviewWidth, PreviewHeight); // 設置預覽圖片大小 mCamera.setParameters(mParameters); } } private void checkPermission() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { String[] permissions = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}; for (String permission : permissions) { if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, permissions, 200); return; } } } } }
layout裏面只有一個surface:ide
<SurfaceView android:id="@+id/surface_id" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" />
首先是獲取相應的surfaceview,而且設置callback,只有在surface準備完成以後才能進行預覽,因此當surface建立成功以後纔去打開camera。ui