iphone SDK > 3.0 .视频缩略图?

Posted

技术标签:

【中文标题】iphone SDK > 3.0 .视频缩略图?【英文标题】:iphone sdk > 3.0 . Video Thumbnail? 【发布时间】:2009-08-11 09:30:47 【问题描述】:

从我读到的内容来看,苹果不会公开 api 以允许开发人员使用当前的 sdk 获取电影的缩略图。

任何人都可以分享一些关于他们如何处理的代码吗? 我听说您可以在 ui 图像选择器关闭之前访问相机选择器视图并找到图像视图。这看起来有点丑。

我还考虑使用 ffmpeg 从电影中抓取一帧,但不知道如何将其编译为 iphone 的库。任何指针将不胜感激

【问题讨论】:

【参考方案1】:

希望我的代码可以帮助到你们。它很丑。我认为苹果应该开放这种 API。 当然,所有的 NSLog() 都应该被删除。只是为了演示。

阿尔文

- (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 ...

【讨论】:

致 Rahul Vyas,该代码已在我的项目中使用,并且运行良好。 将 contextInfo 转换为 NSString:(NSString*)contextInfo 除非我遗漏了什么,这看起来取决于将视频添加到用户的库中(这可能并不适合所有人)。【参考方案2】:

在与电影相同的文件夹中有一个 jpg 作为缩略图。我只用手机录制的视频对其进行了测试,但效果很好。它的名称与电影不同,因此获取电影所在的目录路径并迭代为 .jpg 即可。

【讨论】:

让我知道结果如何。如果您有任何麻烦,我可以发布一些代码来为您完成。刚刚在我们的应用中实现了这个,所以我知道它有效。 好的,对于那些修补这个的人来说还有另一个细节。在我们的表单中,用户可以取消并选择另一张图片。它实际上将 .MOV 和 .jpg 添加到同一个 tmp 目录,这会破坏我的上述建议,因为它不会将正确的 jpg 映射到正确的 .MOV。可能有更清洁的方法,但我通过查看文件夹中所有 jpg 的 NSFileModificationDate 并使用最新的来修复它。 对不起,我的意思是“取消并选择另一部电影”。【参考方案3】:

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

【讨论】:

这个。只需创建一个 MPMoviePlayerController 实例并使用它从回调中的路径中获取缩略图,无论是从库中还是从您刚刚录制的视频中。工作正常。 这种方法是最好的,毫无疑问。但是可从 ios 3.2 及更高版本中使用。因此,如果您想在您的应用程序上支持较旧的 iOS。您将需要使用其他方法。 重要提示... MPMoviePlayerController 似乎在初始化后自动播放。确保在创建后明确停止它,否则如果扬声器未静音,用户会听到扬声器发出的声音。 我在使用这种方法时遇到的一个问题是,即使我在本地录制视频,但在我制作播放器后,持续时间设置为 0。似乎我必须等待持续时间更改的回调,才能获得缩略图,因为我想要最后一帧的缩略图。【参考方案4】:
NSString *videoLink=[info objectForKey:@"UIImagePickerControllerMediaURL"];

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

【讨论】:

【参考方案5】:

这是一篇关于使用 ffmpeg 从电影中提取帧的博文:

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

github上对应项目:iFrameExtractor

【讨论】:

【参考方案6】:

只是想提供有关此的更新。当您将选择器设置为 UIImagePickerControllerSourceTypeCamera 时,事情似乎在获取缩略图方面起作用。但是,当您尝试从现有库(即 UIImagePickerControllerSourceTypePhotoLibrary)中进行选择时 缩略图的 .jpg 永远不会被创建。我什至尝试使用 UISaveVideoAtPathToSavedPhotosAlbum(... ) 重新保存,但仍然没有骰子。似乎在捕获视频时首先创建了缩略图。这是你“抓住”它的唯一机会。之后它被移动到 /var/mobile/Media/DCIM/ 的子目录中。虽然您实际上可以列出缩略图并看到它在那里,但该文件是不可读且不可复制的,因为我相信该目录受到保护。

如果有人对此有解决方法,我将不胜感激,因为在我的情况下,我需要在从库中选择现有视频后获取现有视频的缩略图。

【讨论】:

两种情况都使用 E-Madd 的解决方案【参考方案7】:

如果您使用 UIImagePickerController 获取图像,则 JPG 不会存储在 tmp 目录中。我不确定这个问题的答案,但 ffmpeg,更具体地说是它背后的库,可能是你的选择。

【讨论】:

以上是关于iphone SDK > 3.0 .视频缩略图?的主要内容,如果未能解决你的问题,请参考以下文章

iPhone - 在 3.0 和 4.0 操作系统/SDK 上播放视频?

iPhone SDK 3.0 针对 2.2.1 SDK

在iPhone 3.0 SDK中改变了渐变技巧?

MAP 与 iPhone 3.0 SDK 一起使用都有哪些限制?

除了缩略图方法之外,还有其他方法可以在 Iphone 中截取视频吗?

在 iPhone 3.0 SDK 中为 MoviePlayer 添加自定义控件