#iphone #ios #avfoundation
#iPhone #iOS #avfoundation
Вопрос:
Я пишу приложение, которое работает с видео, используя AVFoundation.
Поведение моего приложения простое: я беру видео с фотопленки, затем создаю изменяемую композицию с несколькими звуковыми дорожками. С помощью mix composition я инициализирую AVAssetExportSession, который сохраняет видеофайл в каталоге documents моего приложения.
До этого момента все было в порядке: мое видео сохранено, и я могу воспроизвести его на другом контроллере. Если я возьму видео, которое я только что сохранил в своей папке documents, для некоторого редактирования (таким же образом, как в первый раз AVMutableComposition, AVAssetExportSession), все снова будет в порядке.
Но в третий раз, когда я выполняю этот процесс для редактирования видео, статус AVAssetExportSession становится «Сбой» и с этой ошибкой:
"Domain=AVFoundationErrorDomain Code=-11820 "Cannot Complete Export" UserInfo=0x1a9260 {NSLocalizedRecoverySuggestion=Try exporting again., NSLocalizedDescription=Cannot Complete Export}"
Я прочитал, что это общая ошибка, из-за которой сеанс не удалось экспортировать. В чем смысл этого? Почему я произвел процесс редактирования только в третий раз? Может ли это быть ошибкой управления памятью? Ошибка?. Это код моей AVAssetExportSession:
_assetExport = [[AVAssetExportSession alloc] initWithAsset:mixComposition presetName:AVAssetExportPresetHighestQuality];
_assetExport.shouldOptimizeForNetworkUse = YES;
///data odierna
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"ddMMyyyyHHmmss"];
NSDate *now = [[NSDate alloc] init];
NSString *dateString = [format stringFromDate:now];
[now release];
[format release];
NSString* ext = @".MOV";
NSString* videoName=[NSString stringWithFormat:@"%@%@", dateString, ext];
///data odierna
NSString *exportPath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:videoName];
if ([[NSFileManager defaultManager] fileExistsAtPath:exportPath])
{
[[NSFileManager defaultManager] removeItemAtPath:exportPath error:nil];
}
_assetExport.outputFileType = AVFileTypeQuickTimeMovie;
[_assetExport setTimeRange:CMTimeRangeMake(kCMTimeZero, videoAsset.duration)];
NSURL *exportUrl = [NSURL fileURLWithPath:exportPath] ;
_assetExport.outputURL = exportUrl ;
[_assetExport exportAsynchronouslyWithCompletionHandler:^
{
switch (_assetExport.status)
{
case AVAssetExportSessionStatusFailed:
{
NSLog (@"FAIL %@",_assetExport.error);
if ([[NSFileManager defaultManager] fileExistsAtPath:[_assetExport.outputURL path]])
{
[[NSFileManager defaultManager] removeItemAtPath:[_assetExport.outputURL path] error:nil];
}
[self performSelectorOnMainThread:@selector (ritenta)
withObject:nil
waitUntilDone:NO];
break;
}
case AVAssetExportSessionStatusCompleted:
{
NSLog (@"SUCCESS");
[self performSelectorOnMainThread:@selector (saveVideoToAlbum:)
withObject:exportPath
waitUntilDone:NO];
break;
}
case AVAssetExportSessionStatusCancelled:
{
NSLog (@"CANCELED");
break;
}
};
}];
Я выполнил множество поисковых запросов в Интернете, у некоторых людей возникла проблема с outputURL сеанса, но я попробовал, и, похоже, в моем коде все в порядке. Чтобы присвоить файлу уникальное имя, я использую NSDate. В целях отладки я попытался восстановить стандартное строковое имя, но проблема остается. Есть идеи? Может ли кто-нибудь предложить мне альтернативный метод для экспорта в папку documents актива с AssetWriter, установленного в AVAssetExportSession?
Комментарии:
1. Экспортер часто терпит неудачу, когда вы не предоставляете правильную AVMutableComposition, поэтому отлаживайте объекты AVMutableComposition в третий раз.
2. Вы на симуляторе? Я получаю ошибку на симуляторе, но на реальном устройстве она выполняется успешно
Ответ №1:
Проблема в том, что _assetExport.outputFileType
вы установили тип AVFileTypeQuickTimeMovie
. Который, скорее всего, не будет поддерживаться типом.
Попробуйте выяснить, какие типы выходных файлов поддерживаются _assetExport, используя следующий код, и используйте подходящий.
NSLog (@"created exporter. supportedFileTypes: %@", exporter.supportedFileTypes);
или
просто измените
_assetExport.outputFileType = AVFileTypeQuickTimeMovie;
Для
exporter.outputFileType = @"com.apple.m4a-audio";
Также не забудьте изменить расширение с
NSString* ext = @".MOV"; to @".m4a"
Это должно сработать. У меня это сработало.