近两年一直从事视频行业的开发, 加班也比较严重, 好久没有写文章了, 最近稍微有些时间, 前来写点文章, 记录一些开发中遇到的问题, 和解决方法!
做视频会议项目, 当然是离不开音视频啦, 也常常和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语言入门8-数组-基本算法

    一.          什么是数组 数组就是具有相同数据类型的有序集合. 分为一维数组.二维数组及多维数组. 一维数组就是用一个下标定义的数组 二维数组就是用二个下标定义的数组 我们把具有三个下标及三 ...

  2. Java、Java SE、Java Web和Java EE的区别

    刚接触Java对这些概念上的东西有点模糊,查了很多资料,想把它分享出来,要是哪里不对请大家指正(^_^) 1.Java 毫无疑问这就是门语言和C.C++.C#一样没什么好说的. 2.Java SE和J ...

  3. Spring 整合 ibatis

    是的,真的是那个不好用的ibatis,不是好用的mybatis. 由于工作需要用到ibatis需要自己搭建环境,遇到了不少的坑,做一下记录. 一.环境配置 Maven JDK1.6 (非常重要,使用S ...

  4. kubernetes CRD 开发指南

    扩展kubernetes两个最常用最需要掌握的东西:自定义资源CRD 和 adminsion webhook, 本文教你如何十分钟掌握CRD开发. kubernetes允许用户自定义自己的资源对象,就 ...

  5. 0 推荐系统——CB和CF

    一.基于内容的推荐(CB,Content-based Recommendations): 基于内容的推荐CB应该算是最早被使用的推荐方法,它根据用户过去喜欢的产品(本文统称为 item),为用户推荐和 ...

  6. 1. 源码分析---SOFARPC可扩展的机制SPI

    这几天离职在家,正好没事可以疯狂的输出一下,本来想写DUBBO的源码解析的,但是发现写DUBBO源码的太多了,所以找一个写的不那么多的框架,所以就选中SOFARPC这个框架了. SOFARPC是蚂蚁金 ...

  7. 不用 Spring Security 可否?试试这个小而美的安全框架

    写在前面 在一款应用的整个生命周期,我们都会谈及该应用的数据安全问题.用户的合法性与数据的可见性是数据安全中非常重要的一部分.但是,一方面,不同的应用对于数据的合法性和可见性要求的维度与粒度都有所区别 ...

  8. 【Java例题】2.5 温度转换

    5.输入华氏温度, 用下列公式将其转换为摄氏温度并输出. C=5/9(F-32). package study; import java.util.Scanner; public class demo ...

  9. Linux下Docker以及portainer相关配置

    一.安装使用Docer CE 本文以CentOS 7为例,安装docker CE版本,docker有两种版本,社区版本CE和企业版本EE,此处学习研究以CE版本为例, 两种安装方式可选:1.使用yum ...

  10. 数据结构之二叉树的构建C++版

    二叉树的构建要注意与链式表的区别,二叉树这里的构建十分低级,每个树只是构建了一个单一的二叉树节点,总体来看是有下向上构建的.用户需要手动去构建自己需要的树,而不是直接去插入数据就到二叉树中了,因为不是 ...