近两年一直从事视频行业的开发, 加班也比较严重, 好久没有写文章了, 最近稍微有些时间, 前来写点文章, 记录一些开发中遇到的问题, 和解决方法!
做视频会议项目, 当然是离不开音视频啦, 也常常和WebRTC打交道, 包括编译WebRTC, 修改源码, 还有C++和OC的混编开发, JS交互, 也尝试过RN的开发来避开一些问题等等, 东西很多, 路也很不好走, 通宵加班也是家常便饭, 不过现在项目基本稳定,已经上线, 用户反馈也都很不错! 回头看看走过的路, 虽然坎坎坷坷, 但是也是收获满满呀!
进入正题, 项目中有共享的功能, 屏幕共享使用的ReplayKit, 但是应用外的屏幕共享时是使用的Broadcast Extension, 而该扩展是另外的独立进程, 涉及到宿主App和扩展App的信令之间的交互, 好在有比较有好的第三方使用, 省了不少事, 最终完成了屏幕共享! 如果有朋友涉及到这方面的知识的话, 可以一起交流沟通哈!
除屏幕共享外, 我们要有网页共享, 网页共享, 开始一脸懵逼! 后来的解决方案是, 共享人端使用WKWebView, 观看端看的是视频流! OK, 那么问题来了, 如何把一个UIView 的渲染数据采集成为Buffer呢, 头大, 最初考路过使用应用内的录屏, 这样是可以解决, 但是, 录屏的话吧整个屏幕上的内容全都采集出来, 不是很友好, 用户只想共享这个网页, 其他的不想让观看者看到! 确实挺麻烦的, 查了很多资料, 也没有特别合适的!
经过多方面研究和资料的查阅, 最终的解决方案是, 创建CVPixelBufferRef pxbuffer, 然后获取像素基本地址

void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
然后在创建上下文以pxdata 所指向的内存作为上下文数据存贮的容器, 最后 渲染 上下文[self.webView.layer renderInContext:context];
这样就将 webView 视图上的渲染数据转成了一帧 CVPixelBufferRef 数据, 然后根据帧率设置定时器, 去不停的获取webView的渲染数据转换成需要像素缓冲数据!

具体的代码如下

- (CVPixelBufferRef)CVPixelBufferRef {

    CGSize size = self.frame.size;
NSDictionary *options = @{(NSString*)kCVPixelBufferCGImageCompatibilityKey : @YES,
(NSString*)kCVPixelBufferCGBitmapContextCompatibilityKey : @YES,
(NSString*)kCVPixelBufferIOSurfacePropertiesKey: [NSDictionary dictionary]};
CVPixelBufferRef pxbuffer = NULL; CGFloat frameWidth = size.width;
CGFloat frameHeight = size.height; CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault,
frameWidth,
frameHeight,
kCVPixelFormatType_32ARGB,
(__bridge CFDictionaryRef) options,
&pxbuffer); NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL); CVPixelBufferLockBaseAddress(pxbuffer, 0);
void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer);
NSParameterAssert(pxdata != NULL); CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); CGContextRef context = CGBitmapContextCreate(pxdata, size.width, size.height, 8, CVPixelBufferGetBytesPerRow(pxbuffer), rgbColorSpace, kCGImageAlphaPremultipliedFirst); NSParameterAssert(context); CGContextConcatCTM(context, CGAffineTransformMakeRotation(0));
CGAffineTransform flipVertical = CGAffineTransformMake( 1, 0, 0, -1, 0, frameHeight);
CGContextConcatCTM(context, flipVertical); // CGAffineTransform flipHorizontal = CGAffineTransformMake( -1.0, 0.0, 0.0, 1.0, frameWidth, 0.0 );
// CGContextConcatCTM(context, flipHorizontal); [self.webView.layer renderInContext:context]; CGColorSpaceRelease(rgbColorSpace);
CGContextRelease(context);
CVPixelBufferUnlockBaseAddress(pxbuffer, 0); return pxbuffer;
}

这或许不是最好的方法, 但目前确实解决了燃眉之急, 分享出来, 为有同样需求的小伙伴提供一条方案, 或者小伙伴有更好的方法, 分享出来, 大家可以学习交流一下

或者上我的简书

