Обновление: Я думал, что проблема в нехватке памяти; это не. Эта ошибка постоянно возникает в 4.3 и не встречается в 4.1 / 4.2 даже при достаточно низких условиях памяти.
Это небольшая библиотека Objective-C, которую мне пришлось написать для того, что в первую очередь является приложением Monotouch - AVFoundation еще не полностью связан.
Вот след:
0 Orbiter 0x007977d8 mono_handle_native_sigsegv + 404
1 Orbiter 0x007746b4 mono_sigsegv_signal_handler + 348
2 libsystem_c.dylib 0x34ce472f _sigtramp + 42
3 AVFoundation 0x365b3ab5 -[AVAssetExportSession dealloc] + 164
4 CoreFoundation 0x34bc2c43 -[NSObject(NSObject) release] + 30
5 AVFoundation 0x365b3607 -[AVAssetExportSession release] + 62
6 CoreFoundation 0x34bdd047 sendRelease + 14
7 libsystem_blocks.dylib 0x312c292f _Block_object_dispose + 118
8 AVFoundation 0x365b45b3 __destroy_helper_block_5 + 22
9 libsystem_blocks.dylib 0x312c288f _Block_release + 58
10 libdispatch.dylib 0x30df18ed _dispatch_call_block_and_release + 16
11 libdispatch.dylib 0x30deced1 _dispatch_queue_drain + 240
12 libdispatch.dylib 0x30ded043 _dispatch_queue_invoke + 78
13 libdispatch.dylib 0x30dec611 _dispatch_worker_thread2 + 196
14 libsystem_c.dylib 0x34cda591 _pthread_wqthread + 264
15 libsystem_c.dylib 0x34cdabc4 _init_cpu_capabilities + 4294967295
Вот код:
@implementation AVUtils : NSObject
+ (void) dubAudio:(NSURL*)videoUrl
withTrack:(NSURL*)audioUrl
outputTo:(NSURL*)newUrl
handleSuccess:(void(^)(void))successHandler
handleFailure:(void(^)(NSError* err))failureHandler
{
AVURLAsset* video = [[AVURLAsset alloc]initWithURL:videoUrl options:nil];
AVAssetTrack* videoTrack = [[video tracksWithMediaType:AVMediaTypeVideo] objectAtIndex:0];
CMTime videoDuration = video.duration;
AVURLAsset* audio = [[AVURLAsset alloc]initWithURL:audioUrl options:nil];
AVAssetTrack* audioTrack = [[audio tracksWithMediaType:AVMediaTypeAudio] objectAtIndex:0];
CMTime audioDuration = audio.duration;
CMTime newDuration = CMTimeMinimum(audioDuration, videoDuration);
CMTimeRange newTimeRange = CMTimeRangeMake(kCMTimeZero, newDuration);
AVMutableComposition* newComposition = [AVMutableComposition composition];
NSError* theError;
BOOL success;
AVMutableCompositionTrack* newAudioTrack = [newComposition addMutableTrackWithMediaType:AVMediaTypeAudio
preferredTrackID:kCMPersistentTrackID_Invalid];
theError = nil;
success = [newAudioTrack insertTimeRange:newTimeRange ofTrack:audioTrack atTime:kCMTimeZero error:&theError];
if (success == NO) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error adding audio track"
message:[theError localizedDescription]
delegate: nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alertView show];
[alertView release];
} else {
AVMutableCompositionTrack* newVideoTrack = [newComposition addMutableTrackWithMediaType:AVMediaTypeVideo
preferredTrackID:kCMPersistentTrackID_Invalid];
theError = nil;
success = [newVideoTrack insertTimeRange:newTimeRange ofTrack:videoTrack atTime:kCMTimeZero error:&theError];
if (success == NO) {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Error adding audio track"
message:[theError localizedDescription]
delegate: nil
cancelButtonTitle:@"Cancel"
otherButtonTitles:nil];
[alertView show];
[alertView release];
} else {
AVAssetExportSession* _assetExport = [[AVAssetExportSession alloc] initWithAsset:newComposition presetName:AVAssetExportPresetPassthrough];
_assetExport.outputFileType = @"com.apple.quicktime-movie";
_assetExport.outputURL = newUrl;
_assetExport.shouldOptimizeForNetworkUse = YES;
[_assetExport exportAsynchronouslyWithCompletionHandler:
^(void) {
if (_assetExport.status == AVAssetExportSessionStatusCompleted) {
successHandler();
} else {
failureHandler(_assetExport.error);
}
[_assetExport release];
[video release];
[audio release];
[newComposition release];
}
];
}
}
}
@end
Моя теория состояла в том, что я просачивал указатель на _assetExport.error
, передавая его другому потоку, которым я был, и затем он был недействительным, когда на него ссылались, потому что _assetExport
собирал мусор. Но я проверил, что segfault происходит, даже когда экспорт завершается успешно, так что в данном случае это не так.
Я довольно новичок в Obj-C - кто-нибудь может увидеть какие-либо другие очевидные недостатки в том, что я здесь делаю?