gpt4 book ai didi

ios - AVFoundation 将第一帧添加到视频

转载 作者:可可西里 更新时间:2023-11-01 05:33:58 24 4
gpt4 key购买 nike

我正在尝试控制由我的应用生成的视频在 iOS 上的照片应用中的显示方式。我制作的所有视频都以黑框开始,然后逐渐淡入和淡出,等等。将这些视频保存到照片时,Apple 会获取第一帧(黑色方 block )并将其用作照片中的缩略图。我想更改此设置,以便我可以设置自己的缩略图,以便人们轻松识别视频。

因为我找不到任何内置的 API,我试图通过添加我生成的缩略图作为视频的第一帧来破解它。我正在尝试为此使用 AVFoundation,但遇到了一些问题。

我的代码抛出以下错误:[AVAssetReaderTrackOutput copyNextSampleBuffer] cannot copy next sample buffer before adding this output to an instance of AVAssetReader (using -addOutput:) and calling -startReading on that asset reader' ,尽管调用了该方法。

这是我的代码:

AVAsset *asset = [[AVURLAsset alloc] initWithURL:fileUrl options:nil];
UIImage *frame = [self generateThumbnail:asset];

NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys:
AVVideoCodecH264, AVVideoCodecKey,
[NSNumber numberWithInt:640], AVVideoWidthKey,
[NSNumber numberWithInt:360], AVVideoHeightKey,
nil];

AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:asset error:nil];
AVAssetReaderOutput *readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:[asset.tracks firstObject]
outputSettings:nil];
[assetReader addOutput:readerOutput];

AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:path
fileType:AVFileTypeMPEG4
error:nil];
NSParameterAssert(videoWriter);

AVAssetWriterInput* writerInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo
outputSettings:videoSettings];

AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor
assetWriterInputPixelBufferAdaptorWithAssetWriterInput:writerInput
sourcePixelBufferAttributes:nil];

NSParameterAssert(writerInput);
NSParameterAssert([videoWriter canAddInput:writerInput]);

[videoWriter addInput:writerInput];

[assetReader startReading];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];

CVPixelBufferRef buffer = [self pixelBufferFromCGImage:frame.CGImage andSize:frame.size];

BOOL append_ok = NO;
while (!append_ok) {
if (adaptor.assetWriterInput.readyForMoreMediaData) {
append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:kCMTimeZero];
CVPixelBufferPoolRef bufferPool = adaptor.pixelBufferPool;
NSParameterAssert(bufferPool != NULL);

[NSThread sleepForTimeInterval:0.05];
} else {
[NSThread sleepForTimeInterval:0.1];
}
}
CVBufferRelease(buffer);

dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
[writerInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock:^{
CMSampleBufferRef nextBuffer;
while (writerInput.readyForMoreMediaData) {
nextBuffer = [readerOutput copyNextSampleBuffer];
if(nextBuffer) {
NSLog(@"Wrote: %zu bytes", CMSampleBufferGetTotalSampleSize(nextBuffer));
[writerInput appendSampleBuffer:nextBuffer];
} else {
[writerInput markAsFinished];
[videoWriter finishWritingWithCompletionHandler:^{
//int res = videoWriter.status;
}];
break;
}
}
}];

我尝试了一些变体,但都无济于事。我也看到过一些由于文件格式而导致的崩溃。我正在使用 mp4 文件(不确定如何找出其压缩状态或是否支持),但即使使用未压缩的 .mov 文件(通过在 Mac 上使用 Photo Booth 制作)我也无法使其工作).

知道我做错了什么吗?

最佳答案

刚遇到同样的问题。

你的 assetReader 在函数结束后被 ARC 释放。但是来自 readerOutput 的 block 读取缓冲区继续尝试读取内容。

当 assetReader 消失时,readerOutput 与它断开连接,因此错误表明您需要将它连接回 assetReader。

解决方法是确保 assetReader 未被释放。例如。通过将它放在一个属性中。

关于ios - AVFoundation 将第一帧添加到视频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27608510/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com