finishWritingWithCompletionHandler can't callback

i get a cvpixelbuffer from arframe,and then use AVAssetWriter to turn buffer to a video which is .mov type.
But on iphone12mini nad iphone12promax ,finishWritingWithCompletionHandler can't callback and have an error like this:

NSLocalizedDescription = "Cannot Encode";
NSLocalizedFailureReason = "The encoder required for this media is busy.";
NSLocalizedRecoverySuggestion = "Stop any other actions that encode media and try again.";
NSUnderlyingError = "Error Domain=NSOSStatusErrorDomain Code=-12915 \"The operation couldn\U2019t be completed. (OSStatus error -12915.)\"";
Answered by Onion_Shen in 652483022
just one,but i make the process in another thread

my code is just this:

Code Block
- (BOOL)saveVideo
{
if (!self.videoPath self.videoPath.length == 0 !self.buffer) {
return NO;
}
NSURL *url = [NSURL fileURLWithPath:self.videoPath];
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:url fileType:AVFileTypeQuickTimeMovie error:&error];
if (error) {
Log(@"%s error = %@",PRETTY_FUNCTION,error);
return NO;
}
NSDictionary *videoSetting = @{
AVVideoCodecKey:AVVideoCodecTypeH264,
AVVideoWidthKey:@(CVPixelBufferGetWidth(self.buffer)),
AVVideoHeightKey:@(CVPixelBufferGetHeight(self.buffer))
};
AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSetting];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:writerInput sourcePixelBufferAttributes:nil];
if (![videoWriter canAddInput:writerInput]) {
return NO;
}
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CMTime presentTime = CMTimeMake(0, 600);
while (1) {
if ([writerInput isReadyForMoreMediaData]) {
[adaptor appendPixelBuffer:self.buffer withPresentationTime:presentTime];
[writerInput markAsFinished];
block BOOL isFinish = NO;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[videoWriter finishWritingWithCompletionHandler:^{
isFinish = YES;
dispatch_semaphore_signal(semaphore);
}];
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 2.0f * NSEC_PER_SEC);
dispatch_semaphore_wait(semaphore, time);
if (!isFinish) {
Log(@"%s create video error",PRETTY_FUNCTION__);
}
break;
}
}
return YES;
}

How many video tracks are you trying to encode at once?
Accepted Answer
just one,but i make the process in another thread

my code is just this:

Code Block
- (BOOL)saveVideo
{
if (!self.videoPath self.videoPath.length == 0 !self.buffer) {
return NO;
}
NSURL *url = [NSURL fileURLWithPath:self.videoPath];
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:url fileType:AVFileTypeQuickTimeMovie error:&error];
if (error) {
Log(@"%s error = %@",PRETTY_FUNCTION,error);
return NO;
}
NSDictionary *videoSetting = @{
AVVideoCodecKey:AVVideoCodecTypeH264,
AVVideoWidthKey:@(CVPixelBufferGetWidth(self.buffer)),
AVVideoHeightKey:@(CVPixelBufferGetHeight(self.buffer))
};
AVAssetWriterInput *writerInput = [[AVAssetWriterInput alloc] initWithMediaType:AVMediaTypeVideo outputSettings:videoSetting];
AVAssetWriterInputPixelBufferAdaptor *adaptor = [[AVAssetWriterInputPixelBufferAdaptor alloc] initWithAssetWriterInput:writerInput sourcePixelBufferAttributes:nil];
if (![videoWriter canAddInput:writerInput]) {
return NO;
}
[videoWriter addInput:writerInput];
[videoWriter startWriting];
[videoWriter startSessionAtSourceTime:kCMTimeZero];
CMTime presentTime = CMTimeMake(0, 600);
while (1) {
if ([writerInput isReadyForMoreMediaData]) {
[adaptor appendPixelBuffer:self.buffer withPresentationTime:presentTime];
[writerInput markAsFinished];
block BOOL isFinish = NO;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[videoWriter finishWritingWithCompletionHandler:^{
isFinish = YES;
dispatch_semaphore_signal(semaphore);
}];
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 2.0f * NSEC_PER_SEC);
dispatch_semaphore_wait(semaphore, time);
if (!isFinish) {
Log(@"%s create video error",PRETTY_FUNCTION__);
}
break;
}
}
return YES;
}

That looks straightforward. When you get this error, are there any other apps on the phone doing media-related work?
no, just my app
i call the saveVideo function use dispatchasync which in a serial queue,the dispatchsemaphore_wait will call due to timeout,and the status of videoWriter is AVAssetWriterStatusWriting
finishWritingWithCompletionHandler can't callback
 
 
Q