iOS 视图渲染数据转CVPixelBuffer的更多相关文章

  1. iOS 视图,动画渲染机制探究

    腾讯Bugly特约作者:陈向文 终端的开发,首当其冲的就是视图.动画的渲染,切换等等.用户使用 App 时最直接的体验就是这个界面好不好看,动画炫不炫,滑动流不流畅.UI就是 App 的门面,它的体验 ...

  2. iOS 图像渲染原理

    http://chuquan.me/2018/09/25/ios-graphics-render-principle/ 通过 图形渲染原理 一文,大致能够了解图形渲染过程中硬件相关的原理.本文将进一步 ...

  3. iOS开发系列--数据存取

    概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...

  4. Rails :布局和视图渲染

    原文地址: http://guides.ruby-china.org/layouts_and_rendering.html Rails 布局和视图渲染 本文介绍 Action Controller 和 ...

  5. iOS 视图控制器转场详解

    iOS 视图控制器转场详解 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标有了大幅度的增长,多谢唐巧前辈的推荐.有些人问我相关的问题 ...

  6. Laravel 5 多个视图共享数据的方法

    我们都知道模板一般会用到继承,导航栏就是一个很好的例子,但是导航栏的数据如何共享,比如有个导航的文件叫在view/navigation.blade.php 为了简单一点,文件里只有设置了一个变量 {{ ...

  7. SpringMVC核心——视图渲染(包含视图解析)问题

    一.本来想说的是返回值处理问题,但在 SpringMVC 中,返回值处理问题的核心就是视图渲染.所以这里标题叫视图渲染问题. 本来想在上一篇文章中对视图解析进行说明的,但是通过源码发现,它应该算到视图 ...

  8. 【转】iOS开发系列--数据存取

    原文: http://www.cnblogs.com/kenshincui/p/4077833.html#SQLite 概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储 ...

  9. 微信小程序教学第四章第二节(含视频):小程序中级实战教程:详情-视图渲染

    § 详情 - 数据渲染 本文配套视频地址: https://v.qq.com/x/page/x055550lrvd.html 开始前请把 ch4-2 分支中的 code/ 目录导入微信开发工具 这一节 ...

随机推荐

  1. C#3.0新增功能07 查询表达式

    连载目录    [已更新最新开发文章,点击查看详细] 查询是什么及其作用是什么 查询是一组指令,描述要从给定数据源(或源)检索的数据以及返回的数据应具有的形状和组织. 查询与它生成的结果不同. 通常情 ...

  2. 原 docker 安装使用 solr

    1.安装solr 7.5 docker solr 官网:https://hub.docker.com/_/solr/ docker pull solr:7.5.0 2.启动solr服务 docker ...

  3. Java基础之方法

    方法 某段代码经常使用,可以使用大括号将这段代码包括起来,起个名字,以后就使用这个名字来代替这段代码. 定义格式: 修饰符 返回值类型 方法名(参数列表) { 方法体语句:   return语句: } ...

  4. Linux基础文件查找

    一.文件查找 (一).命令文件 [root@linux ~]# chich ls //从PATH环境变量 [root@linux ~]# chereis vim [root@linux ~]# ech ...

  5. oracle 创建表空间,用户并授权

    1. 查看所有表空间及存储路径 select file_name, tablespace_name from dba_data_files; 2. 创建表空间 CREATE TABLESPACE xs ...

  6. 分享我的GD32F450的IAP过程

    最近一个项目使用GD32F450VI+ESP8266需要做远程升级,基本参考正点原子IAP的那一章节,但是在GD32F450上却遇到了问题,无法跳转,然后使用正点原子的开发板stm32f429,以及s ...

  7. 剑指offer-链表

    1. 链表中环的入口节点 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null. 思路一:用哈希表存已经遍历过的节点,O(1)复杂度查找,如果再次遇到就是环入口 # -*- cod ...

  8. React Native-安卓环境的搭建

    最近公司做一个项目,项目中使用React Native(简称RN)来写安卓APP,现在我分享下安卓环境搭建的过程. 我参照https://reactnative.cn/docs/getting-sta ...

  9. p2p 打洞专场(转)

    就像1000个人眼中有1000个哈姆雷特一样,每个人眼中的区块链也是不一样的!作为技术人员眼中的区块链就是将各种技术的融合,包括密码学,p2p网络,分布式共识机制以及博弈论等.我们今天就来讨论一下区块 ...

  10. TCP/UDP对比总结

    目录 1 TCP-UDP对比 2 UDP介绍 3 TCP介绍 3.1 可靠传输的原理和实现 3.1.1 可靠传输原理 3.1.2 可靠传输实现 3.2 TCP面向连接管理 3.2.1 建立连接 3.2 ...