{"id":6132,"date":"2014-04-13T04:33:31","date_gmt":"2014-04-13T04:33:31","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2014\/04\/13\/adding-audio-to-a-video-using-obj-c-plugin-and-avassetwriterinput-collection-of-common-programming-errors-2\/"},"modified":"2014-04-13T04:33:31","modified_gmt":"2014-04-13T04:33:31","slug":"adding-audio-to-a-video-using-obj-c-plugin-and-avassetwriterinput-collection-of-common-programming-errors-2","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2014\/04\/13\/adding-audio-to-a-video-using-obj-c-plugin-and-avassetwriterinput-collection-of-common-programming-errors-2\/","title":{"rendered":"Adding audio to a video using Obj-C plugin and AVAssetWriterInput-Collection of common programming errors"},"content":{"rendered":"<ul>\n<li><img decoding=\"async\" src=\"http:\/\/www.gravatar.com\/avatar\/9e94485272be68aae7e674d941f62d4d?s=32&amp;d=identicon&amp;r=PG\" \/><br \/>\nuser1754032<\/p>\n<p>I&#8217;m trying to take a video created using the iVidCap plugin and add audio to it. Basically the exact same thing as in this question: Writing video + generated audio to AVAssetWriterInput, audio stuttering. I&#8217;ve used the code from this post as a basis to try and modify the iVidCap.mm file myself, but the app always crashes in endRecordingSession.<\/p>\n<p>I&#8217;m not sure how I need to modify endRecordingSession to accomodate for the audio (the original plugin just creates a video file). Here is the function:<\/p>\n<pre><code>- (int) endRecordingSession: (VideoDisposition) action {\n\nNSLog(@\"Start endRecordingSession\");\nNSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];\n\nNSLog(@\"Auto released pool\");\n\nNSString *filePath;\nBOOL success = false;\n\n[videoWriterInput markAsFinished];\nNSLog(@\"Mark video writer input as finished\");\n\/\/[audioWriterInput markAsFinished];\n\n\/\/ Wait for the video status to become known.\n\/\/ Is this really doing anything?\nint status = videoWriter.status;\nwhile (status == AVAssetWriterStatusUnknown) {\n    NSLog(@\"Waiting for video to complete...\");\n    [NSThread sleepForTimeInterval:0.5f];\n    status = videoWriter.status;\n}\n\nNSLog(@\"Video completed\");\n\n@synchronized(self) {\n    success = [videoWriter finishWriting];\n    NSLog(@\"Success: %@\", success);\n    if (!success) {\n        \/\/ We failed to successfully finalize the video file.\n        NSLog(@\"finishWriting returned NO\");\n\n    } else {\n        \/\/ The video file was successfully written to the Documents folder.\n        filePath = [[self getDocumentsFileURL:videoFileName] path];\n        if (action == Save_Video_To_Album) {\n\n            \/\/ Move the video to an accessible location on the device.\n            NSLog(@\"Temporary video filePath=%@\", filePath);\n            if (UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(filePath)) {\n                NSLog(@\"Video IS compatible. Adding it to photo album.\");\n                UISaveVideoAtPathToSavedPhotosAlbum(filePath, self, @selector(copyToPhotoAlbumCompleteFromVideo: didFinishSavingWithError: contextInfo:), nil);\n            } else {\n                NSLog(@\"Video IS NOT compatible. Could not be added to the photo album.\");\n                success = NO;\n            }\n        } else if (action == Discard_Video) {\n            NSLog(@\"Video cancelled. Removing temporary video file: %@\", filePath);\n            [self removeFile:filePath];  \n        }\n    }\n\n    [self cleanupWriter];\n}\n\nisRecording = false;\n\n[pool drain];\n\nreturn success; }\n<\/code><\/pre>\n<p>Right now it crashes on [videoWriter finishWriting]. I tried adding [audioWriterInput markAsFinished], but then it crashes on that. I would contact the original poster since it seems like they got it working, but there doesn&#8217;t seem to be a way to send private messages.<\/p>\n<p>Does anyone have any suggestions on how I can get this to work or why it&#8217;s crashing? I&#8217;ve tried my best to figure this out but I&#8217;m pretty new to Obj-C. I can post the rest of the code if needed (a lot of it is in the original post referenced earlier).<\/p>\n<\/li>\n<li><img decoding=\"async\" src=\"http:\/\/www.gravatar.com\/avatar\/f45bff1b42011b870cb5dfdba0d10255?s=32&amp;d=identicon&amp;r=PG\" \/><br \/>\nPete<\/p>\n<p>The issue might actually be in the writeAudioBuffer function.<\/p>\n<p>If you copied the code from that post but didnlt change it then you will certainly have some problems.<\/p>\n<p>You need to do something like this:<\/p>\n<pre><code>if ( ![self waitForAudioWriterReadiness]) {\n    NSLog(@\"WARNING: writeAudioBuffer dropped frame after wait limit reached.\");\n    return 0;\n}\n\nOSStatus status;\nCMBlockBufferRef bbuf = NULL;\nCMSampleBufferRef sbuf = NULL;\n\nsize_t buflen = n * nchans * sizeof(float);\n\nCMBlockBufferRef tmp_bbuf = NULL;\nstatus = CMBlockBufferCreateWithMemoryBlock(\n                                            kCFAllocatorDefault, \n                                            samples, \n                                            buflen, \n                                            kCFAllocatorDefault, \n                                            NULL, \n                                            0, \n                                            buflen, \n                                            0, \n                                            &amp;tmp_bbuf);\n\nif (status != noErr || !tmp_bbuf) {\n    NSLog(@\"CMBlockBufferCreateWithMemoryBlock error\");\n    return -1;\n}\n\/\/ Copy the buffer so that we get a copy of the samples in memory.\n\/\/ CMBlockBufferCreateWithMemoryBlock does not actually copy the data!\n\/\/ \nstatus = CMBlockBufferCreateContiguous(kCFAllocatorDefault, tmp_bbuf, kCFAllocatorDefault, NULL, 0, buflen, kCMBlockBufferAlwaysCopyDataFlag, &amp;bbuf);\n\/\/CFRelease(tmp_bbuf); \/\/ causes abort?!\nif (status != noErr) {\n    NSLog(@\"CMBlockBufferCreateContiguous error\");\n    \/\/CFRelease(bbuf);\n    return -1;\n}\n\n\nCMTime timestamp = CMTimeMake(sample_position_, 44100);\n\nstatus = CMAudioSampleBufferCreateWithPacketDescriptions(\n    kCFAllocatorDefault, bbuf, TRUE, 0, NULL, audio_fmt_desc_, 1, timestamp, NULL, &amp;sbuf);\n\nsample_position_ += n;\nif (status != noErr) {\n    NSLog(@\"CMSampleBufferCreate error\");\n    return -1;\n}\nBOOL r = [audioWriterInput appendSampleBuffer:sbuf];\nif (!r) {\n    NSLog(@\"appendSampleBuffer error\");\n}\n\/\/CFRelease(bbuf); \/\/ crashes, don't know why..  Is there a leak here?\n\/\/CFRelease(sbuf);\n\nreturn 0;\n<\/code><\/pre>\n<p>There are a few things to do with memory management that I am unsure on here.<\/p>\n<p>Additionally be sure to use:<\/p>\n<pre><code>audioWriterInput.expectsMediaDataInRealTime = YES;\n<\/code><\/pre>\n<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>user1754032 I&#8217;m trying to take a video created using the iVidCap plugin and add audio to it. Basically the exact same thing as in this question: Writing video + generated audio to AVAssetWriterInput, audio stuttering. I&#8217;ve used the code from this post as a basis to try and modify the iVidCap.mm file myself, but the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-6132","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/6132","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=6132"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/6132\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=6132"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=6132"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=6132"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}