Обработчик завершения не вызывается на iOS7 GM
Я использую AVAssetWriter, и он отлично работает на iOS6.
Проблема в том, когда я позвонил finishWritingWithCompletionHandler
, обработчик завершения не вызывается на iOS7 GM.
я звонил markAsFinished
, и даже endSessionAtSourceTime
прежде чем я вызываю finishWritingWithCompletionHandler.
На iOS6 работает нормально.
И даже более того, на iOS7 он работает несколько раз, а затем снова не работает.
Я не знаю почему, но это работает, если я вызываю метод, используя представление оповещения. Так я попробовал performSelectorOnMainThread
а также inBackground
, но это не помогло.
Есть идеи?
5 ответов
Очевидно, вам нужно сохранить assetWriter сейчас.
Вы можете попробовать сохранить его с сильным свойством и посмотреть, будет ли вызван ваш обработчик завершения. (Обязательно обнуляйте это свойство в обработчике завершения.)
Рэй Фикс, ты прав. Нам нужно сохранить assetWriter. Самый простой способ - использовать его внутри блока finishWritingWithCompletionHandler:
NSError *error = nil;
AVAssetWriter *videoWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:path]
fileType:AVFileType3GPP
error:&error];
//startWriting, session etc.
[videoWriter finishWritingWithCompletionHandler:^{
NSLog(@"%@",videoWriter);
NSLog(@"Write Ended");
}];
Это происходит и в ARC.
Самое простое решение - определить свойства AVAssetWriter(и, как я полагаю, AVAssetReader)
@property(nonatomic,strong) AVAssetWriter *assetWriter;
@property(nonatomic,strong) AVAssetReader *assetReader;
а потом
self.assetWriter = [AVAssetWriter assetWriterWithURL:destURL
fileType:AVFileTypeWAVE
error:&assetError];
и в блоке завершения
[assetWriterInput markAsFinished];
[assetWriter finishWritingWithCompletionHandler:^{
[assetReader cancelReading];
completionBlock(self);
}];
Сохранение автора активов очень важно, но я также столкнулся с очень странной периодической ошибкой, хотя все мои активы были сохранены (и никогда не использовались повторно). Проблема также не была в конфликте имен файлов или в отсутствующем каталоге, потому что все имена моих файлов основаны на CACurrentMediaTime() и не меняют каталоги.
Кажется, если вы не установите endSessionAtSourceTime:
для редактора ресурсов каждый раз существует очень редкий (но воспроизводимый) шанс, что обработчик завершения для finishWritingWithCompletionHandler:
никогда не будет вызван. Если вы подождете несколько секунд и проверите состояние редактора ресурсов, он будет в состоянии AVAssetWriterStatusFailure, и ошибка будет неописанной: "Произошла неизвестная ошибка (-12763)". Кроме того, изменение формата файла для редактора ресурсов не повлияет на эту проблему. Наконец, эта проблема, вероятно, является проблемой только в том случае, если вам нужно быстро записывать фильмы снова и снова (так как вероятность неудачи, вероятно, составляет 1/15 - 1/20).
Поэтому просто сохраните отметку времени презентации для последнего образца, который вы передаете составителю ресурса, и позвоните endSessionAtSourceTime:
с этим временем выборки прямо перед тем, как вы собираетесь позвонить finishWritingWithCompletionHandler:
,
Это также может произойти, если каталог назначения не существует. В этом случае запись работает нормально, но файл не создан и блок не вызывается.