用WebRTC打造一个Animoji + Facetime 的视频聊天应用

1, Animoji

Animoji是在iPhone X上的动画表情。是iPhone在十周年特别版iPhone X发布的新功能。其使用面部识别传感器来检测用户面部表情变化, 并最终生成可爱的3D动画表情符号, 目前只能在iMessage中使用. 但有人破解了Animoji, 并提取相应的头文件供大家在产品中使用.


2, Factime

FaceTime 是苹果公司iOS和Mac OS X内置的一款视频通话软件,通过Wi-Fi或者蜂窝数据接入互联网,在两个装有FaceTime 的设备之间实现视频通话. 用通俗的话讲就是视频电话.


之前在试用Animoji的时候觉得很神奇, 在想如果和实时的视频聊天配合起来应该很有意思, 大概花了半天的时间, 写出了这个小玩具.


首先Animoji:

在网上找到有人封装好的Animoji 头文件 github.com/efremidze/A…, 研究了之后发现并没有可以获得Animoji 一帧的接口, 我继续把这个库完善了一下, 暴漏出了可以获得每一帧数据的接口. 我fork 了一份代码在这里 github.com/notedit/Ani…, 修改之后的代码也已经PR到原来的项目中. 


帧数据处理:

后面在做视频传输的时候需要CVPixelBuffer, 而我们这里从Animoji里只能获得CIImage, 另外我们需要对取得的数据做一次缩放处理, 避免图片过大. 这里主要使用了CoreImage 和 CVPixelBuffer的一些处理, 直接上代码:

-(CVPixelBufferRef)processCIImage:(CIImage*)image {    @autoreleasepool  {        [filter setValue:image forKey:kCIInputImageKey];        CIImage *outimage = [filter outputImage];NSLog(@"outimage widthxheight %dx%d", (int)outimage.extent.size.width,(int)outimage.extent.size.height);        CVPixelBufferRef outPixelBuffer = NULL;        CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,(int)outimage.extent.size.width,(int)outimage.extent.size.height,kCVPixelFormatType_420YpCbCr8BiPlanarFullRange ,(__bridge CFDictionaryRef) @{(__bridge NSString *) kCVPixelBufferIOSurfacePropertiesKey: @{}},&outPixelBuffer);if (status != 0) {            NSLog(@"CVPixelBufferCreate error %d", (int)status);            CFRelease(outPixelBuffer);            return nil;        }        [ciContext render:outimage toCVPixelBuffer:outPixelBuffer bounds:outimage.extent colorSpace:nil];        return outPixelBuffer;    }
}复制代码

到这里你已经可以很happy的拿到Animoji的帧数据了.


视频通话:

为了快速完成这一部分我直接使用了我们的音视频通话SDK — dotEngine , 支持自定义的YUV 数据输入, 然后我们就可以很愉快的把上一步拿到的数据喂给这个SDK.

大概的流程如下 

dotEngine = DotEngine.sharedInstance(with:self)
localStream = DotStream(audio: true, video: true, videoProfile: DotEngineVideoProfile.DotEngine_VideoProfile_360P, delegate: self)videoCapturer = DotVideoCapturer()localStream.videoCaptuer = videoCapturer// some other codelet image = self.animoji.snapshot(with:self.animoji.frame.size)let ciimage = CIImage(image: image!)let pixelBuffer = self.convert.processCIImage(ciimage)
if pixelBuffer != nil {     self.videoCapturer?.send(pixelBuffer!.takeUnretainedValue(), rotation: VideoRotation.roation_0)      pixelBuffer?.release()
}复制代码

运行效果如下图:




完整的代码在 github.com/dotEngine/a…

我们的音视频通讯SDK dotEngine github.com/dotEngine



转载于:https://juejin.im/post/5aaa086d6fb9a028b77a887c


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部