Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 从视频中获取缩略图图像总是返回空值_Iphone_Ios_Objective C_Cocoa Touch_Ios6 - Fatal编程技术网

Iphone 从视频中获取缩略图图像总是返回空值

Iphone 从视频中获取缩略图图像总是返回空值,iphone,ios,objective-c,cocoa-touch,ios6,Iphone,Ios,Objective C,Cocoa Touch,Ios6,我正在尝试从视频中获取第一个缩略图 我尝试了以下方法: 一个 AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil]; AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset]; gen.appliesPreferredTrackTransform =

我正在尝试从视频中获取第一个缩略图

我尝试了以下方法:

一个

AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil];
AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:asset];
gen.appliesPreferredTrackTransform = YES;
CMTime time = CMTimeMakeWithSeconds(0.0, 600);
NSError *error = nil;
CMTime actualTime;

CGImageRef image = [gen copyCGImageAtTime:time actualTime:&actualTime error:&error];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
CGImageRelease(image);
NSLog(@"the error is %@: image is %@: url is %@: ",error,_mainThumbnail,[NSURL fileURLWithPath:_moviePath] );
但是,我的日志是:

the error is (null): image is (null): 
url is file:///private/var/mobile/Applications/D1293BDC-EA7E-4AC7-AD3C-1BA3548F37D6/tmp/trim.6F0C4631-E5E8-43CD-BF32-9B8F09D4ACF1.MOV: 
两个

AVURLAsset *asset=[[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:_moviePath] options:nil];
    AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
    generator.appliesPreferredTrackTransform=TRUE;

    CMTime thumbTime = CMTimeMakeWithSeconds(0,30);

    AVAssetImageGeneratorCompletionHandler handler = ^(CMTime requestedTime, CGImageRef im, CMTime actualTime, AVAssetImageGeneratorResult result, NSError *error){
        if (result != AVAssetImageGeneratorSucceeded) {
            NSLog(@"couldn't generate thumbnail, error:%@", error);
        }
        _mainThumbnail.image = [UIImage imageWithCGImage:im];
        NSLog(@"thumbnails %@ ",_mainThumbnail.image);
    };

    CGSize maxSize = CGSizeMake(320, 180);
    generator.maximumSize = maxSize;
    [generator generateCGImagesAsynchronouslyForTimes:[NSArray arrayWithObject:[NSValue valueWithCMTime:thumbTime]] completionHandler:handler];
日志thumnails为空

为什么图像为空?我查看了其他论坛,他们建议使用fileURLWithPath——我已经在使用它了


我正在使用ios7

我成功地使用了这个片段,从视频中获得了一个屏幕截图:

- (UIImage *)currentItemScreenShot
{
    AVURLAsset *asset = (AVURLAsset *)playerItem_.asset;

    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

    imageGenerator.appliesPreferredTrackTransform = YES;

    CGImageRef thumb = [imageGenerator 
    copyCGImageAtTime:CMTimeMakeWithSeconds(0, 1.0)
    actualTime:NULL
    error:NULL];

    UIImage *image = [UIImage imageWithCGImage:thumb];

    CGImageRelease(thumb);

    [imageGenerator release];

    return image;
}

但是在我的例子中-我在应用程序中成功导入视频两秒钟后进行此操作。(它在图片方向上有问题,如果我在导入视频后执行此操作,有时会返回无图像或半图像)。

您可以尝试此方法。它在给定的URL处获取视频的第一帧,并将其作为
UIImage
返回

- (UIImage *)thumbnailFromVideoAtURL:(NSURL *)url
{
    AVAsset *asset = [AVAsset assetWithURL:url];

    //  Get thumbnail at the very start of the video
    CMTime thumbnailTime = [asset duration];
    thumbnailTime.value = 0;

    //  Get image from the video at the given time
    AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset];

    CGImageRef imageRef = [imageGenerator copyCGImageAtTime:thumbnailTime actualTime:NULL error:NULL];
    UIImage *thumbnail = [UIImage imageWithCGImage:imageRef];
    CGImageRelease(imageRef);

    return thumbnail;
}
该方法不检查错误,因为我使用它的代码没有问题,如果有任何错误,只返回
nil


