IPhone用に開発しているアプリケーションがあります。それは、カメラからビデオをキャプチャし、ビデオファイルをファイルシステムに保存します。
画像をファイルシステムに保存する前に、このビデオファイルのサムネイル画像を作成する必要があります。私の動機は、作成されたビデオのサムネイルのリストを表示して、ユーザーが特定のサムネイルを選択して目的のファイルを再生できるようにすることです。
カメラでキャプチャされたビデオファイルのサムネイル画像を作成する方法について誰かにアドバイスしてもらえますか?.
また、iOSSDKを使用して既存のビデオファイルのサムネイルを作成できるかどうか教えてください。
これを試してください(実際にはムービープレーヤーは表示されません):
+ (UIImage *)imageFromMovie:(NSURL *)movieURL atTime:(NSTimeInterval)time {
// set up the movie player
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc]
initWithContentURL:movieURL];
mp.shouldAutoplay = NO;
mp.initialPlaybackTime = time;
mp.currentPlaybackTime = time;
// get the thumbnail
UIImage *thumbnail = [mp thumbnailImageAtTime:time
timeOption:MPMovieTimeOptionNearestKeyFrame];
// clean up the movie player
[mp stop];
[mp release];
return(thumbnail);
}
同期呼び出しであるはずなので、メインスレッドをブロックする可能性がありますが、映画の冒頭で時間を使うと、すぐに実行されているようです。これを頻繁に行う場合は、UIImageのカテゴリとして追加できます。これは私が行ったことです。
あなたの質問から、ムービーを保存する前にこれを実行したいことがわかりました。ファイルのURLがないと機能しない可能性があります。ただし、カメラキャプチャにUIImagePickerControllerを使用している場合は、この関数に、imagePickerController:didFinishPickingMediaWithInfo:の情報ディクショナリで返されたURLをキーUIImagePickerControllerMediaURLで渡すことができます。
より良い解決策は、実際にはAVFoundationフレームワークを使用してこれを行うことです。これは、MPMoviePlayerControllerを構築する必要性を回避します。これにより、UIImagePickerControllerと組み合わせて使用すると、カメラのアイリスが閉じたままになるという問題が発生します(少なくとも私が経験したことです)。
私が使用するコード:
+ (UIImage *)thumbnailFromVideoAtURL:(NSURL *)contentURL {
UIImage *theImage = nil;
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:contentURL options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
NSError *err = NULL;
CMTime time = CMTimeMake(1, 60);
CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:NULL error:&err];
theImage = [[[UIImage alloc] initWithCGImage:imgRef] autorelease];
CGImageRelease(imgRef);
[asset release];
[generator release];
return theImage;
}
非常に簡単にこれを試してください...
ステップ1:ヘッダーをインポートします#import <MediaPlayer/MediaPlayer.h>
ステップ2:URLパスを取得します
NSURL *videoURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"Sample" ofType:@"m4v"]];
ステップ:最後にサムネイルを取得します
- (UIImage *)VideoThumbNail:(NSURL *)videoURL
{
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
UIImage *thumbnail = [player thumbnailImageAtTime:52.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
[player stop];
return thumbnail;
}
これを試して :
generate.requestedTimeToleranceBefore = kCMTimeZero;
generate.requestedTimeToleranceAfter = kCMTimeZero;
正しいフレームを取得するには、追加する必要があります。
AVFoundation
フレームワークとSwift 3.0を使用するソリューションのコード(コメント付きのコードは必要ありません。コードの下で説明します。必要かどうかを判断する必要があります):
import AVFoundation
func generateThumbnailForVideo(at url: URL) -> UIImage? {
let kPreferredTimescale: Int32 = 1000
let asset = AVURLAsset(url: url)
let generator = AVAssetImageGenerator(asset: asset)
generator.appliesPreferredTrackTransform = true
//generator.requestedTimeToleranceBefore = kCMTimeZero
//generator.requestedTimeToleranceAfter = kCMTimeZero
//generator.maximumSize = CGSize(width: 100, height: 100)
var actualTime: CMTime = CMTime(seconds: 0, preferredTimescale: kPreferredTimescale)
//generates thumbnail at first second of the video
let cgImage = try? generator.copyCGImage(at: CMTime(seconds: 1, preferredTimescale: kPreferredTimescale), actualTime: &actualTime)
return cgImage.flatMap() { return UIImage(cgImage: $0, scale: UIScreen.main.scale, orientation: .up) }
}
サムネイルの作成はコストのかかる操作になる可能性があるため、このコードをバックグラウンドスレッドで実行することを検討してください。
また、AVAssetImageGenerator
クラスのいくつかのプロパティを見てください。
requestedTimeToleranceBefore
( Appleのドキュメント ):画像が生成される可能性のある要求された時間までの最大時間。
デフォルト値はkCMTimePositiveInfinityです。
RequestedTimeToleranceBeforeとrequestedTimeToleranceAfterの値をkCMTimeZeroに設定して、フレーム精度の画像生成を要求します。これにより、追加のデコード遅延が発生する可能性があります。
requestedTimeToleranceAfter
( Appleのドキュメント ):要求された時間の後、画像が生成される可能性のある最大時間。
デフォルト値はkCMTimePositiveInfinityです。
RequestedTimeToleranceBeforeとrequestedTimeToleranceAfterの値をkCMTimeZeroに設定して、フレーム精度の画像生成を要求します。これにより、追加のデコード遅延が発生する可能性があります。
maximumSize
( Appleのドキュメント ):生成された画像の最大サイズを指定します。
デフォルト値はCGSizeZeroで、アセットのスケーリングされていないディメンションを指定します。
AVAssetImageGeneratorは、定義された境界ボックス内に収まるように画像を拡大縮小します。画像が拡大されることはありません。拡大縮小された画像のアスペクト比は、apertureModeプロパティによって定義されます。