應用場景====在項目中需要根據視頻內容,由用戶自行獲取視頻封面,為此,開發出一個簡單的類似相機視頻預覽的功能
image
底部橫條是根據視頻時間等分的時間節點獲取對應的視頻封面(這里取的是十等分)其實就是設置十個圖片,然后按時間節點獲取視頻截圖放進去(這里就不作代碼介紹了)
那個選中幀放大且可移動效果用的是uislider,通過將滑動的點設為獲取到的視頻幀圖而實現當前效果
重點在于下面這個視頻幀獲取的問題:
-(UIImage*)thumbnailImageWithAtTime:(NSTimeInterval)inputTime
{
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:_videoUrl options:nil];
//獲取視頻縮略圖
AVAssetImageGenerator imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
imageGenerator.appliesPreferredTrackTransform = YES;
CMTime requestTime;
requestTime =CMTimeMakeWithSeconds(inputTime, 600); // CMTime是表示電影時間信息的結構體,第一個參數表示是視頻當前時間,第二個參數表示每秒幀數
NSError* error =nil;
CMTime actualTime;
CGImageRefimageRef = [imageGeneratorcopyCGImageAtTime:requestTime actualTime:&actualTimeerror:&error];
UIImage *thumbImg = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
return thumbImg;
}
然而當你輸入你想要獲取的時間節點時,就會出現一個問題,獲取的圖片差強人意
為什么呢?這里要先看下CMTime的內容
CMTime是表示視頻時間信息的結構體。
它存在兩個構造函數:CMTimeMake 、CMTimeMakeWithSeconds
CMTimeMake(a,b) a當前第幾幀, b每秒鐘多少幀(例如):
CMTime showTime =CMTimeMake(900, 300);
CMTimeShow(showTime);
輸出: {900/300 = 3.000}
代表處于900幀,一秒鐘300幀,當前時間為3秒
CMTimeMakeWithSeconds(a,b) a當前時間,b每秒鐘多少幀.
CMTime showTime =CMTimeMakeWithSeconds(3, 300);
CMTimeShow(showTime);
輸出: {900/300 = 3.000}
代表當前時間為3s,一秒鐘300幀,處于900幀
按目前的分析來看,根據這個方法來做是可以獲取到幀圖的,為什么會出現偏差呢?
將requestTime與actualTime OUTPUT出來,
CMTimeShow(requestTime),CMTimeShow(actualTime)會發現兩者之間偏差很大
后來查了一下資料,獲取到了相關信息:
當我們獲取某個時間點的某一幀時,首先會在范圍內尋找,有索引內的關鍵幀(比如整數秒幀)或者緩存,就會直接返回,進而優化性能。
文檔中定義相關范圍的的API是 requestedTimeToleranceAfter 和 requestedTimeToleranceBefore
所以,我們處理獲取任意幀的問題就出在這,只要補上:
imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
就可以了。
以上內容是引用了其他大神的博客內容,具體地址因為是很久之前寫的文章已經遺忘,經人提醒過來排版。