Как я могу захватить изображение, когда AVPlayer воспроизводит поток m3u8?

Я использую AVPlayer для воспроизведения файла m3u8 и хочу захватить изображение в этом коде:

AVAssetImageGenerator *gen = [[AVAssetImageGenerator alloc] initWithAsset:self.player.currentItem.asset];
gen.appliesPreferredTrackTransform = YES;
NSError *error = nil;
CMTime actualTime;
CMTime now = self.player.currentTime;
[gen setRequestedTimeToleranceAfter:kCMTimeZero];
[gen setRequestedTimeToleranceBefore:kCMTimeZero];
CGImageRef image = [gen copyCGImageAtTime:now actualTime:&actualTime error:&error];
UIImage *thumb = [[UIImage alloc] initWithCGImage:image];
NSLog(@"%f , %f",CMTimeGetSeconds(now),CMTimeGetSeconds(actualTime));

NSLog(@"%@",error);
if (image) {
    CFRelease(image);
}

Но это не работает. И ошибка:

Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo=0x7fadf25f59f0 {NSUnderlyingError=0x7fadf25f1670 "The operation couldn’t be completed. (OSStatus error -12782.)", NSLocalizedFailureReason=An unknown error occurred (-12782), NSLocalizedDescription=The operation could not be completed}

Как я могу решить эту проблему?
Большое спасибо.


person pxiaofu    schedule 02.04.2015    source источник


Ответы (3)


AVAssetImageGenerator могут потребоваться местные активы. Возможно, вам повезет больше, если вы добавите AVPlayerItemVideoOutput к AVPlayer, ищете нужное место и вызываете copyPixelBufferForItemTime:itemTimeForDisplay: на видеовыходе.

person Rhythmic Fistman    schedule 03.04.2015

Я решил ту же проблему с вами, используя следующий код.

Вы можете использовать этот код:

Характеристики

@property (strong, nonatomic) AVPlayer *player;
@property (strong, nonatomic) AVPlayerItem *playerItem;
@property (strong, nonatomic) AVPlayerItemVideoOutput *videoOutput;

Исходный

AVURLAsset *asset = [AVURLAsset URLAssetWithURL:url options:nil];
self.playerItem = [AVPlayerItem playerItemWithAsset:asset];
self.player = [AVPlayer playerWithPlayerItem:_playerItem];

Получение изображения

CMTime currentTime = _player.currentItem.currentTime;
CVPixelBufferRef buffer = [_videoOutput copyPixelBufferForItemTime:currentTime itemTimeForDisplay:nil];
CIImage *ciImage = [CIImage imageWithCVPixelBuffer:buffer];
UIImage *image = [UIImage imageWithCIImage:ciImage];
//Use image^^
person hooni    schedule 17.02.2017
comment
как вы инициализируете videoOutput? - person AntonijoDev; 21.08.2017

Чтобы захватить изображение из avplayer видео HLS:

private let videoOutput = AVPlayerItemVideoOutput(pixelBufferAttributes: [String(kCVPixelBufferPixelFormatTypeKey): NSNumber(value: kCVPixelFormatType_32BGRA)])

private let jpegCompressionQuality = 0.7

private func imageFromCurrentPlayerContext() {
    guard let player = player else { return }
    let currentTime: CMTime = player.currentTime()

    guard let buffer: CVPixelBuffer = videoOutput.copyPixelBuffer(forItemTime: currentTime, itemTimeForDisplay: nil) else { return }
    let ciImage: CIImage = CIImage(cvPixelBuffer: buffer)
    let context: CIContext = CIContext.init(options: nil)

    guard let cgImage: CGImage = context.createCGImage(ciImage, from: ciImage.extent) else { return }
    let image: UIImage = UIImage.init(cgImage: cgImage)

    guard let jpegImage: Data = UIImageJPEGRepresentation(image, jpegCompressionQuality) else { return }
    // be happy
}
person Felipe Kimio    schedule 06.12.2018
comment
Не могли бы вы объяснить, как объект вывода видео узнает, с каким проигрывателем или элементом проигрывателя работать? - person Shaked Sayag; 07.02.2019