叨叨兩句ios
動手寫這篇總結時候也是二月底過完年回來上班了,又開始新的一年了,今年會是什麼樣子?這問題可能得年末再回答本身了。在家窩了那麼久,上班仍是的接着看咱們要看的東西,畢竟咱們要作的事還真的太多的。app
總結第五章的內容,這兩天把後面幾章的內容大概的翻着看了看,知道了下後面幾章的內容大體講的都是那些內容。這裏就先開始總結書本中第五章的內容。前面第四章的內容視頻播放咱們再前面的確也總過了,就不在這裏再去重複總結。異步
一:AVPlayerViewControlleride
在第五章的最開始講述的就是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的通常算數運算ui
#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源代碼對於它的定義:this
/*! @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能夠學到許多東西!