叨叨两句


 

      动手写这篇总结时候也是二月底过完年回来上班了,又开始新的一年了,今年会是什么样子?这问题可能得年底再回答自己了。在家窝了那么久,上班还是的接着看我们要看的东西,毕竟我们要做的事还真的太多的。

      总结第五章的内容,这两天把后面几章的内容大概的翻着看了看,知道了下后面几章的内容大致讲的都是那些内容。这里就先开始总结书本中第五章的内容。前面第四章的内容视频播放我们再前面的确也总过了,就不在这里再去重复总结。

   

一:AVPlayerViewController


 

      在第五章的最开始讲述的就是AVPlayerViewController,这个控制器在前面也没有好好说过,不过苹果给我们的关于AVPlayerViewController的API也就那么多,我们在这里看看它的头文件,以及它的一些使用。下面就先看看AVPlayerViewController这个类的头文件的方法,我们对它的属性进行一个解释说明:

  1. File: AVPlayerViewController.h
  2. Framework: AVKit
  3. Copyright © 2014-2017 Apple Inc. All rights reserved.
  4. 导入库头文件
  5. #import <UIKit/UIKit.h>
  6. #import <AVFoundation/AVFoundation.h>
  7.  
  8. NS_ASSUME_NONNULL_BEGIN
  9. //AVPlayerViewController有这个代理,这个代理方法就在下面
  10. @protocol AVPlayerViewControllerDelegate;
  11.  
  12. @class AVPlayerViewController
  13. 这个摘要说明了AVPlayerViewController这个控制器的基本特征
  14. @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.
  15.  
  16. // 8.0之后有的AVPlayerViewController
  17. API_AVAILABLE(ios(8.0))
  18. @interface AVPlayerViewController : UIViewController
  19. // 简单的播放器AVPlayer属性
  20. @property player
  21. @abstract The player from which to source the media content for the view controller.
  22. @property (nonatomic, strong, nullable) AVPlayer *player;
  23.  
  24. // 是否展示添加在上面的子控件
  25. @property showsPlaybackControls
  26. @abstract Whether or not the receiver shows playback controls. Default is YES.
  27. @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).
  28. @property (nonatomic) BOOL showsPlaybackControls;
  29.  
  30. // 这个属性字面意思是视频重力 其实它是用来确定在承载层的范围内视频可以拉伸或者缩放的程度
  31. // 具体的在下面@discussion部分有讨论,我们再总结一下它三个值分别代表的含义
  32. // AVLayerVideoGravityResizeAspect 会在承载层的范围内缩放视频的大小来保持视频的原始比例宽高,默认值
  33. // AVLayerVideoGravityResizeAspectFill 保留视频的宽高比,并且通过缩放填满整个播放界面
  34. // AVLayerVideoGravityResize 会将视频内容拉伸匹配承载层的范围,一般不常用,因为会把图片扭曲导致变形
  35. @property videoGravity
  36. @abstract A string defining how the video is displayed within an AVPlayerLayer bounds rect.
  37. @discussion Options are AVLayerVideoGravityResizeAspect, AVLayerVideoGravityResizeAspectFill and AVLayerVideoGravityResize. AVLayerVideoGravityResizeAspect is default.
  38. See <AVFoundation/AVAnimation.h> for a description of these options.
  39. @property (nonatomic, copy) NSString *videoGravity;
  40.  
  41. // 通过这个bool类型的值确定视频是否已经准备好展示
  42. @property readyForDisplay
  43. @abstract Boolean indicating that the first video frame has been made ready for display for the current item of the associated AVPlayer.
  44. @property (nonatomic, readonly, getter = isReadyForDisplay) BOOL readyForDisplay;
  45.  
  46. // 视频的尺寸
  47. @property videoBounds
  48. @abstract The current size and position of the video image as displayed within the receiver's view's bounds.
  49. @property (nonatomic, readonly) CGRect videoBounds;
  50.  
  51. // 有自定义的控件可以添加在这里UIView上
  52. @property contentOverlayView
  53. @abstract Use the content overlay view to add additional custom views between the video content and the controls.
  54. @property (nonatomic, readonly, nullable) UIView *contentOverlayView;
  55.  
  56. // 是否允许使用画中画播放模式,这个画中画播放在下面会写Demo 9.0之后的属性
  57. @property allowsPictureInPicturePlayback
  58. @abstract Whether or not the receiver allows Picture in Picture playback. Default is YES.
  59. @property (nonatomic) BOOL allowsPictureInPicturePlayback API_AVAILABLE(ios(9.0));
  60.  
  61. // 10.0之后的属性
  62. @property updatesNowPlayingInfoCenter
  63. @abstract Whether or not the now playing info center should be updated. Default is YES.
  64. @property (nonatomic) BOOL updatesNowPlayingInfoCenter API_AVAILABLE(ios(10.0));
  65.  
  66. // 理解摘要的意思是是否允许点击播放之后自动全屏播放视频 默认值是NO
  67. @property entersFullScreenWhenPlaybackBegins
  68. @abstract Whether or not the receiver automatically enters full screen when the play button is tapped. Default is NO.
  69. @discussion If YES, the receiver will show a user interface tailored to this behavior.
  70. @property (nonatomic) BOOL entersFullScreenWhenPlaybackBegins API_AVAILABLE(ios(11.0));
  71.  
  72. // 也是理解摘要,是否允许退出全屏播放在播放结束之后
  73. @property exitsFullScreenWhenPlaybackEnds
  74. @abstract Whether or not the receiver automatically exits full screen when playback ends. Default is NO.
  75. @discussion If multiple player items have been enqueued, the receiver exits fullscreen once no more items are remaining in the queue.
  76. @property (nonatomic) BOOL exitsFullScreenWhenPlaybackEnds API_AVAILABLE(ios(11.0));
  77.  
  78. // AVPlayerViewControllerDelegate代理
  79. @property delegate
  80. @abstract The receiver's delegate.
  81. @property (nonatomic, weak, nullable) id <AVPlayerViewControllerDelegate> delegate API_AVAILABLE(ios(9.0));
  82. @end
  83.  
  84. // 下面就是AVPlayerViewControllerDelegate代理方法 下面的代理方法都是optional可选的
  85. @protocol AVPlayerViewControllerDelegate
  86. @abstract A protocol for delegates of AVPlayerViewController.
  87. @protocol AVPlayerViewControllerDelegate <NSObject>
  88. @optional
  89.  
  90. @method playerViewControllerWillStartPictureInPicture:
  91. @param playerViewController The player view controller.
  92. @abstract Delegate can implement this method to be notified when Picture in Picture will start.
  93. // 即将开始画中画播放
  94. - (void)playerViewControllerWillStartPictureInPicture:(AVPlayerViewController *)playerViewController;
  95.  
  96. @method playerViewControllerDidStartPictureInPicture:
  97. @param playerViewController The player view controller.
  98. @abstract Delegate can implement this method to be notified when Picture in Picture did start.
  99. // 已经开始了画中画播放模式
  100. - (void)playerViewControllerDidStartPictureInPicture:(AVPlayerViewController *)playerViewController;
  101.  
  102. @method playerViewController:failedToStartPictureInPictureWithError:
  103. @param playerViewController The player view controller.
  104. @param error An error describing why it failed.
  105. @abstract Delegate can implement this method to be notified when Picture in Picture failed to start.
  106. // 这个摘要已经给我们说的比较清楚了,当画中画模式播放失败之后就会走这个代理方法
  107. - (void)playerViewController:(AVPlayerViewController *)playerViewController failedToStartPictureInPictureWithError:(NSError *)error;
  108.  
  109. @method playerViewControllerWillStopPictureInPicture:
  110. @param playerViewController The player view controller.
  111. @abstract Delegate can implement this method to be notified when Picture in Picture will stop.
  112. // 画中画播放模式即将结束
  113. - (void)playerViewControllerWillStopPictureInPicture:(AVPlayerViewController *)playerViewController;
  114.  
  115. @method playerViewControllerDidStopPictureInPicture:
  116. @param playerViewController The player view controller.
  117. @abstract Delegate can implement this method to be notified when Picture in Picture did stop.
  118. // 画中画播放已经结束
  119. - (void)playerViewControllerDidStopPictureInPicture:(AVPlayerViewController *)playerViewController;
  120.  
  121. @method playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:
  122. @param playerViewController The player view controller.
  123. @abstract Delegate can implement this method and return NO to prevent(阻止) player view controller from automatically being dismissed when Picture in Picture starts.
  124. // 要是在画中画开始播放的时候 播放的底层控制器要是消失就返回NO
  125. - (BOOL)playerViewControllerShouldAutomaticallyDismissAtPictureInPictureStart:(AVPlayerViewController *)playerViewController;
  126.  
  127. @method playerViewController:restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:
  128. @param playerViewController The player view controller.
  129. @param completionHandler The completion handler the delegate needs to call after restore.
  130. @abstract Delegate can implement this method to restore(恢复) the user interface(交互) before Picture in Picture stops.
  131. // 画中画播放结束恢复用户交互
  132. - (void)playerViewController:(AVPlayerViewController *)playerViewController restoreUserInterfaceForPictureInPictureStopWithCompletionHandler:(void (^)(BOOL restored))completionHandler;
  133.  
  134. @end
  135. NS_ASSUME_NONNULL_END

 

 

