如何修剪音频数据?

Posted

技术标签:

【中文标题】如何修剪音频数据?【英文标题】:How to trim audio data? 【发布时间】:2011-10-21 13:06:08 【问题描述】:

我想删除最后 5 秒的音频数据并将其作为新音频保存到不同的位置。我正在尝试使用 ExtAudioFile 服务通过以下代码来完成它,但这里我的音频输出大小从 2.5 MB 增加到 26.5 MB ..我在哪里错了。

UInt32 size;                                                                                                                                                                                           NSString *docsDir;
NSArray *dirPaths;
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = [dirPaths objectAtIndex:0];
NSString *destinationURL = [docsDir
                            stringByAppendingPathComponent:@"Audio3.m4a"];
NSURL * soundFilePath = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                                                pathForResource:@"Audio1"
                                                ofType:@"m4a"]];
ExtAudioFileRef inputFile= NULL;
ExtAudioFileRef outputFile= NULL;
ExtAudioFileOpenURL((CFURLRef)soundFilePath, &inputFile);

AudiostreamBasicDescription destFormat;

destFormat.mFormatID = kAudioFormatMPEG4AAC;
destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
destFormat.mSampleRate = 441000;
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 2;
destFormat.mBitsPerChannel = 16;    
destFormat.mReserved = 0;

OSStatus createStatus =ExtAudioFileCreateWithURL((CFURLRef)[NSURL fileURLWithPath:destinationURL],kAudioFileM4AType,&destFormat,NULL,kAudioFileFlags_EraseFile,&outputFile);
//ExtAudioFileDispose(outputFile);
NSLog(@"createStatus: %i", createStatus);
//this is not needed as file url is already opened. 


ExtAudioFileOpenURL((CFURLRef)soundFilePath, &inputFile);
//ExtAudioFileOpenURL((CFURLRef)[NSURL fileURLWithPath:destinationURL], &outputFile);   
//find out how many frames long this file is 

SInt64 length = 0;
UInt32 dataSize2 = (UInt32)sizeof(length);
ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);

AudioStreamBasicDescription clientFormat;
clientFormat.mFormatID = kAudioFormatMPEG4AAC;
clientFormat.mSampleRate = 441000;
clientFormat.mFormatFlags = kAudioFormatFlagsCanonical;
clientFormat.mBitsPerChannel = 16;
clientFormat.mChannelsPerFrame = 2;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerPacket = 2;
clientFormat.mBytesPerFrame = 2;
destFormat.mReserved = 0;

size = sizeof(clientFormat);

//set the intermediate format to canonical on the source file for conversion (?) 
ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
ExtAudioFileSetProperty(outputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);

OSStatus seekStatus = ExtAudioFileSeek(outputFile, 0);  
NSLog(@"seekstatus %i", seekStatus);

SInt64 newLength = length - (5); //shorten by 5 seconds worth of frames 

NSLog(@"length: %i frames", length);

UInt8 *buffer = malloc(64*1024); //64K 

UInt32 totalFramecount = 0;
while(true) 
    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mNumberChannels = 2;
    bufferList.mBuffers[0].mData = buffer; //pointer to buffer of audio data 
    bufferList.mBuffers[0].mDataByteSize =64*1024; //number of bytes in the buffer 

    UInt32 frameCount = 64*1024 / 2; //2 bytes per frame        
    // Read a chunk of input 
    SInt64              outFrameOffset;
    ExtAudioFileTell(inputFile, &outFrameOffset)    ;
    NSLog(@"head status %i", outFrameOffset);
    OSStatus status = ExtAudioFileRead(inputFile, &frameCount, &bufferList);
    totalFramecount += frameCount;

    NSLog(@"read status %i", status);
    NSLog(@"loaded %i frames and stopping at %i", totalFramecount, newLength);

    if (!frameCount ||(totalFramecount >= newLength)) 
        //termination condition 
        break;
       
    OSStatus writeStatus = ExtAudioFileWrite(outputFile, frameCount, &bufferList);
    NSLog(@"ws: %i", writeStatus);
   
free(buffer);

ExtAudioFileDispose(inputFile);
ExtAudioFileDispose(outputFile);

【问题讨论】:

【参考方案1】:

您正在获取压缩音频 (M4A) 并对其进行解压缩,这是您需要执行的操作以缩减音频内容。如果您想恢复到 2.5 MB 范围,则需要在完成后重新压缩音频。

请记住,重复的有损解压缩-编辑-重新压缩循环会降低您的音频质量。如果您要执行大量音频编辑操作,您应该将音频从压缩转换为未压缩,然后运行转换,最后重新压缩。

【讨论】:

感谢您的回答,但现在我无法播放这个新保存的音频文件,并且持续时间和比特率也未显示在其信息中。我该如何解决? 为一个有用的答案投票以表示感谢可能会增加获得跟进的机会 试一试Audacity,深入了解您的代码创建的音频文件。尽管 1.3 版本处于 Beta 阶段,但它非常稳定,并且明显优于 1.2。 我找不到任何关于如何从音频文件中删除的答案,例如,如果我想从第二个 3 到 10 删除。你可以检查这个问题吗:***.com/questions/53928988/…

以上是关于如何修剪音频数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在颤动中制作音频修剪小部件

如何在 iOS 中从开始时间到结束时间修剪或播放音频?

使用 Sox 开始和结束音频批量修剪

在 Node.js 中修剪和连接音频文件

iOS:使用 Swift 修剪音频文件?

修剪音频文件并获得静音之间的部分