2017-03-08 79 views
0

我跟隨this code獲取視頻中的所有幀。在這個環節中,他正試圖在特定的時間得到一個框架。但我需要獲得所有框架。這裏是我的代碼...Swift - 從視頻中獲取所有幀

var mutableVideoURL = NSURL() 
var videoFrames = [UIImage]() 

let asset : AVAsset = AVAsset(url: self.mutableVideoURL as URL) 
let mutableVideoDuration = CMTimeGetSeconds(asset.duration) 
print("-----Mutable video duration = \(mutableVideoDuration)") 
let mutableVideoDurationIntValue = Int(mutableVideoDuration) 
print("-----Int value of mutable video duration = \(mutableVideoDurationIntValue)") 

for index in 0..<mutableVideoDurationIntValue { 
    self.generateFrames(url: self.mutableVideoURL, fromTime: Float64(index)) 
} 

    func generateFrames(url : NSURL, fromTime:Float64) { 
     let asset: AVAsset = AVAsset(url: url as URL) 
     let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset) 
     assetImgGenerate.appliesPreferredTrackTransform = true 
     let time  : CMTime = CMTimeMakeWithSeconds(fromTime, 600) 
     var img: CGImage? 
     do { 
      img = try assetImgGenerate.copyCGImage(at:time, actualTime: nil) 
     } catch { 
     } 
     if img != nil { 
      let frameImg: UIImage = UIImage(cgImage: img!) 
      UIImageWriteToSavedPhotosAlbum(frameImg, nil, nil, nil)//I saved here to check 
      videoFrames.append(frameImg) 
      print("-----Array of video frames *** \(videoFrames)") 
     } else { 
       print("error !!!") 
     } 
    } 

我測試此代碼與2個視頻(的影片長度約5秒和3.45分鐘)。此代碼完美適用於持續時間較短(視頻長度:5秒)和持續時間較長(視頻長度:3.45分鐘)的情況,NSLog顯示來自調試器的消息:由於內存問題而終止 任何幫助將不勝感激。

+0

有什麼錯誤?你可以把'print(error.localizedDescription)'趕進 – WeiJay

+0

來自調試器的消息:由於內存問題而終止:( –

+0

那麼這意味着內存中有太多的幀,所以它會崩潰。本質上,你需要處理和循環以較少內存密集的方式通過圖像。 – Harish

回答

0

當產生超過1幀蘋果公司建議使用方法: generateCGImagesAsynchronously(forTimes:completionHandler:)

不過,如果你喜歡跟隨當前的做法有一對夫婦的改進,你可以做些什麼來減少內存使用:

  • 您正在實例化循環內的AVAssetAVAssetImageGenerator,您可以將它們實例化一次並將其發送給方法generateFrames
  • 刪除線

    UIImageWriteToSavedPhotosAlbum(frameImg, nil, nil, nil)//I saved here to check

    ,因爲你是在照片 專輯,這需要額外的內存節省每幀。

最終結果可能是這樣的:

var videoFrames:[UIImage] = [UIImage] 
let asset:AVAsset = AVAsset(url:self.mutableVideoURL as URL) 
let assetImgGenerate:AVAssetImageGenerator = AVAssetImageGenerator(asset:asset) 
assetImgGenerate.appliesPreferredTrackTransform = true 
let duration:Float64 = CMTimeGetSeconds(asset.duration) 
let durationInt:Int = Int(mutableVideoDuration) 

for index:Int in 0 ..< durationInt 
{ 
    generateFrames(
     assetImgGenerate:assetImgGenerate, 
     fromTime:Float64(index)) 
} 

func generateFrames(
    assetImgGenerate:AVAssetImageGenerator, 
    fromTime:Float64) 
{ 
    let time:CMTime = CMTimeMakeWithSeconds(fromTime, 600) 
    let cgImage:CGImage? 

    do 
    { 
     cgImage = try assetImgGenerate.copyCGImage(at:time, actualTime:nil) 
    } 
    catch 
    { 
     cgImage = nil 
    } 

    guard 

     let img:CGImage = cgImage 

    else 
    { 
     continue 
    } 

    let frameImg:UIImage = UIImage(cgImage:img) 
    videoFrames.append(frameImg) 
}