Objective-C:使用NSData从电影中获取PNG缩略图 [英] Objective-C: Getting PNG Thumbnail from Movie with NSData

查看:309
本文介绍了Objective-C:使用NSData从电影中获取PNG缩略图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码尝试从NSData获取视频文件的屏幕截图。我可以确认NSData是有效的而不是nil,但dataString和movieURL都返回nil。

I have the following code to attempt to get a screenshot of a video file from NSData. I can confirm the NSData is valid and not nil, however both dataString and movieURL are returning nil.

- (UIImage *)imageFromMovie:(NSData *)movieData {

    // set up the movie player
    NSString *dataString = [[NSString alloc] initWithData:movieData encoding:NSUTF8StringEncoding];
    NSURL *movieURL = [NSURL URLWithString:dataString];

    // get the thumbnail
    AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:movieURL options:nil];
    AVAssetImageGenerator *generate1 = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
    generate1.appliesPreferredTrackTransform = YES;
    NSError *err = NULL;
    CMTime time = CMTimeMake(1, 2);
    CGImageRef oneRef = [generate1 copyCGImageAtTime:time actualTime:NULL error:&err];
    UIImage *one = [[UIImage alloc] initWithCGImage:oneRef];

    return(one);

}

编辑:这是一个看看在哪里/如何从UIImagePicker获取NSData

Here's a look at where/how I'm getting the NSData from the UIImagePicker

if ([mediaType isEqualToString:@"ALAssetTypeVideo"]) {

    ALAssetsLibrary *assetLibrary=[[ALAssetsLibrary alloc] init];
    [assetLibrary assetForURL:[[info objectAtIndex:x] valueForKey:UIImagePickerControllerReferenceURL] resultBlock:^(ALAsset *asset) {

    ALAssetRepresentation *rep = [asset defaultRepresentation];

        unsigned long DataSize = (unsigned long)[rep size];
    Byte *buffer = (Byte*)malloc(DataSize);
        NSUInteger buffered = [rep getBytes:buffer fromOffset:0.0 length:DataSize error:nil];

    //here’s the NSData
    NSData *data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:YES];



    } failureBlock:^(NSError *err) {
             NSLog(@"Error: %@",[err localizedDescription]);
        }];
}


推荐答案

在阅读之前下载我的示例项目答案来自:

Download my sample project before reading this answer from:

https:// drive.google.com/open?id=0B_exgT43OZJOWl9HMDJCR0cyTW8

我知道你发布这个问题已经很久了;但是,我发现它,可以回答它,而且我有理由相信,除非你使用Apple Developer Connection网站提供的样本代码来做你所要求的,你仍然需要回答。我完全基于这个事实:很难弄明白。

I know it's been a really long time since you posted this question; but, I found it, can answer it, and am reasonably confident that, unless you used the sample code provided by the Apple Developer Connection web site that does what you're asking, you still need answer. I base that solely on this fact: it's hard to figure out.

尽管如此,我还有一个基本的,有效的项目来解决你的问题;但是,在查看之前,请查看我在iPhone 6s Plus上运行的视频:

Nonetheless, I have a basic, working project that addresses your question; however, before looking at it, check out a video I made of it running on my iPhone 6s Plus:

<iframe width="640" height="360" src="https://www.youtube.com/embed/GiF-FFKvy5M?rel=0&amp;controls=0&amp;showinfo=0" frameborder="0" allowfullscreen></iframe>

