This project uses Android lastest MediaCodec API for video/audio encoding and popular C ibrary librtmp (source code included) for rtmp streaming, in addionion, provides ability to implement real-time effect filters after camera capturing phase and before encoding phase. Some features are:
@Override
public void onCreate(final Bundle savedInstanceState) {
... ...
RESConfig resConfig = RESConfig.obtain();
resConfig.setRtmpAddr("rtmp://***");
resConfig.setFilterMode(RESConfig.FilterMode.HARD);
resConfig.setTargetVideoSize(new Size(720, 480));
resConfig.setBitRate(1000 * 1024);
resConfig.setVideoFPS(30);
resConfig.setVideoGOP(1);
resConfig.setRenderingMode(RESConfig.RenderingMode.OpenGLES);//setrender mode in softmode
resConfig.setDefaultCamera(Camera.CameraInfo.CAMERA_FACING_FRONT);
if (!resClient.prepare(resConfig)) {
Log.e("Main", "prepare,failed!!");
finish();
}
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
resClient.startPreview(surface, width, height);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
resClient.updatePreview(width, height);
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
resClient.stopPreview();
return false;
}
@Override
protected void onStart() {
super.onResume();
resClient.startStreaming();
}
@Override
protected void onStop() {
super.onPause();
resClient.stopStreaming();
}
@Override
protected void onDestroy() {
super.onDestroy();
resClient.destroy();
}
int frontDirection, backDirection;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_FRONT, cameraInfo);
frontDirection = cameraInfo.orientation;
Camera.getCameraInfo(Camera.CameraInfo.CAMERA_FACING_BACK, cameraInfo);
backDirection = cameraInfo.orientation;
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
resConfig.setFrontCameraDirectionMode((frontDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_270 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_90) | RESConfig.DirectionMode.FLAG_DIRECTION_FLIP_HORIZONTAL);
resConfig.setBackCameraDirectionMode((backDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_90 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_270));
} else {
resConfig.setBackCameraDirectionMode((backDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_0 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_180));
resConfig.setFrontCameraDirectionMode((frontDirection == 90 ? RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_180 : RESConfig.DirectionMode.FLAG_DIRECTION_ROATATION_0) | RESConfig.DirectionMode.FLAG_DIRECTION_FLIP_HORIZONTAL);
}
BlackWhiteSoftFilter bwsFilter = new BlackWhiteSoftFilter();
resClient.setSoftVideoFilter(bwsFilter);
BaseSoftVideoFilter filter = resClient.acquireSoftVideoFilter();
if (filter != null) {
if (filter instanceof BlackWhiteFilterSoft) {
BlackWhiteFilterSoft bwsFilter = (BlackWhiteFilterSoft) filter;
blackWhiteFilter.setGap((byte) 128); // 0 ~ 255
}
... ...
resClient.releaseSoftVideoFilter();
支持两种滤镜模式:使用cpu的软模式和使用gpu(opengles)的硬模式,硬模式效率通常高于软模式。
软模式下:
硬模式下: