【问题标题】:Adding audio to a video using Obj-C plugin and AVAssetWriterInput使用 Obj-C 插件和 AVAssetWriterInput 向视频添加音频
【发布时间】:2012-10-17 18:28:24
【问题描述】:

我正在尝试拍摄使用 iVidCap 插件创建的视频并向其添加音频。基本上与这个问题完全相同:Writing video + generated audio to AVAssetWriterInput, audio stuttering。我使用这篇文章中的代码作为基础尝试自己修改 iVidCap.mm 文件,但应用程序总是在 endRecordingSession 中崩溃。

我不确定我需要如何修改 endRecordingSession 以适应音频(原始插件只是创建一个视频文件)。这是函数:

- (int) endRecordingSession: (VideoDisposition) action {

NSLog(@"Start endRecordingSession");
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];

NSLog(@"Auto released pool");

NSString *filePath;
BOOL success = false;

[videoWriterInput markAsFinished];
NSLog(@"Mark video writer input as finished");
//[audioWriterInput markAsFinished];

// Wait for the video status to become known.
// Is this really doing anything?
int status = videoWriter.status;
while (status == AVAssetWriterStatusUnknown) {
    NSLog(@"Waiting for video to complete...");
    [NSThread sleepForTimeInterval:0.5f];
    status = videoWriter.status;
}

NSLog(@"Video completed");

@synchronized(self) {
    success = [videoWriter finishWriting];
    NSLog(@"Success: %@", success);
    if (!success) {
        // We failed to successfully finalize the video file.
        NSLog(@"finishWriting returned NO");

    } else {
        // The video file was successfully written to the Documents folder.
        filePath = [[self getDocumentsFileURL:videoFileName] path];
        if (action == Save_Video_To_Album) {

            // Move the video to an accessible location on the device.
            NSLog(@"Temporary video filePath=%@", filePath);
            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filePath)) {
                NSLog(@"Video IS compatible. Adding it to photo album.");
                UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, @selector(copyToPhotoAlbumCompleteFromVideo: didFinishSavingWithError: contextInfo:), nil);
            } else {
                NSLog(@"Video IS NOT compatible. Could not be added to the photo album.");
                success = NO;
            }
        } else if (action == Discard_Video) {
            NSLog(@"Video cancelled. Removing temporary video file: %@", filePath);
            [self removeFile:filePath];  
        }
    }

    [self cleanupWriter];
}

isRecording = false;

[pool drain];

return success; }

现在它在 [videoWriter finishWriting] 上崩溃。我尝试添加 [audioWriterInput markAsFinished],但随后它崩溃了。我会联系原始发帖者,因为他们似乎可以正常工作,但似乎没有办法发送私人消息。

是否有人对我如何使其工作或为什么会崩溃有任何建议?我已经尽力解决这个问题,但我对 Obj-C 还是很陌生。如果需要,我可以发布其余代码(其中很多都在前面引用的原始帖子中)。

【问题讨论】:

    标签: objective-c audio video avfoundation avassetwriter


    【解决方案1】:

    问题实际上可能出在 writeAudioBuffer 函数中。

    如果你从那篇文章中复制了代码但没有更改它,那么你肯定会遇到一些问题。

    你需要做这样的事情:

    if ( ![self waitForAudioWriterReadiness]) {
        NSLog(@"WARNING: writeAudioBuffer dropped frame after wait limit reached.");
        return 0;
    }
    
    OSStatus status;
    CMBlockBufferRef bbuf = NULL;
    CMSampleBufferRef sbuf = NULL;
    
    size_t buflen = n * nchans * sizeof(float);
    
    CMBlockBufferRef tmp_bbuf = NULL;
    status = CMBlockBufferCreateWithMemoryBlock(
                                                kCFAllocatorDefault, 
                                                samples, 
                                                buflen, 
                                                kCFAllocatorDefault, 
                                                NULL, 
                                                0, 
                                                buflen, 
                                                0, 
                                                &tmp_bbuf);
    
    if (status != noErr || !tmp_bbuf) {
        NSLog(@"CMBlockBufferCreateWithMemoryBlock error");
        return -1;
    }
    // Copy the buffer so that we get a copy of the samples in memory.
    // CMBlockBufferCreateWithMemoryBlock does not actually copy the data!
    // 
    status = CMBlockBufferCreateContiguous(kCFAllocatorDefault, tmp_bbuf, kCFAllocatorDefault, NULL, 0, buflen, kCMBlockBufferAlwaysCopyDataFlag, &bbuf);
    //CFRelease(tmp_bbuf); // causes abort?!
    if (status != noErr) {
        NSLog(@"CMBlockBufferCreateContiguous error");
        //CFRelease(bbuf);
        return -1;
    }
    
    
    CMTime timestamp = CMTimeMake(sample_position_, 44100);
    
    status = CMAudioSampleBufferCreateWithPacketDescriptions(
        kCFAllocatorDefault, bbuf, TRUE, 0, NULL, audio_fmt_desc_, 1, timestamp, NULL, &sbuf);
    
    sample_position_ += n;
    if (status != noErr) {
        NSLog(@"CMSampleBufferCreate error");
        return -1;
    }
    BOOL r = [audioWriterInput appendSampleBuffer:sbuf];
    if (!r) {
        NSLog(@"appendSampleBuffer error");
    }
    //CFRelease(bbuf); // crashes, don't know why..  Is there a leak here?
    //CFRelease(sbuf);
    
    return 0;
    

    我在这里不确定与内存管理有关的一些事情。

    另外一定要使用:

    audioWriterInput.expectsMediaDataInRealTime = YES;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-26
      • 1970-01-01
      • 2011-06-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多