如您所见,我的iPhone视频集中每个资产的海报框都显示在UICollectionViewCell中;在UICollectionViewController(或UICollectionView / datasource委托:

As you can see, the poster frame for every asset in my iPhone's video collection is displayed in UICollectionViewCell; in the UICollectionViewController (or the UICollectionView / datasource delegate:

void (^renderThumbnail)(NSIndexPath *, CustomCell *) = ^(NSIndexPath *indexPath, CustomCell *cell) {
[[PHImageManager defaultManager] requestAVAssetForVideo:AppDelegate.assetsFetchResults[indexPath.section] options:nil resultHandler:^(AVAsset * _Nullable asset, AVAudioMix * _Nullable audioMix, NSDictionary * _Nullable info) {
    cell.asset = [asset copy];
    cell.frameTime = [NSValue valueWithCMTime:kCMTimeZero];
}];
};

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    PHAsset *phAsset = AppDelegate.assetsFetchResults[indexPath.section];
    CustomCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellReuseIdentifier forIndexPath:indexPath];
    cell.representedAssetIdentifier = phAsset.localIdentifier;
    CGFloat hue = (CGFloat)indexPath.section / 5;
    cell.backgroundColor = [UIColor colorWithHue:hue saturation:1.0f brightness:0.5f alpha:1.0f];

    if ([cell.representedAssetIdentifier isEqualToString:phAsset.localIdentifier]) {
        NSPurgeableData *data = [self.thumbnailCache objectForKey:phAsset.localIdentifier];
        [data beginContentAccess];
        UIImage *image = [UIImage imageWithData:data];
        if (image != nil) {
            cell.contentView.layer.contents = (__bridge id)image.CGImage;
            NSLog(@"Cached image found");
        } else {
            renderThumbnail(indexPath, cell);
        }
        [data endContentAccess];
        [data discardContentIfPossible];



    }

    // Request an image for the asset from the PHCachingImageManager.
    /*[AppDelegate.imageManager requestImageForAsset:phAsset
     targetSize:cell.contentView.bounds.size
     contentMode:PHImageContentModeAspectFill
     options:nil
     resultHandler:^(UIImage *result, NSDictionary *info) {
     // Set the cell's thumbnail image if it's still showing the same asset.
     if ([cell.representedAssetIdentifier isEqualToString:phAsset.localIdentifier]) {
     cell.thumbnailImage = result;
     }
     }];*/

    return cell;
}

在UICollectionViewCell子类中:

In the UICollectionViewCell subclass:

@implementation CustomCell

- (void)prepareForReuse {
    [super prepareForReuse];
    _asset = nil;
    _frameTime = nil;
    _thumbnailImage = nil;
    [self.contentView.layer setContents:nil];
    [[self contentView] setContentMode:UIViewContentModeScaleAspectFit];
    [[self contentView] setClipsToBounds:YES];
}

- (void)dealloc {

}

- (void)setAsset:(AVAsset *)asset {
    _asset = asset;
}

- (void)setFrameTime:(NSValue *)frameTime {
    _frameTime = frameTime;
    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(concurrentQueue, ^{
        AVAssetImageGenerator *imageGenerator = [AVAssetImageGenerator assetImageGeneratorWithAsset:_asset];
        imageGenerator.appliesPreferredTrackTransform = YES;
        imageGenerator.requestedTimeToleranceAfter = kCMTimeZero;
        imageGenerator.requestedTimeToleranceBefore = kCMTimeZero;
            [imageGenerator generateCGImagesAsynchronouslyForTimes:@[frameTime] completionHandler:^(CMTime requestedTime, CGImageRef  _Nullable image, CMTime actualTime, AVAssetImageGeneratorResult result, NSError * _Nullable error) {
                dispatch_sync(dispatch_get_main_queue(), ^{
                    self.thumbnailImage = [UIImage imageWithCGImage:image scale:25.0 orientation:UIImageOrientationUp];
                });
            }];
    });
}

- (void)setThumbnailImage:(UIImage *)thumbnailImage {
    _thumbnailImage = thumbnailImage;
    self.contentView.layer.contents = (__bridge id)_thumbnailImage.CGImage;
}

@end

NSCache设置如下这个:

The NSCache is set up like this:

self.thumbnailCache = [[NSCache alloc] init];
    self.thumbnailCache.name = @"Thumbnail Cache";
    self.thumbnailCache.delegate = self;
    self.thumbnailCache.evictsObjectsWithDiscardedContent = true;
    self.thumbnailCache.countLimit = AppDelegate.assetsFetchResults.count;

以这种方式获得PHAssets:

The PHAssets were acquired this way:

- (PHFetchResult *)assetsFetchResults {
    __block PHFetchResult *i = self->_assetsFetchResults;
    if (!i) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeSmartAlbumVideos options:nil];
            self->_assetCollection = smartAlbums.firstObject;
            if (![self->_assetCollection isKindOfClass:[PHAssetCollection class]]) self->_assetCollection = nil;
            PHFetchOptions *allPhotosOptions = [[PHFetchOptions alloc] init];
            allPhotosOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
            i = [PHAsset fetchAssetsInAssetCollection:self->_assetCollection options:allPhotosOptions];
            self->_assetsFetchResults = i;
        });
    }

    return i;
}

这篇关于Objective-C:使用NSData从电影中获取PNG缩略图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