web-dev-qa-db-ja.com

iPhone AVFoundationを使用してビデオからUIimage(フレーム)を読み取る

私の英語で申し訳ありません)iPhoneでビデオから読み取ったフレームに関する情報を探している私はこのプロジェクトを見つけました http://www.codza.com/extracting-frames-from-movies-on-iphone/comment-page -1#comment-1116 ですが、AVFoundationを使用してビデオからフレームをキャプチャし、パフォーマンスを向上させることができることもどこかで読みました。

しかし、私はそれをどのように行うことができるかについての情報を見つけることができません...

いくつかのアイデア?

読んでくれてありがとう

21
matiasfh

あなたは、特定の時間にビデオからApple呼び出しサムネイル画像)を生成するための呼び出しを使用することについて話している。

MPMoviePlayerController(iOSがファイルまたは他のソースからのビデオを保持するために使用するもの)の場合、これを行うための2つのコマンドがあります。 1つ目は、特定の時点で映画から1つのサムネイル(画像)を生成し、2つ目は、ある時間範囲のサムネイルのセットを生成します。

この例では、10秒でムービークリップに画像を取得しますmyMovie.mp4

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

これは同期的に実行されることに注意してください。つまり、スクリーンショットを取得する間、ユーザーは待機する必要があります。

もう1つのオプションは、映画から一連の画像を一連の時間から取得することです。

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];

この2番目の方法では、新しい画像が生成されるたびに、タイプMPMoviePlayerThumbnailImageRequestDidFinishNotificationの通知がトリガーされます。これを監視して画像を処理するオブザーバーを設定できます-私はあなたにそのビットを自分で解決することを任せます!

37
h4xxr

AVAssetImageGenerator 、具体的には generateCGImagesAsynchronouslyForTimes:completionHandler を試すこともできます。

This SO answer には良いサンプルコードがあります。

19
Steve

AVAssetImageGeneratorでフレームを取得するためのSwift2コード:

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
    }
}
5
Avt

ビデオからFPS画像を取得するコードは次のとおりです

1)インポート

#import <Photos/Photos.h>

2)viewDidLoad内

    videoUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:@"VfE_html5" ofType:@"mp4"]];
    [self createImage:5]; // 5 is frame per second (FPS) you can change FPS as per your requirement.

3)機能

-(void)createImage:(int)withFPS {
    AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoUrl options:nil];
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    generator.requestedTimeToleranceAfter =  kCMTimeZero;
    generator.requestedTimeToleranceBefore =  kCMTimeZero;

    for (Float64 i = 0; i < CMTimeGetSeconds(asset.duration) *  withFPS ; i++){
        @autoreleasepool {
            CMTime time = CMTimeMake(i, withFPS);
            NSError *err;
            CMTime actualTime;
            CGImageRef image = [generator copyCGImageAtTime:time actualTime:&actualTime error:&err];
            UIImage *generatedImage = [[UIImage alloc] initWithCGImage:image];
            [self savePhotoToAlbum: generatedImage]; // Saves the image on document directory and not memory
            CGImageRelease(image);
        }
    }
}

-(void)savePhotoToAlbum:(UIImage*)imageToSave {

    [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
        PHAssetChangeRequest *changeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:imageToSave];
    } completionHandler:^(BOOL success, NSError *error) {
        if (success) {
            NSLog(@"sucess.");
        }
        else {
            NSLog(@"fail.");
        }
    }];
}
3
Hardik Thakkar