简体   繁体   中英

iphone sdk > 3.0 . Video Thumbnail?

From what i have read apple doesnt expose the api to allow developers to get a thumbnail of a movie using the current sdk.

Can any one share some code as to how they are going about this? I have heard you can access the camera picker view and find the image view just before the ui image picker is closed. This seems kinda ugly.

Also ive considered using ffmpeg to grab a frame out of the movie but wouldnt hava a clue as to how to compile it as a library for the iphone. Any pointers would be greatly appreciated

Hope my code could help you guys. It's ugly. I think apple should open this kind of APIs. Of course, all NSLog() should be removed. It's just for demonstration.

alvin

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
 // e.g.
 NSString *tempFilePath = [(NSURL *)[info valueForKey:UIImagePickerControllerMediaURL] absoluteString];
 NSLog(@"didFinishPickingMediaWithInfo: %@",tempFilePath);
 // e.g. /private/var/mobile/Applications/D1E784A4-EC1A-402B-81BF-F36D3A08A332/tmp/capture/capturedvideo.MOV
 tempFilePath = [[tempFilePath substringFromIndex:16] retain];
 NSLog(@"didFinishPickingMediaWithInfo: %@",tempFilePath);
 NSLog(@"===Try to save video to camera roll.===");
 NSLog(@"UIVideoAtPathIsCompatibleWithSavedPhotosAlbum: %@",UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath)? @"YES":@"NO");
 // Check if the video file can be saved to camera roll.
    if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath)){
  // YES. Copy it to the camera roll.
  UISaveVideoAtPathToSavedPhotosAlbum(tempFilePath, self, @selector(video:didFinishSavingWithError:contextInfo:), tempFilePath);
 }

 [self dismissModalViewControllerAnimated:YES];
}

- (void)video:(NSString *)videoPath didFinishSavingWithError:(NSError *)error contextInfo:(NSString *)contextInfo{
 NSLog(@"didFinishSavingWithError--videoPath in camera roll:%@",videoPath);
 NSLog(@"didFinishSavingWithError--videoPath in temp directory:%@",contextInfo);
 // The thumbnail jpg should located in this directory.
 NSString *thumbnailDirectory = [[contextInfo stringByDeletingLastPathComponent] stringByDeletingLastPathComponent];

 // Debug info. list all files in the directory of the video file.
 // e.g. /private/var/mobile/Applications/D1E784A4-EC1A-402B-81BF-F36D3A08A332/tmp/capture
 NSLog([contextInfo stringByDeletingLastPathComponent]);
 NSLog([[[NSFileManager defaultManager] contentsOfDirectoryAtPath:[contextInfo stringByDeletingLastPathComponent] error:nil] description]);
 // Debug info. list all files in the parent directory of the video file, i.e. the "~/tmp" directory.
 // e.g. /private/var/mobile/Applications/D1E784A4-EC1A-402B-81BF-F36D3A08A332/tmp
 NSLog(thumbnailDirectory);
 NSLog([[[NSFileManager defaultManager] contentsOfDirectoryAtPath:thumbnailDirectory error:nil] description]);
 ///////////////////

 // Find the thumbnail for the video just recorded.
 NSString *file,*latestFile;
 NSDate *latestDate = [NSDate distantPast];
 NSDirectoryEnumerator *dirEnum = [[NSFileManager defaultManager] enumeratorAtPath:[[contextInfo stringByDeletingLastPathComponent]stringByDeletingLastPathComponent]];
 // Enumerate all files in the ~/tmp directory
 while (file = [dirEnum nextObject]) {
  // Only check files with jpg extension.
  if ([[file pathExtension] isEqualToString: @"jpg"]) {
   NSLog(@"***latestDate:%@",latestDate);
   NSLog(@"***file name:%@",file);
   NSLog(@"***NSFileSize:%@", [[dirEnum fileAttributes] valueForKey:@"NSFileSize"]);
   NSLog(@"***NSFileModificationDate:%@", [[dirEnum fileAttributes] valueForKey:@"NSFileModificationDate"]);
   // Check if current jpg file is the latest one.
   if ([(NSDate *)[[dirEnum fileAttributes] valueForKey:@"NSFileModificationDate"] compare:latestDate] == NSOrderedDescending){
    latestDate = [[dirEnum fileAttributes] valueForKey:@"NSFileModificationDate"];
    latestFile = file;
    NSLog(@"***latestFile changed:%@",latestFile);
   }
  }
 }
 // The thumbnail path.
 latestFile = [NSTemporaryDirectory() stringByAppendingPathComponent:latestFile];
 NSLog(@"****** The thumbnail file should be this one:%@",latestFile);

 // Your code ...
 // Your code ...
 // Your code ...
}

There is a jpg in the same folder as the the movie that is the thumbnail. I have only tested it with video recorded from the phone, but it works fine. Its not named the same as the movie, so get the directory path the movie is in and iterate for a .jpg and away you go.

我找到的最佳方法... MPMoviePlayerController thumbnailImageAtTime:timeOption

NSString *videoLink=[info objectForKey:@"UIImagePickerControllerMediaURL"];

MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:(NSURL*)videoLink];
UIImage *imageSel = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
[player stop];
[player release];

Here's a blog post about extracting frames from movies using ffmpeg:

http://www.codza.com/extracting-frames-from-movies-on-iphone

The corresponding project on github: iFrameExtractor

Just wanted to provide an update on this. Things seem to work in terms of getting the thumbnail when you've set your picker to UIImagePickerControllerSourceTypeCamera. However when you try to pick from the existing library (ie UIImagePickerControllerSourceTypePhotoLibrary) the .jpg for the thumbnail never gets created. I even tried re-saving with UISaveVideoAtPathToSavedPhotosAlbum(... ) and still no dice. It seems like the thumbnail is first created when the video is captured. That is your only opportunity to "grab" it. Afterwards it gets moved into a subdirectory of /var/mobile/Media/DCIM/ . While you can actually list the thumbnail image and see that is there, that file is unreadable and uncopyable as I believe that directory is protected.

If anyone has a workaround for this I would greatly appreciate it as in my case I need to grab the thumbnail of existing video after choosing it from the library.

If your using UIImagePickerController to get the image, then a JPG would not be stored in the tmp directory. I'm not sure of the answer for this, but ffmpeg, more specifically the libraries behind it, may be your option.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM