iOS 视图渲染数据转CVPixelBuffer
近两年一直从事视频行业的开发, 加班也比较严重, 好久没有写文章了, 最近稍微有些时间, 前来写点文章, 记录一些开发中遇到的问题, 和解决方法!
做视频会议项目, 当然是离不开音视频啦, 也常常和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的更多相关文章
- iOS 视图,动画渲染机制探究
腾讯Bugly特约作者:陈向文 终端的开发,首当其冲的就是视图.动画的渲染,切换等等.用户使用 App 时最直接的体验就是这个界面好不好看,动画炫不炫,滑动流不流畅.UI就是 App 的门面,它的体验 ...
- iOS 图像渲染原理
http://chuquan.me/2018/09/25/ios-graphics-render-principle/ 通过 图形渲染原理 一文,大致能够了解图形渲染过程中硬件相关的原理.本文将进一步 ...
- iOS开发系列--数据存取
概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储到数据库.例如前面IOS开发系列-Objective-C之Foundation框架的文章中提到归档.plist文件存储, ...
- Rails :布局和视图渲染
原文地址: http://guides.ruby-china.org/layouts_and_rendering.html Rails 布局和视图渲染 本文介绍 Action Controller 和 ...
- iOS 视图控制器转场详解
iOS 视图控制器转场详解 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标有了大幅度的增长,多谢唐巧前辈的推荐.有些人问我相关的问题 ...
- Laravel 5 多个视图共享数据的方法
我们都知道模板一般会用到继承,导航栏就是一个很好的例子,但是导航栏的数据如何共享,比如有个导航的文件叫在view/navigation.blade.php 为了简单一点,文件里只有设置了一个变量 {{ ...
- SpringMVC核心——视图渲染(包含视图解析)问题
一.本来想说的是返回值处理问题,但在 SpringMVC 中,返回值处理问题的核心就是视图渲染.所以这里标题叫视图渲染问题. 本来想在上一篇文章中对视图解析进行说明的,但是通过源码发现,它应该算到视图 ...
- 【转】iOS开发系列--数据存取
原文: http://www.cnblogs.com/kenshincui/p/4077833.html#SQLite 概览 在iOS开发中数据存储的方式可以归纳为两类:一类是存储为文件,另一类是存储 ...
- 微信小程序教学第四章第二节(含视频):小程序中级实战教程:详情-视图渲染
§ 详情 - 数据渲染 本文配套视频地址: https://v.qq.com/x/page/x055550lrvd.html 开始前请把 ch4-2 分支中的 code/ 目录导入微信开发工具 这一节 ...
随机推荐
- java:选择排序法对数组排序
最近想练一练Java的算法,然后碰到LeetCode上一道从排序数组删除重复项的小题,刚开始没看到是从排序数组中,就乱写,其实要是排序树组,就比乱序的感觉上好写多了.然后就想回顾下冒泡法对数组排序,凭 ...
- 深入了解数据校验:Java Bean Validation 2.0(JSR380)
每篇一句 吾皇一日不退役,尔等都是臣子 相关阅读 [小家Java]深入了解数据校验(Bean Validation):基础类打点(ValidationProvider.ConstraintDescri ...
- Linux中的update和upgrade的作用
update 是同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包.update是下载源里面的metad ...
- MicroPython TPYBoard v201 简易家庭气象站的实现过程
转载请注明文章来源,更多教程可自助参考docs.tpyboard.com,QQ技术交流群:157816561,公众号:MicroPython玩家汇 前言 上一篇教程中我们实现了一个简单网页的显示.本篇 ...
- 1.4.1python下载网页(每天一更)
# -*- coding: utf-8 -*- ''' Created on 2019年4月27日 @author: lenovo ''' # import urllib3 # def downloa ...
- 10分钟了解分布式CAP、BASE理论
CAP理论 2000年7月,Eric Brewer教授提出CAP猜想:2年后,Seth Gilbert和Nancy Lynch从理论上证明了CAP:之后,CAP理论正式成为分布式计算领域的公认定理. ...
- 【JDK】JDK源码分析-AbstractQueuedSynchronizer(1)
概述 前文「JDK源码分析-Lock&Condition」简要分析了 Lock 接口,它在 JDK 中的实现类主要是 ReentrantLock (可译为“重入锁”).ReentrantLoc ...
- PythonDay05
第五章 今日内容 字典 字典 语法:{'key1':1,'key2':2} 注意:dict保存的数据不是按照我们添加进去的顺序保存的. 是按照hash表的顺序保存的. ⽽hash表 不是连续的. 所以 ...
- 直方图均衡基本原理及Python实现
1. 基本原理 通过一个变换,将输入图像的灰度级转换为`均匀分布`,变换后的灰度级的概率密度函数为 $$P_s(s) = \frac{1}{L-1}$$ 直方图均衡的变换为 $$s = T(r) = ...
- java并发编程(二十)----(JUC集合)CopyOnWriteArrayList介绍
这一节开始我们正式来介绍JUC集合类.我们按照List.Set.Map.Queue的顺序来进行介绍.这一节我们来看一下CopyOnWriteArrayList. CopyOnWriteArrayLis ...