AVFoundation 框架初探究(四)

叨叨两句
动手写这篇总结时候也是二月底过完年回来上班了,又开始新的一年了,今年会是什么样子?这问题可能得年底再回答自己了。在家窝了那么久,上班还是的接着看我们要看的东西,毕竟我们要做的事还真的太多的。
总结第五章的内容,这两天把后面几章的内容大概的翻着看了看,知道了下后面几章的内容大致讲的都是那些内容。这里就先开始总结书本中第五章的内容。前面第四章的内容视频播放我们再前面的确也总过了,就不在这里再去重复总结。
一:AVPlayerViewController
在第五章的最开始讲述的就是AVPlayerViewController,这个控制器在前面也没有好好说过,不过苹果给我们的关于AVPlayerViewController的API也就那么多,我们在这里看看它的头文件,以及它的一些使用。下面就先看看AVPlayerViewController这个类的头文件的方法,我们对它的属性进行一个解释说明:
File: AVPlayerViewController.h
Framework: AVKit
Copyright © 2014-2017 Apple Inc. All rights reserved.
导入库头文件
#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h> NS_ASSUME_NONNULL_BEGIN
//AVPlayerViewController有这个代理,这个代理方法就在下面
@protocol AVPlayerViewControllerDelegate; @class AVPlayerViewController
这个摘要说明了AVPlayerViewController这个控制器的基本特征
@abstract AVPlayerViewController is a subclass of UIViewController that can be used to display the visual content of an AVPlayer object and the standard playback controls. // 8.0之后有的AVPlayerViewController
API_AVAILABLE(ios(8.0))
@interface AVPlayerViewController : UIViewController // 简单的播放器AVPlayer属性
@property player
@abstract The player from which to source the media content for the view controller.
@property (nonatomic, strong, nullable) AVPlayer *player; // 是否展示添加在上面的子控件
@property showsPlaybackControls
@abstract Whether or not the receiver shows playback controls. Default is YES.
@discussion Clients can set this property to NO when they don't want to have any playback controls on top of the visual content (e.g. for a game splash screen).
@property (nonatomic) BOOL showsPlaybackControls; // 这个属性字面意思是视频重力 其实它是用来确定在承载层的范围内视频可以拉伸或者缩放的程度
// 具体的在下面@discussion部分有讨论,我们再总结一下它三个值分别代表的含义
// AVLayerVideoGravityResizeAspect 会在承载层的范围内缩放视频的大小来保持视频的原始比例宽高,默认值
// AVLayerVideoGravityResizeAspectFill 保留视频的宽高比,并且通过缩放填满整个播放界面
// AVLayerVideoGravityResize 会将视频内容拉伸匹配承载层的范围,一般不常用,因为会把图片扭曲导致变形
@property videoGravity
@abstract A string defining how the video is displayed within an AVPlayerLayer bounds rect.
@discussion Options are AVLayerVideoGravityResizeAspect, AVLayerVideoGravityResizeAspectFill and AVLayerVideoGravityResize. AVLayerVideoGravityResizeAspect is default.
See <AVFoundation/AVAnimation.h> for a description of these options.
@property (nonatomic, copy) NSString *videoGravity; // 通过这个bool类型的值确定视频是否已经准备好展示
@property readyForDisplay
@abstract Boolean indicating that the first video frame has been made ready for display for the current item of the associated AVPlayer.
@property (nonatomic, readonly, getter = isReadyForDisplay) BOOL readyForDisplay; // 视频的尺寸
@property videoBounds
@abstract The current size and position of the video image as displayed within the receiver's view's bounds.
@property (nonatomic, readonly) CGRect videoBounds; // 有自定义的控件可以添加在这里UIView上
@property contentOverlayView
@abstract Use the content overlay view to add additional custom views between the video content and the controls.
@property (nonatomic, readonly, nullable) UIView *contentOverlayView; // 是否允许使用画中画播放模式,这个画中画播放在下面会写Demo 9.0之后的属性
@property allowsPictureInPicturePlayback
@abstract Whether or not the receiver allows Picture in Picture playback. Default is YES.
@property (nonatomic) BOOL allowsPictureInPicturePlayback API_AVAILABLE(ios(9.0)); // 10.0之后的属性
@property updatesNowPlayingInfoCenter
@abstract Whether or not the now playing info center should be updated. Default is YES.
@property (nonatomic) BOOL updatesNowPlayingInfoCenter API_AVAILABLE(ios(10.0)); // 理解摘要的意思是是否允许点击播放之后自动全屏播放视频 默认值是NO
@property entersFullScreenWhenPlaybackBegins
@abstract Whether or not the receiver automatically enters full screen when the play button is tapped. Default is NO.
@discussion If YES, the receiver will show a user interface tailored to this behavior.
@property (nonatomic) BOOL entersFullScreenWhenPlaybackBegins API_AVAILABLE(ios(11.0)); // 也是理解摘要,是否允许退出全屏播放在播放结束之后
@property exitsFullScreenWhenPlaybackEnds
@abstract Whether or not the receiver automatically exits full screen when playback ends. Default is NO.
@discussion If multiple player items have been enqueued, the receiver exits fullscreen once no more items are remaining in the queue.
@property (nonatomic) BOOL exitsFullScreenWhenPlaybackEnds API_AVAILABLE(ios(11.0)); // AVPlayerViewControllerDelegate代理
@property delegate
@abstract The receiver's delegate.
@property (nonatomic, weak, nullable) id <AVPlayerViewControllerDelegate> delegate API_AVAILABLE(ios(9.0));
@end // 下面就是AVPlayerViewControllerDelegate代理方法 下面的代理方法都是optional可选的
@protocol AVPlayerViewControllerDelegate
@abstract A protocol for delegates of AVPlayerViewController.
@protocol AVPlayerViewControllerDelegate <NSObject>
@optional @method playerViewControllerWillStartPictureInPicture:
@param playerViewController The player view controller.
@abstract Delegate can implement this method to be notified when Picture in Picture will start.
// 即将开始画中画播放
- (void)playerViewControllerWillStartPictureInPicture:(AVPlayerViewController *)playerViewController; @method playerViewControllerDidStartPictureInPicture:
@param playerViewController The player view controller.
@abstract Delegate can implement this method to be notified when Picture in Picture did start.
// 已经开始了画中画播放模式
- (void)playerViewControllerDidStartPictureInPicture:(AVPlayerViewController *)playerViewController; @method playerViewController:failedToStartPictureInPictureWithError:
@param playerViewController The player view controller.
@param error An error describing why it failed.
@abstract Delegate can implement this method to be notified when Picture in Picture failed to start.
// 这个摘要已经给我们说的比较清楚了,当画中画模式播放失败之后就会走这个代理方法
- (void)playerViewController:(AVPlayerViewController *)playerViewController failedToStartPictureInPictureWithError:(NSError *)error; @method playerViewControllerWillStopPictureInPicture:
@param playerViewController The player view controller.
@abstract Delegate can implement this method to be notified when Picture in Picture will stop.
// 画中画播放模式即将结束
- (void)playerViewControllerWillStopPictureInPicture:(AVPlayerViewController *)playerViewController; @method playerViewControllerDidStopPictureInPicture:
@param playerViewController The player view controller.
@abstract Delegate can implement this method to be notified when Picture in Picture did stop.
// 画中画播放已经结束
- (void)playerViewControllerDidStopPictureInPicture:(AVPlayerViewController *)playerViewController; @method playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:
@param playerViewController The player view controller.
@abstract Delegate can implement this method and return NO to prevent(阻止) player view controller from automatically being dismissed when Picture in Picture starts.
// 要是在画中画开始播放的时候 播放的底层控制器要是消失就返回NO
- (BOOL)playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:(AVPlayerViewController *)playerViewController; @method playerViewController:restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:
@param playerViewController The player view controller.
@param completionHandler The completion handler the delegate needs to call after restore.
@abstract Delegate can implement this method to restore(恢复) the user interface(交互) before Picture in Picture stops.
// 画中画播放结束恢复用户交互
- (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler; @end
NS_ASSUME_NONNULL_END
就这两点了
书中的第四五章的内容在总结也就还剩这么两点,由于还有部分涉及到的是Mac OS 系统的部分知识,我们就在这里不提了,就说说还需要我们理解的两点:
一: CMTime 也是对第四章一点内容的补充
我们简单的看看这个CMTime的一般算数运算
#pragma mark --
#pragma mark -- CMTime的简单的使用
-(void)CMTimeCalculate{ CMTime timeO = CMTimeMake(1,10);
CMTime timeT = CMTimeMake(1,5); // 加
CMTime timeA = CMTimeAdd(timeO,timeT);
CMTimeShow(timeA); //减
CMTime timeS = CMTimeSubtract(timeO,timeT);
CMTimeShow(timeS); //乘 整形
CMTime timeB = CMTimeMake(1,10);
CMTime timeI = CMTimeMultiply(timeB,5);
CMTimeShow(timeI); //乘 浮点型
CMTime timeF = CMTimeMultiplyByFloat64(timeB,5.6);
CMTimeShow(timeF); // 比较 1是大于 0是相等 -1是小于
int timeC = CMTimeCompare(timeO,timeT);
NSLog(@"比较得到大的是%d",timeC); // -1 //求绝对值
CMTime timeAB = CMTimeAbsoluteValue(timeS);
CMTimeShow(timeAB);
}
CMTimeRange也是属于CMTime范畴,下面是在我们的iOS源代码对于它的定义:
/*!
@typedef CMTimeRange
@abstract A time range represented as two CMTime structures.
*/
typedef struct
{
CMTime start; /*! @field start The start time of the time range. */
CMTime duration; /*! @field duration The duration of the time range. */
} CMTimeRange;
通过这个定义我们就了解了它的组成,在Demo中我们已经是简单的使用过它了,具体点的我们可以在代码中去查看。
关于CMTime还有一点值得我们注意,那就是它和秒之间的转换函数: Float64 CMTimeGetSeconds(CMTime time) 通过这个函数,你就可以把一个CMTime实例转换成Float64位对象。
AVAssetExportSession
我们先看看在我们的Demo里面我们使用到的关于AVAssetExportSession的代码,我们在这里使用它的时候只是利用它进行了一下视频的压缩:
#pragma mark --
#pragma mark -- 视频压缩方法
-(void)compressVideoWithFileUrl:(NSURL *)fileUrl{ /*
这里需要注意的一点就是在重复的路径上保存文件是不行的,可以选择在点击开始的时候删除之前的
也可以这样按照时间命名不同的文件保存
在后面的 AVAssetWriter 也要注意这一点
*/
// 压缩后的视频的方法命名
NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:@"yyyy-MM-dd-HH:mm:ss"]; // 压缩后的文件路径
self.videoPath = [NSString stringWithFormat:@"%@/%@.mov",NSTemporaryDirectory(),[formatter stringFromDate:[NSDate date]]]; // 先根据你传入的文件的路径穿件一个AVAsset
AVAsset * asset = [AVAsset assetWithURL:fileUrl];
/* 根据urlAsset创建AVAssetExportSession压缩类
第二个参数的意义:常用 压缩中等质量 AVAssetExportPresetMediumQuality
AVF_EXPORT NSString *const AVAssetExportPresetLowQuality NS_AVAILABLE_IOS(4_0);
AVF_EXPORT NSString *const AVAssetExportPresetMediumQuality NS_AVAILABLE_IOS(4_0);
AVF_EXPORT NSString *const AVAssetExportPresetHighestQuality NS_AVAILABLE_IOS(4_0); */
AVAssetExportSession * exportSession = [[AVAssetExportSession alloc]initWithAsset:asset presetName:AVAssetExportPresetMediumQuality]; // 优化压缩,这个属性能使压缩的质量更好
exportSession.shouldOptimizeForNetworkUse = YES;
// 到处的文件的路径
exportSession.outputURL = [NSURL fileURLWithPath:self.videoPath];
// 导出的文件格式
/*!
@constant AVFileTypeMPEG4 mp4格式的 AVFileTypeQuickTimeMovie mov格式的
@abstract A UTI for the MPEG-4 file format.
@discussion
The value of this UTI is @"public.mpeg-4".
Files are identified with the .mp4 extension.
可以看看这个outputFileType格式,比如AVFileTypeMPEG4也可以写成public.mpeg-4,其他类似
*/
exportSession.outputFileType = AVFileTypeQuickTimeMovie; NSLog(@"视频压缩后的presetName: %@",exportSession.presetName);
// 压缩的方法 export 导出 Asynchronously 异步
[exportSession exportAsynchronouslyWithCompletionHandler:^{ /*
exportSession.status 枚举属性
typedef NS_ENUM(NSInteger, AVAssetExportSessionStatus) {
AVAssetExportSessionStatusUnknown,
AVAssetExportSessionStatusWaiting,
AVAssetExportSessionStatusExporting,
AVAssetExportSessionStatusCompleted,
AVAssetExportSessionStatusFailed,
AVAssetExportSessionStatusCancelled
};
*/
int exportStatus = exportSession.status;
switch (exportStatus) {
case AVAssetExportSessionStatusFailed: NSLog(@"压缩失败");
break;
case AVAssetExportSessionStatusCompleted:
{
/*
压缩后的大小
也可以利用exportSession的progress属性,随时监测压缩的进度
*/
NSData * data = [NSData dataWithContentsOfFile:self.videoPath];
float dataSize = (float)data.length/1024/1024;
NSLog(@"视频压缩后大小 %f M", dataSize); }
break;
default:
break;
}
}];
}
总结一下:
通过补充上面的这两点就算是总结完了书中前五章大概的内容,通过后面这两点的学习,能总结出来的就是多看API文件!摘要虽然都是英文的,有些同行可能因为不太好就不会去看,但读懂一些基本的英文文档也是我们的基本技能,通过看API可以学到许多东西!
AVFoundation 框架初探究(四)的更多相关文章
- AVFoundation 框架初探究(二)
接着第一篇总结 系列第一篇地址:AVFoundation 框架初探究(一) 在第一篇的文章中,我们总结了主要有下面几个点的知识: 1.对AVFoundation框架整体的一个认识 2.AVSpeech ...
- AVFoundation 框架初探究(一)
夜深时动笔 前面一篇文章写了视频播放的几种基本的方式,算是给这个系列开了一个头,这里面最想说和探究的就是AVFoundation框架,很想把这个框架不敢说是完全理解,但至少想把它弄明白它里面到底有什么 ...
- AVFoundation 框架初探究(三)
这篇总结什么? 在该系列的上一篇的文章中,我们总结的大致内容如下: 1.视频录制 AVCaptureSession + AVCaptureMovieFileOutput 2.视频录制 AVCaptu ...
- NLog日志框架使用探究-2
目录 前言 自定义参数 日志输出方式 文件 网络传输 数据库 科学使用 参考文档 前言 在一年前,我写过一篇关于NLog入门文章<NLog日志框架使用探究-1>,文章简单的介绍了Nlog的 ...
- Golang 网络爬虫框架gocolly/colly 四
Golang 网络爬虫框架gocolly/colly 四 爬虫靠演技,表演得越像浏览器,抓取数据越容易,这是我多年爬虫经验的感悟.回顾下个人的爬虫经历,共分三个阶段:第一阶段,09年左右开始接触爬虫, ...
- Spring框架的第四天(整合ssh框架)
## Spring框架的第四天 ## ---------- **课程回顾:Spring框架第三天** 1. AOP注解方式 * 编写切面类(包含通知和切入点) * 开启自动代理 2. JDBC模板技术 ...
- Hibernate框架的第四天
## Hibernate框架的第四天 ## ---------- **回顾:Hibernate框架的第三天** 1. 一对多关联关系映射 * JavaBean的编写 * 编写映射的配置文件 * 使用级 ...
- 自己写一个java的mvc框架吧(四)
自己写一个mvc框架吧(四) 写一个请求的入口,以及初始化框架 上一章写了获取方法的入参,并根据入参的参数类型进行数据转换.这时候,我们已经具备了通过反射调用方法的一切必要条件.现在我们缺少一个htt ...
- Hadoop 框架基础(四)
** Hadoop 框架基础(四) 上一节虽然大概了解了一下 mapreduce,徒手抓了海胆,不对,徒手写了 mapreduce 代码,也运行了出来.但是没有做更深入的理解和探讨. 那么…… 本节目 ...
随机推荐
- 异步式I/O与实践式编程
阻塞 线程在执行中如果遇到磁盘读写或网络通信(统称为I/O操作)通常要消耗很长时间 这时操作系统会剥夺这个线程的CPU控制权,使其暂停执行,同时将资源让给其他工作线程 异步I/O 非阻塞IO 针对所有 ...
- CentOS7.3 ARM虚拟机扩容系统磁盘
由于扩容磁盘的操作非同小可,一旦哪一步出现问题,就会导致分区损坏,数据丢失等一系列严重的问题,因此建议:在进行虚拟机分区扩容之前,一定要备份重要数据文件,并且先在测试机上验证以下步骤,再应用于您的生产 ...
- linux_DNS
linux其配置文件 : /etc/resolv.conf nameserver 223.5.5.5 nameserver 223.6.6.6 # 这两个解析地址为阿里云解析地址,格式也是这样 什么是 ...
- python_print和input
什么是输入? --用户从键盘.鼠标或其他终端 输入 的数据 -- input("提示信息") --python 2.7 rqw_input("提示信息") 如何 ...
- 转-Windows路由表配置:双网卡路由分流
原文链接:http://www.cnblogs.com/lightnear/archive/2013/02/03/2890835.html 一.windows 路由表解释 route print -4 ...
- CSS常用字体名称
CSS样式中常用的字体名称 css中引入字体: @font-face { font-family: "AncientWar"; src: url('style/css/font ...
- 个性化推荐调优:重写spark推荐api
最近用spark的mlib模块中的协同过滤库做个性化推荐.spark里面用的是als算法,本质上是矩阵分解svd降维,把一个M*N的用户商品评分矩阵分解为M*K的userFeature(用户特征矩阵) ...
- CSS核心内容之盒子模型
1.盒子模型具有的属性: 内容(content) 填充(padding) 边框(border) 边界(margin) 图示如下: 2.流概念 1.流的概念 在现实生活中已经流水,在网页设计中就是指元素 ...
- Effective Java 第三版——31.使用限定通配符来增加API的灵活性
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- NOIP 2017 day 1 游记
心情非常复杂.大概就是我问到的所有人都A掉了T1那样. 的确没有按套路出牌,今年T1不是大模拟,反倒是T2. ……已经不想再提到今天的T1了.如果真的要我说,我只能说 我再次学了一整年的OI,结果栽到 ...