关于拓幻的SDK基本使用: 拓幻美颜对接进腾讯云直播过程以及问题
新项目中有一个美颜设置界面, 可提前设置视频时的美颜效果,主要是预览+美颜, 所以找了下, 使用GPUImage图像处理框架来对接拓幻SDK。
一个简单的效果:
想要图像预览, 那就要有一个图像视频流。
在GPUImage框架中, GPUImageVideoCamera
作为GPUImageOutput
的子类,会把图像作为纹理, 传给OpenGL ES处理,然后把纹理往下传递, 所以我们需要创建一个GPUImageVideoCamera
的对象:
@property (nonatomic, strong) GPUImageVideoCamera *videoCamera;
- (GPUImageVideoCamera *)videoCamera {
if (!_videoCamera) {
_videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset1280x720 cameraPosition:AVCaptureDevicePositionFront];
_videoCamera.frameRate = 30; // 调整帧率
_videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait;
_videoCamera.horizontallyMirrorFrontFacingCamera = true;
_videoCamera.horizontallyMirrorRearFacingCamera = false;
[_videoCamera addAudioInputsAndOutputs];
_videoCamera.delegate = self;
[_videoCamera addTarget:self.previewView];
}
return _videoCamera;
}
视频流有了, 还需要一个视图来进行渲染,GPUImageView
一个用作GPUImage 输出的端点的UIView子类, 所以我们再来创建一个GPUImageView
的对象:
@property (nonatomic, strong) GPUImageView *previewView;
- (GPUImageView *)previewView {
if (!_previewView) {
_previewView = [[GPUImageView alloc] initWithFrame:self.view.frame];
_previewView.fillMode = kGPUImageFillModePreserveAspectRatioAndFill;
}
return _previewView;
}
准备就绪后, 初始化TiSDK
,将美颜UI 添加到self. previewView
上加载,并设置代理, 开始相机拍摄:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
// 美颜设置
[TiSDK init:kTuoHuanKey CallBack:^(InitStatus callBack) {
}];
[[TiUIManager shareManager] loadToView:self.previewView forDelegate:self];
[self setUI];
[self.videoCamera startCameraCapture];
}
GPUImageVideoCamera
有个代理GPUImageVideoCameraDelegate
,其实就是一个摄像头采集协议,实现协议方法-(void)willOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
这个方法用于对帧动画的手动处理, 它会在捕获每一帧画面的时候被调用,此时就可以对画面进行一些处理, 那对上我们的需求, 就可以使用TiSDK对每一帧进行纹理渲染:
-(void)willOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer {
// CoreMedia.framework: CMSampleBufferGetImageBuffer
CVPixelBufferRef pixelBuffer = (CVPixelBufferRef)CMSampleBufferGetImageBuffer(sampleBuffer);
BOOL isMirror = (self.videoCamera.cameraPosition == AVCaptureDevicePositionFront);
CVPixelBufferLockBaseAddress(pixelBuffer, 0);
unsigned char *baseAddress = (unsigned char *)CVPixelBufferGetBaseAddressOfPlane(pixelBuffer, 0);
UIDeviceOrientation orientation = [UIDevice currentDevice].orientation;
TiRotationEnum rotation;
switch (orientation) {
case UIDeviceOrientationPortrait:
rotation = CLOCKWISE_90;
break;
case UIDeviceOrientationLandscapeLeft:
rotation = isMirror ? CLOCKWISE_180 : CLOCKWISE_0;
break;
case UIDeviceOrientationLandscapeRight:
rotation = isMirror ? CLOCKWISE_0 : CLOCKWISE_180;
break;
case UIDeviceOrientationPortraitUpsideDown:
rotation = CLOCKWISE_270;
break;
default:
rotation = CLOCKWISE_90;
break;
}
// 视频帧格式
TiImageFormatEnum format;
switch (CVPixelBufferGetPixelFormatType(pixelBuffer)) {
case kCVPixelFormatType_32BGRA:
format = BGRA;
break;
case kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange:
format = NV12;
break;
case kCVPixelFormatType_420YpCbCr8BiPlanarFullRange:
format = NV12;
break;
default:
NSLog(@"错误的视频帧格式!");
format = BGRA;
break;
}
int imageWidth, imageHeight;
if (format == BGRA) {
imageWidth = (int)CVPixelBufferGetBytesPerRow(pixelBuffer) / 4;
imageHeight = (int)CVPixelBufferGetHeight(pixelBuffer);
} else {
imageWidth = (int)CVPixelBufferGetWidthOfPlane(pixelBuffer , 0);
imageHeight = (int)CVPixelBufferGetHeightOfPlane(pixelBuffer , 0);
}
//todo --- tillusory start ---
[[TiSDKManager shareManager] renderPixels:baseAddress Format:format Width:imageWidth Height:imageHeight Rotation:rotation Mirror:isMirror];
//todo --- tillusory end ---
// self.outputImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
self.outputImagePixelBuffer = pixelBuffer;
CVPixelBufferUnlockBaseAddress(pixelBuffer, 0);
}
@property(nonatomic, assign) CVPixelBufferRef outputImagePixelBuffer;
在iOS里,我们经常能看到 CVPixelBufferRef 这个类型,在Camera 采集返回的数据里得到一个CMSampleBufferRef,而每个CMSampleBufferRef里则包含一个 CVPixelBufferRef,在视频硬解码的返回数据里也是一个 CVPixelBufferRef。
顾名思义,CVPixelBufferRef 是一种像素图片类型,由于CV开头,所以它是属于 CoreVideo 模块的。
CVPixelBufferRef里包含很多图片相关属性,比较重要的有 width,height,PixelFormatType等。
到这里,预览+拓幻美颜的功能基本就实现了, 当设置了不同的美颜, 就会实时进行纹理渲染。
由于拓幻SDK有缓存, 即每次设置之后都会做缓存,下次使用时会自动读取缓存, 所以我们设置完成后,在视频时就可以直接使用设置好的美颜参数。
GPUImageVideoCamera
的几个常用方法:
切换摄像头:[self.videoCamera rotateCamera];
开始视频采集:[self.videoCamera startCameraCapture];
停止视频采集:[self.videoCamera stopCameraCapture];
以上, 结束。
如果对你有帮助, 就给一个赞吧~