更新:我认为问题是内存不足;不是。这种错误在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
是垃圾集。但我确认即使导出成功也会发生段错误,所以在这种情况下不是这样。
我是Obj-C的新手 - 任何人都可以看到我在这里做的任何其他明显的缺陷吗?
答案 0 :(得分:2)
看起来关于完成Block的内存管理是个问题。崩溃日志说它在_assetExport的发布时崩溃了..你绝对不应该发布newComposition(你没有分配它或保留它)。