2010-11-16 12 views
19

Przepraszam za mój angielski) Szukasz informacji o czytać klatek z filmu wideo z iPhone Znalazłem ten projekt, http://www.codza.com/extracting-frames-from-movies-on-iphone/comment-page-1#comment-1116, ale również czytałem gdzieś, że można użyć AVFoundation przechwytywanie klatek z video dla lepszej wydajności ..iPhone Czytaj UIImage (ramki) z filmu o AVFoundation

ale nie mogę znaleźć informacje o tym, jak mogę to zrobić ...

jakiś pomysł?

Dzięki za czytanie

Odpowiedz

36

Mówisz o użyciu połączenia do generowania co Jabłko zwraca miniatury z filmów o określonych porach.

Dla MPMoviePlayerController (którego system iOS używa do przechowywania wideo z pliku lub innego źródła), są dwa polecenia, aby to zrobić. Pierwsza generuje pojedynczą miniaturę (obraz) z filmu w określonym momencie, a druga generuje zestaw miniatur dla przedziału czasowego.

Ten przykład pobiera obraz co 10 sekund do klipu filmowego, myMovie.mp4:

MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] 
     initWithContentURL:[NSURL URLWithString:@"myMovie.mp4"]]; 
UIImage *singleFrameImage = [movie thumbnailImageAtTime:10 
     timeOption:MPMovieTimeOptionExact]; 

Zauważ, że ten wykonuje synchronicznie - tj użytkownik będzie musiał zaczekać, aż pojawi się zrzut ekranu.

Inną opcją jest, aby uzyskać serię zdjęć z filmu, z tablicy czasów:

MPMoviePlayerController *movie = [[MPMoviePlayerController alloc] 
     initWithContentURL [NSURL URLWithString:@"myMovie.mp4"]]; 
NSNumber time1 = 10; 
NSNumber time2 = 11; 
NSNumber time3 = 12; 
NSArray *times = [NSArray arrayWithObjects:time1,time2,time3,nil]; 
[movie requestThumbnailImagesAtTimes:times timeOption:MPMovieTimeOptionExact]; 

Ten drugi sposób spowoduje zgłoszenie typu MPMoviePlayerThumbnailImageRequestDidFinishNotification każdym razem nowy obraz jest generowany. Możesz ustawić obserwatora, aby monitorował to i przetwarzał obraz - zostawiam cię do pracy, która zabija sama!

+0

Dzięki !! .. to dobry pomysł .. i rozwiązać za pomocą ffmpeg, ale wa coś natywną do iOS SDK .. postaram swój pomysł – matiasfh

+0

o pierwszej części, czy masz jakiś pomysł, jak to zrobić asynchronicznie? – bluezald

+2

@BacalsoVincent nie zrobiłbyś pierwszego sposobu, jeśli potrzebujesz go asynchronicznie ... jeśli chcesz tylko jeden obraz, ale asynch, użyj drugiej metody z tablicą tylko raz :) – h4xxr

3

Swift 2 Kod podjąć ramek z AVAssetImageGenerator:

func previewImageForLocalVideo(url:NSURL) -> UIImage? 
{ 
    let asset = AVAsset(URL: url) 
    let imageGenerator = AVAssetImageGenerator(asset: asset) 
    imageGenerator.appliesPreferredTrackTransform = true 

    var time = asset.duration 
    //If possible - take not the first frame (it could be completely black or white on camara's videos) 
    time.value = min(time.value, 2) 

    do { 
     let imageRef = try imageGenerator.copyCGImageAtTime(time, actualTime: nil) 
     return UIImage(CGImage: imageRef) 
    } 
    catch let error as NSError 
    { 
     print("Image generation failed with error \(error)") 
     return nil 
    } 
} 
0

w Swift 4 to pracował dla mnie z pewnymi modyfikacjami, głównie zmiany "na" parametr imageGenerator.copyCGImage do typu CMTime:

func showFrame(from file:String) { 
    let file = file.components(separatedBy: ".") 
    guard let path = Bundle.main.path(forResource: file[0], ofType:file[1]) else { 
     debugPrint("\(file.joined(separator: ".")) not found") 
     return 
    } 
    let url = URL(fileURLWithPath: path) 
    let image = previewImageForLocalVideo(url: url) 
    let imgView = UIImageView(image: image) 
    view.addSubview(imgView) 
}  

func previewImageForLocalVideo(url:URL) -> UIImage? { 
    let asset = AVAsset(url: url) 
    let imageGenerator = AVAssetImageGenerator(asset: asset) 
    imageGenerator.appliesPreferredTrackTransform = true 
    let tVal = NSValue(time: CMTimeMake(12, 1)) as! CMTime 
    do { 
     let imageRef = try imageGenerator.copyCGImage(at: tVal, actualTime: nil) 
     return UIImage(cgImage: imageRef) 
    } 
    catch let error as NSError 
    { 
     print("Image generation failed with error \(error)") 
     return nil 
    } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    showFrame(from:"video.mp4") 
} 

Source