第五十七篇、AVAssetReader和AVAssetWrite 对视频进行编码
AV Foundation提供了直接处理媒体样本的低级功能,其中需要使用的两个重要的类,AVAssetReader和AVAssetWrite,AVAssetReader用于从AVAsset资源读取媒体样本,AVAssetWrite用于对媒体资源进行编码并写入到容器文件中。下面简单的使用一下:
初始化AVAssetReader
-(void)configAssetReader { NSURL *videoUrl = [NSURL fileURLWithPath:[self resoucePath]]; _asset = [AVAsset assetWithURL:videoUrl]; //获取资源的一个视频轨道 AVAssetTrack *track = [[_asset tracksWithMediaType:AVMediaTypeVideo] firstObject]; _assetReader = [[AVAssetReader alloc] initWithAsset:_asset error:nil]; //指定将读取的样本数据压缩为BGRA格式 NSDictionary *setting = @{(id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}; //初始化输出,指定从track轨道中读取样本数据 _assetOutPut = [[AVAssetReaderTrackOutput alloc] initWithTrack:track outputSettings:setting]; //添加输出 [_assetReader addOutput:_assetOutPut]; //开始读取过程 [_assetReader startReading]; }
初始化AVAssetWrite
-(void)configWriteInput { NSString *storePath = nil; NSString *path = [self resoucePath]; NSRange range = [path rangeOfString:@"/" options:NSBackwardsSearch]; if (range.location != NSNotFound) { NSString *pathRoot = [path substringToIndex:range.location]; storePath = [pathRoot stringByAppendingPathComponent:@"copy.mp4"]; } if (storePath) { _assetWrite = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:storePath] fileType:AVFileTypeQuickTimeMovie error:nil]; //指定编码格式,像素宽高等信息 NSDictionary *setting = @{ AVVideoCodecKey:AVVideoCodecH264, AVVideoWidthKey:@, AVVideoHeightKey:@, AVVideoCompressionPropertiesKey:@{ AVVideoMaxKeyFrameIntervalKey:@, AVVideoAverageBitRateKey:@, AVVideoProfileLevelKey:AVVideoProfileLevelH264Main31 } }; 初始化写入器,并制定了媒体格式 _assetInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:setting]; //添加写入器 [_assetWrite addInput:_assetInput]; [_assetWrite startWriting]; } }
将读取的数据写入到_assetInput写入器中
-(void)assertReadToAssetInput { dispatch_queue_t queue = dispatch_queue_create("com.writequeue", DISPATCH_QUEUE_CONCURRENT); if (_assetInput) { __block NSInteger count = ; __block BOOL isComplete = NO; //开启写入会话,并指定样本的开始时间 [_assetWrite startSessionAtSourceTime:kCMTimeZero]; [_assetInput requestMediaDataWhenReadyOnQueue:queue usingBlock:^{ if (!isComplete && _assetInput.readyForMoreMediaData) { //样本数据 CMSampleBufferRef buffer = [_assetOutPut copyNextSampleBuffer]; if (buffer) { [_assetInput appendSampleBuffer:buffer]; count++; // 展示第2000帧数据 if (count == ) { CGImageRef imgref = [UIImage imageFromSampleBufferRef:buffer]; //读取CMSampleBuffer中的数据,将其转化为CGImageRef 参考代码见:http://www.jianshu.com/p/3d5ccbde0de1 UIImage *img = [UIImage imageWithCGImage:imgref]; dispatch_sync(dispatch_get_main_queue(), ^{ _imageView.image = img; }); } } else { isComplete = YES; } if(isComplete) { //关闭写入会话 [_assetWrite finishWritingWithCompletionHandler:^{ AVAssetWriterStatus status = self.assetWrite.status; if (status == AVAssetWriterStatusCompleted) { NSLog(@"finsished"); } else { NSLog(@"failure"); } }]; } } }]; } }
-(void)assertReadToAssetInput { dispatch_queue_t queue = dispatch_queue_create("com.writequeue", DISPATCH_QUEUE_CONCURRENT); if (_assetInput) { __block NSInteger count = ; __block BOOL isComplete = NO; //开启写入会话,并指定样本的开始时间 [_assetWrite startSessionAtSourceTime:kCMTimeZero]; [_assetInput requestMediaDataWhenReadyOnQueue:queue usingBlock:^{ if (!isComplete && _assetInput.readyForMoreMediaData) { //样本数据 CMSampleBufferRef buffer = [_assetOutPut copyNextSampleBuffer]; if (buffer) { [_assetInput appendSampleBuffer:buffer]; count++; // 展示第2000帧数据 if (count == ) { CGImageRef imgref = [UIImage imageFromSampleBufferRef:buffer]; //读取CMSampleBuffer中的数据,将其转化为CGImageRef 参考代码见:http://www.jianshu.com/p/3d5ccbde0de1 UIImage *img = [UIImage imageWithCGImage:imgref]; dispatch_sync(dispatch_get_main_queue(), ^{ _imageView.image = img; }); } } else { isComplete = YES; } if(isComplete) { //关闭写入会话 [_assetWrite finishWritingWithCompletionHandler:^{ AVAssetWriterStatus status = self.assetWrite.status; if (status == AVAssetWriterStatusCompleted) { NSLog(@"finsished"); } else { NSLog(@"failure"); } }]; } } }]; } }
第五十七篇、AVAssetReader和AVAssetWrite 对视频进行编码的更多相关文章
- 第五十七篇:webpack打包发布
好家伙,到了打包发布这一步了 1.配置打包命令: 在package.json 文件的 scripts 节点下,新增 build 命令如下: "scripts": { "d ...
- Egret入门学习日记 --- 第十七篇(书中 7.4~8.2节 内容)
第十七篇(书中 7.4~8.2节 内容) 昨天看到 7.3 节,那么今天. 开始 7.4节. 好吧,这些其他的服务器运行知识,就不搞了... 至此,7.4节 内容结束. 开始 7.5节 内容. ...
- 解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译)
解剖SQLSERVER 第十七篇 使用 OrcaMDF Corruptor 故意损坏数据库(译) http://improve.dk/corrupting-databases-purpose-usin ...
- Python之路【第十七篇】:Django【进阶篇 】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路【第十七篇】:Django之【进阶篇】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- Python之路【第十七篇】:Django【进阶篇】
Python之路[第十七篇]:Django[进阶篇 ] Model 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞: 创建数据库,设计表结构和字段 使用 MySQLdb 来连接 ...
- 第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码
第三百五十七节,Python分布式爬虫打造搜索引擎Scrapy精讲—利用开源的scrapy-redis编写分布式爬虫代码 scrapy-redis是一个可以scrapy结合redis搭建分布式爬虫的开 ...
- “全栈2019”Java第五十七章:多态与构造方法详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库
孤荷凌寒自学python第五十七天初次尝试使用python来连接远端MongoDb数据库 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第三天.感觉这个东西学习起来还是那么困 ...
随机推荐
- ADO.NET 快速入门(十二):从 SQL Server 生成 XML 数据
本文演示如何使用2种不同的方法从 SQL Server 生成 XML. 方法1:使用了 SqlCommand 的 ExecuteXmlReader 方法获取 XmlReader,然后使用 Data ...
- Codeforces Round #327 (Div. 2) D. Chip 'n Dale Rescue Rangers 二分 物理
D. Chip 'n Dale Rescue Rangers Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/co ...
- iOS开发UI-利用Quartz2D 实现基本绘图(画三角形、矩形、圆、圆弧)
1.画三角形 运行结果如下 1.1具体实现步骤 1.1.1首先新建一个project,然后自定义一个view 1.2代码 #import "htingShapeView.h" @ ...
- .net平台下C#socket通信(转)
上篇.net平台下C#socket通信(上)介绍了socket通信的基本原理及最基本的通信方式.本文在此基础上就socket通信时经常遇到的问题做一个简单总结,都是项目中的一些小问题,拿来此处便于下次 ...
- MySQL查询优化--细节理论
select的 high_priority还是比较有用,在实践中,平均5~6秒提高到3秒 ======================================================= ...
- c#_自动化测试 (五) 读写64位操作系统的注册表
非Web程序(桌面程序)的设置一般都存在注册表中. 给这些程序做自动化测试时, 需要经常要跟注册表打交道. 通过修改注册表来修改程序的设置. 本章介绍如何利用C#程序如何操作注册表, 特别是如何操作6 ...
- Monolog - Logging for PHP 5.3+
Monolog 是PHP的一个日志类库.相比于其他的日志类库,它有以下的特点: 功能强大.可以把日志发送到文件.socket.邮箱.数据库和各种web services. 遵循 PSR3 的接口规范. ...
- 你真的会用UITableView嘛
UITableView是工程开发中最经常使用到的UI控件,但是你真的了解它嘛,这里记录几点有用的但你可能并不知道的. 当我们的数据未能显示满一屏幕的时候,UITableView会显示多余的横线,这个时 ...
- HTTP,TCP/IP,Socket
HTTP:超文本传输协议,首先它是一个协议,并且是基于TCP/IP协议基础之上的应用层协议. TCP/IP协议是传输层协议,主要解决数据如何在网络中传输,HTTP是应用层协议,主要解决如何包装数据. ...
- B - Plane of Tanks: Pro
Description Vasya has been playing Plane of Tanks with his friends the whole year. Now it is time to ...