第五十七篇、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数据库的第三天.感觉这个东西学习起来还是那么困 ...
随机推荐
- 2015 NOIP day1 t1 神奇的幻方 模拟
神奇的幻方 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.luogu.org/problem/show?pid=2615 Descri ...
- POJ 2420 A Star not a Tree? 爬山算法
B - A Star not a Tree? Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/co ...
- 读《C# 和 Java 的比较》有感
网上的一篇<C# 和 Java 的比较>(或者叫<Java 和 C# 的比较>)写的挺不错的,今天忽然搜索到. 自己刚刚接触C#,也不由自主地随时都拿来和Java做对比,所以就 ...
- 【项目实例】android开发游戏音效代码实例
//音效的音量 int streamVolume; //定义SoundPool 对象 private SoundPool soundPool; //定义HASH表 private HashMap< ...
- Github上最全的APICloud开源前端框架效果盘点(转)
1.微信网站几分钟变身“原生 App” 微信推出了微信JS-SDK,使微信公共号可以直接调用微信原生的接口,具备部分原生应用的能力.微信JS-SDK的推出,将大大提高微信公共号的 用户体验,但是如果存 ...
- apue.h
[root@localhost unix_env_advance_prog]# cat apue.h #ifndef _APUE_H #define _APUE_H #define _XOPEN_SO ...
- C++:构造函数和析构函数能否为虚函数
原文:http://blog.csdn.net/xhz1234/article/details/6510568 C++:构造函数和析构函数能否为虚函数? 简单回答是:构造函数不能为虚函数,而析构函数可 ...
- JS_CSS_logon_Mask
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 1、netlink 连接器 通信机制
使用netlink之前,先参考一下资料:http://www.ibm.com/developerworks/cn/linux/l-connector/ netlink通信机制介绍:资料来源 linux ...
- G - Just a Hook
Description In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most of t ...