就这两点了


  

      书中的第四五章的内容在总结也就还剩这么两点,由于还有部分涉及到的是Mac OS 系统的部分知识,我们就在这里不提了,就说说还需要我们理解的两点:

 

      一: CMTime  也是对第四章一点内容的补充

             我们简单的看看这个CMTime的一般算数运算

  1. #pragma mark --
  2. #pragma mark -- CMTime的简单的使用
  3. -(void)CMTimeCalculate{
  4. CMTime timeO = CMTimeMake(1,10);
  5. CMTime timeT = CMTimeMake(1,5);
  6. // 加
  7. CMTime timeA = CMTimeAdd(timeO,timeT);
  8. CMTimeShow(timeA);
  9. //减
  10. CMTime timeS = CMTimeSubtract(timeO,timeT);
  11. CMTimeShow(timeS);
  12. //乘 整形
  13. CMTime timeB = CMTimeMake(1,10);
  14. CMTime timeI = CMTimeMultiply(timeB,5);
  15. CMTimeShow(timeI);
  16. //乘 浮点型
  17. CMTime timeF = CMTimeMultiplyByFloat64(timeB,5.6);
  18. CMTimeShow(timeF);
  19. // 比较 1是大于 0是相等 -1是小于
  20. int timeC = CMTimeCompare(timeO,timeT);
  21. NSLog(@"比较得到大的是%d",timeC); // -1
  22. //求绝对值
  23. CMTime timeAB = CMTimeAbsoluteValue(timeS);
  24. CMTimeShow(timeAB);
  25. }

 

      CMTimeRange也是属于CMTime范畴,下面是在我们的iOS源代码对于它的定义:

  1. /*!
  2. @typedef CMTimeRange
  3. @abstract A time range represented as two CMTime structures.
  4. */
  5. typedef struct
  6. {
  7. CMTime start; /*! @field start The start time of the time range. */
  8. CMTime duration; /*! @field duration The duration of the time range. */
  9. } CMTimeRange;

      通过这个定义我们就了解了它的组成,在Demo中我们已经是简单的使用过它了,具体点的我们可以在代码中去查看。

      关于CMTime还有一点值得我们注意,那就是它和秒之间的转换函数: Float64 CMTimeGetSeconds(CMTime time)  通过这个函数,你就可以把一个CMTime实例转换成Float64位对象。

 

 

