在 Android 中使用 WebRTC 自定义视频源格式可以通过实现 VideoCapturer
接口来实现。以下是一个示例代码:
首先,创建一个实现 VideoCapturer
接口的自定义视频源类,例如 CustomVideoCapturer
:
import android.content.Context;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.SystemClock;
import org.webrtc.CameraEnumerationAndroid;
import org.webrtc.Logging;
import org.webrtc.SurfaceTextureHelper;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoFrame;
import org.webrtc.VideoFrame.Buffer;
import org.webrtc.VideoSink;
import java.nio.ByteBuffer;
public class CustomVideoCapturer implements VideoCapturer {
private static final String TAG = "CustomVideoCapturer";
private static final int FRAME_RATE = 30;
private static final int IMAGE_WIDTH = 640;
private static final int IMAGE_HEIGHT = 480;
private SurfaceTextureHelper surfaceTextureHelper;
private VideoSink videoSink;
private Camera camera;
private int cameraId;
private boolean running;
private boolean capturingFrames;
public CustomVideoCapturer(Context context, VideoSink videoSink) {
this.videoSink = videoSink;
this.cameraId = CameraEnumerationAndroid.getDeviceIndex(CameraEnumerationAndroid.getNameOfFrontFacingDevice());
}
@Override
public void initialize(SurfaceTextureHelper surfaceTextureHelper, Context context, CapturerObserver capturerObserver) {
this.surfaceTextureHelper = surfaceTextureHelper;
}
@Override
public void startCapture(int width, int height, int framerate) {
if (running) return;
running = true;
camera = Camera.open(cameraId);
Camera.Parameters parameters = camera.getParameters();
parameters.setPreviewSize(IMAGE_WIDTH, IMAGE_HEIGHT);
parameters.setPreviewFormat(ImageFormat.NV21);
camera.setParameters(parameters);
camera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if (capturingFrames) {
Buffer buffer = new VideoFrame.Buffer(data, IMAGE_WIDTH, IMAGE_HEIGHT, ImageFormat.NV21);
VideoFrame frame = new VideoFrame(buffer, 0, SystemClock.elapsedRealtimeNanos());
videoSink.onFrame(frame);
frame.release();
}
camera.addCallbackBuffer(data);
}
});
int bufferSize = IMAGE_WIDTH * IMAGE_HEIGHT * ImageFormat.getBitsPerPixel(ImageFormat.NV21) / 8;
byte[] buffer = new byte[bufferSize];
camera.addCallbackBuffer(buffer);
camera.startPreview();
capturingFrames = true;
}
@Override
public void stopCapture() {
if (!running) return;
running = false;
capturingFrames = false;
camera.stopPreview();
camera.setPreviewCallbackWithBuffer(null);
camera.release();
}
@Override
public void changeCaptureFormat(int width, int height, int framerate) {
// Not supported
}
@Override
public void dispose() {
stopCapture();
}
@Override
public boolean isScreencast() {
return false;
}
}
然后,在使用 WebRTC 的地方,使用自定义视频源类来进行视频捕获:
import org.webrtc.EglBase;
import org.webrtc.PeerConnectionFactory;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoCapturer;
import org.webrtc.VideoSink;
import org.webrtc.VideoSource;
public class MainActivity extends AppCompatActivity {
private PeerConnectionFactory factory;
private VideoSource videoSource;
private VideoCapturer videoCapturer;
private SurfaceViewRenderer surfaceViewRenderer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceViewRenderer = findViewById(R.id.surface_view_renderer);
EglBase.Context eglBaseContext = EglBase.create().getEglBaseContext();
surfaceViewRenderer.init(eglBaseContext, null);
factory = new PeerConnectionFactory.Builder().createPeerConnectionFactory();
videoCapturer = new CustomVideoCapturer(this, new VideoSink() {
@Override
public void onFrame(VideoFrame videoFrame) {
// 处理视频帧
surfaceViewRenderer.renderFrame(videoFrame);
}
});
videoSource = factory.createVideoSource(videoCapturer.isScreencast());
videoCapturer.initialize(null, this, videoSource.getCapturerObserver());
videoCapturer.startCapture(640, 480, 30);
surfaceViewRenderer.setMirror(true);
videoSource.adaptOutputFormat(640, 480, 30);
videoSource.add