视频直播之开篇
现在各大网络的直播平台可是不少,但是大家知道视频直播是怎么做的吗?不懂的人可能认为应该和视频录制差不多。但是做android上面实现还是有很大的差别的。
在android上录制本地视频可以用MediaRecord传入相关参数,写入录制的地址,基本就ok了。但是对于视频直播就难一些,首先需要取到视频的数据,再经过硬件的编码,最后再上传。下面看看简单的实现步骤:
1.首先要进行视频的预览,一般预览有三个控件:surfaceview
,GLSurfaceView
,TextureView
,这三个虽然使用方式上所有差别,但是最终都是要从surface上取数据的。由于android版本对camera部分的改版,在android21之前使用android.hardware.Camera
,之后又加了android.hardware.camera2
,实现起来有多种组合:
a.Camera+Surface
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:
<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。