AVAssetExportSession


 

 

      我们先看看在我们的Demo里面我们使用到的关于AVAssetExportSession的代码,我们在这里使用它的时候只是利用它进行了一下视频的压缩:

  1. #pragma mark --
  2. #pragma mark -- 视频压缩方法
  3. -(void)compressVideoWithFileUrl:(NSURL *)fileUrl{
  4. /*
  5. 这里需要注意的一点就是在重复的路径上保存文件是不行的,可以选择在点击开始的时候删除之前的
  6. 也可以这样按照时间命名不同的文件保存
  7. 在后面的 AVAssetWriter 也要注意这一点
  8. */
  9. // 压缩后的视频的方法命名
  10. NSDateFormatter * formatter = [[NSDateFormatter alloc]init];
  11. [formatter setDateFormat:@"yyyy-MM-dd-HH:mm:ss"];
  12. // 压缩后的文件路径
  13. self.videoPath = [NSString stringWithFormat:@"%@/%@.mov",NSTemporaryDirectory(),[formatter stringFromDate:[NSDate date]]];
  14. // 先根据你传入的文件的路径穿件一个AVAsset
  15. AVAsset * asset = [AVAsset assetWithURL:fileUrl];
  16. /*
  17. 根据urlAsset创建AVAssetExportSession压缩类
  18. 第二个参数的意义:常用 压缩中等质量 AVAssetExportPresetMediumQuality
  19. AVF_EXPORT NSString *const AVAssetExportPresetLowQuality NS_AVAILABLE_IOS(4_0);
  20. AVF_EXPORT NSString *const AVAssetExportPresetMediumQuality NS_AVAILABLE_IOS(4_0);
  21. AVF_EXPORT NSString *const AVAssetExportPresetHighestQuality NS_AVAILABLE_IOS(4_0);
  22. */
  23. AVAssetExportSession * exportSession = [[AVAssetExportSession alloc]initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
  24. // 优化压缩,这个属性能使压缩的质量更好
  25. exportSession.shouldOptimizeForNetworkUse = YES;
  26. // 到处的文件的路径
  27. exportSession.outputURL = [NSURL fileURLWithPath:self.videoPath];
  28. // 导出的文件格式
  29. /*!
  30. @constant AVFileTypeMPEG4 mp4格式的 AVFileTypeQuickTimeMovie mov格式的
  31. @abstract A UTI for the MPEG-4 file format.
  32. @discussion
  33. The value of this UTI is @"public.mpeg-4".
  34. Files are identified with the .mp4 extension.
  35. 可以看看这个outputFileType格式,比如AVFileTypeMPEG4也可以写成public.mpeg-4,其他类似
  36. */
  37. exportSession.outputFileType = AVFileTypeQuickTimeMovie;
  38. NSLog(@"视频压缩后的presetName: %@",exportSession.presetName);
  39. // 压缩的方法 export 导出 Asynchronously 异步
  40. [exportSession exportAsynchronouslyWithCompletionHandler:^{
  41. /*
  42. exportSession.status 枚举属性
  43. typedef NS_ENUM(NSInteger, AVAssetExportSessionStatus) {
  44. AVAssetExportSessionStatusUnknown,
  45. AVAssetExportSessionStatusWaiting,
  46. AVAssetExportSessionStatusExporting,
  47. AVAssetExportSessionStatusCompleted,
  48. AVAssetExportSessionStatusFailed,
  49. AVAssetExportSessionStatusCancelled
  50. };
  51. */
  52. int exportStatus = exportSession.status;
  53. switch (exportStatus) {
  54. case AVAssetExportSessionStatusFailed:
  55. NSLog(@"压缩失败");
  56. break;
  57. case AVAssetExportSessionStatusCompleted:
  58. {
  59. /*
  60. 压缩后的大小
  61. 也可以利用exportSession的progress属性,随时监测压缩的进度
  62. */
  63. NSData * data = [NSData dataWithContentsOfFile:self.videoPath];
  64. float dataSize = (float)data.length/1024/1024;
  65. NSLog(@"视频压缩后大小 %f M", dataSize);
  66. }
  67. break;
  68. default:
  69. break;
  70. }
  71. }];
  72. }

 

      总结一下:

      通过补充上面的这两点就算是总结完了书中前五章大概的内容,通过后面这两点的学习,能总结出来的就是多看API文件!摘要虽然都是英文的,有些同行可能因为不太好就不会去看,但读懂一些基本的英文文档也是我们的基本技能,通过看API可以学到许多东西!

版权声明:本文为taoxu原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/taoxu/p/8337127.html