减小转换后的音频文件的大小

Posted

技术标签:

【中文标题】减小转换后的音频文件的大小【英文标题】:Decrease size of converted audio file 【发布时间】:2011-11-08 12:51:06 【问题描述】:

我正在将我录制的 .m4a 格式的音频转换为 .caf 格式。录制音频的设置如下:

/* Record settings for recording the audio*/ 
recordSetting = [[NSDictionary alloc] initWithObjectsAndKeys:[NSNumber numberWithInt:kAudioFormatMPEG4AAC],AVFormatIDKey,
                 [NSNumber numberWithInt:44100.0],AVSampleRateKey,
                 [NSNumber numberWithInt: 2],AVNumberOfChannelsKey,
                 [NSNumber numberWithInt:16],AVLinearPCMBitDepthKey,
                 [NSNumber numberWithBool:NO],AVLinearPCMIsBigEndianKey,
                 [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey,
                 nil];

我使用此函数将音频转换为 .caf:

-(NSString *)handleConvertToPCM:(NSURL *)convertUrl 

    [self performSelectorOnMainThread:@selector(showActivity) withObject:nil waitUntilDone:NO];

    DEBUG_LOG(@"DEBUGGING");
    DEBUG_LOG(@"handleConvertToPCM");
    // open an ExtAudioFile
    NSLog (@"opening %@", convertUrl);
    ExtAudioFileRef inputFile;
    CheckResult (ExtAudioFileOpenURL((CFURLRef)convertUrl, &inputFile),
                 "ExtAudioFileOpenURL failed");
    // prepare to convert to a plain ol' PCM format
    AudiostreamBasicDescription requiredPCMFormat;
    requiredPCMFormat.mSampleRate = 44100; // todo: or use source rate?
    requiredPCMFormat.mFormatID = kAudioFormatLinearPCM ;
    requiredPCMFormat.mFormatFlags =  kAudioFormatFlagsCanonical;   
    requiredPCMFormat.mChannelsPerFrame = 2;
    requiredPCMFormat.mFramesPerPacket = 1;
    requiredPCMFormat.mBitsPerChannel = 16;
    requiredPCMFormat.mBytesPerPacket = 4;
    requiredPCMFormat.mBytesPerFrame = 4;
    CheckResult (ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat,
                                         sizeof (requiredPCMFormat), &requiredPCMFormat),
                 "ExtAudioFileSetProperty failed");
    // allocate a big buffer. size can be arbitrary for ExtAudioFile.
    UInt32 outputBufferSize = 0x10000;
    void* ioBuf = malloc (outputBufferSize);
    UInt32 sizePerPacket = requiredPCMFormat.mBytesPerPacket;   
    UInt32 packetsPerBuffer = outputBufferSize / sizePerPacket;
    // set up output file   
    self.outputPath = [NSString stringWithFormat:@"%@/export-pcm.caf",DOCUMENTS_FOLDER];
    self.outputURL = [NSURL fileURLWithPath:self.outputPath];
    DEBUG_LOG(@"creating output file %@", self.outputURL);
    AudioFileID outputFile;
    CheckResult(AudioFileCreateWithURL((CFURLRef)outputURL,
                                       kAudioFileCAFType,
                                       &requiredPCMFormat, 
                                       kAudioFileFlags_EraseFile, 
                                       &outputFile),
                "AudioFileCreateWithURL failed");
    // start convertin'
    UInt32 outputFilePacketPosition = 0; //in bytes
    while (true) 
    
        // wrap the destination buffer in an AudioBufferList
        AudioBufferList convertedData;
        convertedData.mNumberBuffers = 1;
        convertedData.mBuffers[0].mNumberChannels = requiredPCMFormat.mChannelsPerFrame;
        convertedData.mBuffers[0].mDataByteSize = outputBufferSize;
        convertedData.mBuffers[0].mData = ioBuf;
        UInt32 frameCount = packetsPerBuffer;
        // read from the extaudiofile
        CheckResult (ExtAudioFileRead(inputFile,
                                      &frameCount,
                                      &convertedData),
                     "Couldn't read from input file");
        if (frameCount == 0) 
        
            printf ("done reading from file");
            break;
        
        // write the converted data to the output file
        CheckResult (AudioFileWritePackets(outputFile,
                                           false,
                                           frameCount,
                                           NULL,
                                           outputFilePacketPosition / requiredPCMFormat.mBytesPerPacket, 
                                           &frameCount,
                                           convertedData.mBuffers[0].mData),
                     "Couldn't write packets to file");

        DEBUG_LOG(@"Converted %ld bytes", outputFilePacketPosition);
        // advance the output file write location
        outputFilePacketPosition += (frameCount * requiredPCMFormat.mBytesPerPacket);
    
    // clean up
    ExtAudioFileDispose(inputFile);
    AudioFileClose(outputFile);
    return(self.outputPath);    


我的问题是转换后的文件的大小与给定的转换文件相比非常大。无论如何通过更改转换设置来减小大小。 我尝试压缩获得的文件,但是压缩需要很长时间。所以我想找到一种方法来减小大小以及转换。

【问题讨论】:

您正在将 MP4 文件解码为纯 PCM。这肯定会导致规模大幅增加。你为什么要转换文件? 它是必需的。任何减小尺寸的方法。设置的任何更改都有效吗?我尝试了一些但失败了。 我不熟悉在 iO 中编写音乐,但是当我使用游戏工具将声音从立体声转换为单声道时,大小减少了一半。也许单声道对你来说就足够了吗? 您可能会通过以下方式获得更小的文件:将两个通道(也称为立体声)减少到一个通道,降低编码器比特率(例如 32kbps),降低播放速率(例如 22kHz)。在任何情况下,不要使用 PCM,而是坚持使用 AAC 编码(MP4 文件)。 如果我更改任何设置都无法正常工作。应用程序将崩溃并且错误提示错误:ExtAudioFileSetProperty failed ('fmt?') 发生在 CheckResult (ExtAudioFileSetProperty()) 期间。 【参考方案1】:

解压缩高度压缩的音频文件几乎总是会产生更大的结果文件,除非您使用更损失的压缩格式重新压缩。

【讨论】:

有没有什么方法可以重新压缩音频,更省时? 对于 caf 格式,文件大小将与采样率(通常为 44.1kHz)乘以每个采样的位数(通常为 16 位或 2 字节)乘以通道数(1、2 或 5)成正比),以秒为单位乘以音频的长度。你想减少哪个? 转换后我的 2 分钟音频大小接近 20MB。我想将其减小到最大 5MB。我应该使用哪些设置来实现这一点? 将 4 件事中的 2 件减半。任意 2. 如果我更改任何设置都无法正常工作。应用程序将崩溃并且错误提示错误:ExtAudioFileSetProperty failed ('fmt?') 发生在 CheckResult (ExtAudioFileSetProperty()) 期间。

以上是关于减小转换后的音频文件的大小的主要内容,如果未能解决你的问题,请参考以下文章

当我们使用 gs 命令将 ps 转换为 pcl 文件时如何减小 PCL 文件大小

怎么在电脑上把文件的KB大小转换成MB?

从视频文件中删除音频

如何使用 PIL 减小图像文件大小

如何在不实际转换的情况下确定转换后音频文件的理论文件大小(即 mp3 到 wav)

减小一些 pdf 文件的大小