编辑:澄清
CMTime

CMTime
has

  • 时间刻度
    -将其视为视频的FPS(每秒帧数)(25 FPS->1s视频有25个视频帧)
  • -混凝土框架的标识。在上面的代码中,这表示要对哪个帧进行缩略
要在精确时间计算帧,必须进行以下计算:

value = timescale * seconds_to_skip
这相当于

"Frame of the video to take" = "FPS" * "Number of seconds to skip"
如果你想以视频第二秒的第一帧为例,实际上你想跳过视频的第一秒。因此,您可以使用:

CMTime thumbnailTime = [asset duration];
thumbnailTime.value = thumbnailTime.timescale * 1;

另一种看法:你想跳过视频的前1秒,然后拍一张缩略图。也就是说,在每秒25帧时,您希望跳过25帧。所以
CMTime.value=25
(跳过25帧)。

以防万一有人犯了和我一样的错误:

检查
URL
是否使用适当的方法生成。您不应该因为文件的本地和web
URL
s而获得通知

如果是本地视频文件,请使用以下代码:

NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
如果是来自互联网的视频文件,请使用以下代码:

NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];

Swift接受答案的版本@Lukas Kukacka答案:

func thumbnailFromVideoAtURL(url: URL) -> UIImage?{

        let asset = AVAsset(url: url)

        //  Get thumbnail at the very start of the video
        var thumbnailTime: CMTime = asset.duration
        thumbnailTime.value = 0

        //  Get image from the video at the given time
        let imageGenerator = AVAssetImageGenerator(asset: asset)
        imageGenerator.appliesPreferredTrackTransform = true // this rotates the image to the correct position the camera took it in

        do{
            let imageRef = try imageGenerator.copyCGImage(at: thumbnailTime, actualTime: nil)
            return UIImage(cgImage: imageRef)

        }catch let err as NSError{
            print(err.localizedDescription)
        }

        return nil
}
奖金

下,让imageGenerator=AVAssetImageGenerator(资产:资产
)我添加了:


我有一个问题,我会记录在肖像,得到缩略图像,它会在景观返回。解决了这个问题。

SWIFT 5.2版本:

NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
你可以找到我的原创文章,我从中获得灵感

重要注意事项:

NSURL *movieURL = [NSURL fileURLWithPath:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
NSURL *movieURL = [NSURL URLWithString:_moviePath];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
requestedTimeToleranceAfter和requestedTimeToleranceBefore应设置为.0,因为根据源代码,“生成图像的实际时间[…]可能与效率要求的时间不同”


appliesPreferredTrackTransform必须设置为TRUE(默认值为FALSE),否则会得到错误的旋转帧。当此属性设置为TRUE时,您将获得您在播放机中真正看到的内容。

什么是
\u main缩略图
?您确定这不是
nil
(因为看起来是这样的)?为什么不尝试直接记录
thumb
(在第一个示例中)?在第一个示例中,在我看来好像从未设置过main缩略图。如果我想要第二个呢?我可以试试thumbnailTime.value=1吗?您需要视频的第2秒或第2帧的缩略图吗?为什么需要第二帧?第一个和第二个之间的差异约为0.04s@25FPS:-)但是:CMTime定义了拍摄缩略图的视频时间,而不是确切的帧数。我的代码使用了一个简单的前提,第一帧在时间0;-)所以为了得到特定的帧,你可能需要计算视频的FPS等,但这是一个不同的讨论,我是说第二秒。我是如何得到它的?请看一看这个问题:它比我在评论中给你的内容更详细。基本上,
CMTime
docs说的是“值/时间刻度=秒”。。。因此,如果您设置
thumbnailTime.value=thumbnailTime.timescale*1
(其中1是您要拍摄缩略图的视频的秒数),您应该大约有视频第二秒的第一帧时间(时间00h00m01s)我在这里找到了解决方案,成功导入是什么意思?好吧,在我的例子中,我拍摄了一个视频或从库中选择,然后将此视频导入应用程序(并保存在应用程序缓存目录中)-如果成功保存,则成功导入。可能会出现问题-视频损坏、内存不足或任何其他问题。