// 获取视频第一帧图片
- (UIImage *)videoImageWithvideoURL:(NSURL *)videoURL atTime:(NSTimeInterval)time {
//先从缓存中查找是否有图片
SDImageCache *cache = [SDImageCache sharedImageCache];
UIImage *memoryImage = [cache imageFromMemoryCacheForKey:videoURL.absoluteString];
if (memoryImage) {
return memoryImage;
}else{
//再从磁盘中查找是否有图片
UIImage *diskImage = [cache imageFromDiskCacheForKey:videoURL.absoluteString];
if (diskImage) {
return diskImage;
}
}
if (!time) {
time = 1; //默认去出第一帧
}
//如果都不存在,开启异步线程截取对应时间点的画面,转成图片缓存至磁盘
//开启信号量用于加锁
dispatch_semaphore_t signal = dispatch_semaphore_create(0);
//局部变量准备赋值
__block UIImage *image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
NSParameterAssert(asset);
AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
assetImageGenerator.appliesPreferredTrackTransform = YES;
assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
CGImageRef thumbnailImageRef = NULL;
CFTimeInterval thumbnailImageTime = time;
NSError *thumbnailImageGenerationError = nil;
thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
if(!thumbnailImageRef)
NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
image = thumbnailImage;
dispatch_async(dispatch_get_main_queue(), ^{
SDImageCache * cache = [SDImageCache sharedImageCache];
//保存至缓存
[cache storeImage:thumbnailImage forKey:videoURL.absoluteString toDisk:YES completion:nil];
});
//完成后解锁
dispatch_semaphore_signal(signal);
});
//等待解锁,解锁后才执行下一步
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
return image;
}
-
获取到了一个视频的URL,获取视频的第一帧,
-
如果图片存在缓存,则直接使用缓存,没有缓存则去出图片后保存到缓存
-
但是我这出现了个问题:就是加锁后 单元格 在显示图片的时候没有缓存是加载数据会很慢大概有2-3秒的等待,可能数据比较少如果数据多的话就更慢了,所以把锁给去掉了
-
这个是在Cell里直接写的
_dynamicImageView
就是cell中需要赋值的视图
- (void)videoImageWithvideoURL:(NSURL *)videoURL atTime:(NSTimeInterval)time {
//先从缓存中查找是否有图片
SDImageCache *cache = [SDImageCache sharedImageCache];
UIImage *memoryImage = [cache imageFromMemoryCacheForKey:videoURL.absoluteString];
if (memoryImage) {
// [self setBackgroundImage:memoryImage forState:UIControlStateNormal];
_dynamicImageView.image = memoryImage;
return;
}else{
//再从磁盘中查找是否有图片
UIImage *diskImage = [cache imageFromDiskCacheForKey:videoURL.absoluteString];
if (diskImage) {
// [self setBackgroundImage:diskImage forState:UIControlStateNormal];
_dynamicImageView.image = diskImage;
return;
}
}
if (!time) {
time = 1;
}
//如果都不存在,开启异步线程截取对应时间点的画面,转成图片缓存至磁盘
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
NSParameterAssert(asset);
AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
assetImageGenerator.appliesPreferredTrackTransform = YES;
assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
CGImageRef thumbnailImageRef = NULL;
CFTimeInterval thumbnailImageTime = time;
NSError *thumbnailImageGenerationError = nil;
thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
if(!thumbnailImageRef)
NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
UIImage*thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
dispatch_async(dispatch_get_main_queue(), ^{
SDImageCache * cache = [SDImageCache sharedImageCache];
[cache storeImage:thumbnailImage forKey:videoURL.absoluteString toDisk:YES completion:nil];
// [self setBackgroundImage:thumbnailImage forState:UIControlStateNormal];
self->_dynamicImageView.image = thumbnailImage;
});
});
}
- 这个是去掉了锁
// 获取视频第一帧
- (UIImage *)videoImageWithvideoURL:(NSURL *)videoURL atTime:(NSTimeInterval)time {
//先从缓存中查找是否有图片
SDImageCache *cache = [SDImageCache sharedImageCache];
UIImage *memoryImage = [cache imageFromMemoryCacheForKey:videoURL.absoluteString];
if (memoryImage) {
// [_contentBtn setBackgroundImage:memoryImage forState:UIControlStateNormal];
return memoryImage;
}else{
//再从磁盘中查找是否有图片
UIImage *diskImage = [cache imageFromDiskCacheForKey:videoURL.absoluteString];
if (diskImage) {
// [_contentBtn setBackgroundImage:diskImage forState:UIControlStateNormal];
return diskImage;
}
}
if (!time) {
time = 1;
}
//如果都不存在,开启异步线程截取对应时间点的画面,转成图片缓存至磁盘
// __weak typeof (_contentBtn) weakContentBtn = _contentBtn;
// dispatch_semaphore_t signal = dispatch_semaphore_create(0);
__block UIImage *image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
NSParameterAssert(asset);
AVAssetImageGenerator *assetImageGenerator =[[AVAssetImageGenerator alloc] initWithAsset:asset];
assetImageGenerator.appliesPreferredTrackTransform = YES;
assetImageGenerator.apertureMode = AVAssetImageGeneratorApertureModeEncodedPixels;
CGImageRef thumbnailImageRef = NULL;
CFTimeInterval thumbnailImageTime = time;
NSError *thumbnailImageGenerationError = nil;
thumbnailImageRef = [assetImageGenerator copyCGImageAtTime:CMTimeMake(thumbnailImageTime, 60)actualTime:NULL error:&thumbnailImageGenerationError];
if(!thumbnailImageRef)
NSLog(@"thumbnailImageGenerationError %@",thumbnailImageGenerationError);
UIImage *thumbnailImage = thumbnailImageRef ? [[UIImage alloc]initWithCGImage: thumbnailImageRef] : nil;
image = thumbnailImage;
dispatch_async(dispatch_get_main_queue(), ^{
SDImageCache * cache = [SDImageCache sharedImageCache];
[cache storeImage:thumbnailImage forKey:videoURL.absoluteString toDisk:YES completion:nil];
// [weakContentBtn setBackgroundImage:thumbnailImage forState:UIControlStateNormal];
});
// dispatch_semaphore_signal(signal);
});
// dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER);
return image;
}
- 所以这个锁的问题,我理解应该是可以不用加的以为没有其他线程同时去访问这个资源。去掉锁后速度会快很多。