2015-08-29 3 views
4

Я хочу захватить кадры из видео в определенное время. Я вызываю функцию grab-frame с временем, заданным в секундах как Float64. Проблема в том, что она не захватывает текущий кадр. Кажется, он игнорирует десятичные знаки. Если я вызову функцию, например, с 1.22 и 1.70, она вернет тот же фрейм. Я совершенно новый, когда речь заходит о Swift, поэтому я думаю, что я не получу объект CMTime. Так может ли кто-нибудь понять, что в этом плохого?Захват кадров из видео с помощью Swift

func generateThumnail(url : NSURL, fromTime:Float64) -> UIImage { 
    var asset :AVAsset = AVAsset.assetWithURL(url) as! AVAsset 
    var assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset) 
    assetImgGenerate.appliesPreferredTrackTransform = true 
    var error  : NSError? = nil 
    var time  : CMTime = CMTimeMakeWithSeconds(fromTime, 600)   
    var img   : CGImageRef = assetImgGenerate.copyCGImageAtTime(time, actualTime: nil, error: &error) 
    var frameImg : UIImage = UIImage(CGImage: img)! 
    return frameImg 
} 

var grabTime = 1.22 
img = generateThumnail(urlVideo, fromTime: Float64(grabTime)) 
+0

Ваш код работает нормально для меня в ИОС Playground: [скриншот 1] (https://www.evernote.com/shard/s89/sh/26b0df60-07ab-497a-aad0-fa1d846fb200/f1147c3886afd1f9/res/63c58859-ddec-4b65-98b0-5a577e10ec21/skitch.png), [скриншот 2] (https://www.evernote.com/shard/s89/sh/524547e8-9884-42ac-ad17-baa8d7eeb9b4/de65115d4542ffe2/res/071ab169-3913-4d33-8014-110de8a70416/skitch.png), поэтому ваша проблема делает не из-за непонимания CMTime. – Moritz

+0

Спасибо за попытку. Я не знаю, что я делаю неправильно. Я хочу захватить все кадры на 4-секундном клипе и сохранить их в массиве. Но большинство кадров выглядят одинаково. :/Возможно, это имеет какое-то отношение к длине видео. – arpo

+0

Вы пробовали использовать другой шкалу времени? 6000 - это много. Из документа: «если временной шкала равна 4, каждая единица представляет четверть секунды, а если временной интервал равен 10, каждая единица составляет десятую часть секунды и т. Д.». С вашей шкалой времени у меня также были некоторые сэмплированные изображения, являющиеся одними и теми же от моего короткого клипа, но больше не с гораздо меньшими временными шкалами. – Moritz

ответ

8

Благодаря @ Эрик-й, который нашел этот пост: iOS Take Multiple Screen Shots

мне удалось выяснить, что добавление:

assetImgGenerate.requestedTimeToleranceAfter = kCMTimeZero; 
    assetImgGenerate.requestedTimeToleranceBefore = kCMTimeZero; 

... к моей функции будет делать трюк.

Мой обновленный функция выглядит следующим образом:

func generateThumnail(url : NSURL, fromTime:Float64) -> UIImage { 
    var asset :AVAsset = AVAsset.assetWithURL(url) as! AVAsset 
    var assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset) 
    assetImgGenerate.appliesPreferredTrackTransform = true 
    assetImgGenerate.requestedTimeToleranceAfter = kCMTimeZero; 
    assetImgGenerate.requestedTimeToleranceBefore = kCMTimeZero; 
    var error  : NSError? = nil 
    var time  : CMTime = CMTimeMakeWithSeconds(fromTime, 600)   
    var img   : CGImageRef = assetImgGenerate.copyCGImageAtTime(time, actualTime: nil, error: &error) 
    var frameImg : UIImage = UIImage(CGImage: img)! 
    return frameImg 
} 

var grabTime = 1.22 
img = generateThumnail(urlVideo, fromTime: Float64(grabTime)) 
+2

обновления требуется для последующего использования быстрых версий: сделать { пусть IMG = попробовать assetImgGenerate.copyCGImageAtTime (время, ActualTime: ноль) возвращение UIImage (CGImage: IMG) } поймать пусть ошибку как NSError { печати ("Формирование изображения не удалось с error \ (ошибка) ") return nil } – Pichirichi

1

я включил ответ ARPO в в моем проекте, обновлялись Swift 3:

fileprivate func generateThumnail(url : URL, fromTime:Float64) -> UIImage? { 
    let asset :AVAsset = AVAsset(url: url) 
    let assetImgGenerate : AVAssetImageGenerator = AVAssetImageGenerator(asset: asset) 
    assetImgGenerate.appliesPreferredTrackTransform = true 
    assetImgGenerate.requestedTimeToleranceAfter = kCMTimeZero; 
    assetImgGenerate.requestedTimeToleranceBefore = kCMTimeZero; 
    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!) 
     return frameImg 
    } else { 
     return nil 
    } 
} 
+0

Это не работает. получение нулевого изображения – shripad20

Смежные вопросы