123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- //
- // AudioConverter.m
- // ContactPoster
- //
- // Created by TSYH on 2024/1/25.
- //
- #import "AudioConverter.h"
- #import "lame.h"
- #import <AVFoundation/AVFoundation.h>
- @implementation AudioConverter
- // 转换为mp3
- + (void)convenrtToMp3WithResult:(NSString *)originalPath
- outPath:(NSString *)outPath
- completion:(ConvertCompletionHandler)completion {
-
- [[NSFileManager defaultManager] removeItemAtPath:outPath error:nil];
-
- @try {
- int read, write;
-
- FILE *pcm = fopen([originalPath cStringUsingEncoding:1], "rb");//被转换的文件
- fseek(pcm, 4*1024, SEEK_CUR); //skip file header
- FILE *mp3 = fopen([outPath cStringUsingEncoding:1], "wb");//转换后文件的存放位置
-
- const int PCM_SIZE = 8192;
- const int MP3_SIZE = 8192;
- short int pcm_buffer[PCM_SIZE*2];
- unsigned char mp3_buffer[MP3_SIZE];
-
- lame_t lame = lame_init();
- lame_set_num_channels (lame, 2 ); // 设置 1 为单通道,默认为 2 双通道
- lame_set_in_samplerate(lame, 44100);//
- lame_set_brate (lame, 8);
- lame_set_mode (lame, 3);
- lame_set_VBR(lame, vbr_default);
- lame_set_quality (lame, 2); /* 2=high 5 = medium 7=low 音 质 */
- lame_init_params(lame);
-
- do {
- read = fread(pcm_buffer, 2*sizeof(short int), PCM_SIZE, pcm);
- if (read == 0)
- write = lame_encode_flush(lame, mp3_buffer, MP3_SIZE);
- else
- write = lame_encode_buffer_interleaved(lame, pcm_buffer, read, mp3_buffer, MP3_SIZE);
-
- fwrite(mp3_buffer, write, 1, mp3);
-
- } while (read != 0);
-
- lame_close(lame);
- fclose(mp3);
- fclose(pcm);
- }
- @catch (NSException *exception) {
- // NSLog(@"%@",[exception description]);
- completion(nil, exception.reason);
- }
- @finally {
- completion(outPath, nil);
- }
- }
- + (void)convertM4aToWav:(NSString *)originalPath
- outPath:(NSString *)outPath
- compltion:(ConvertCompletionHandler)compltion {
- if ([[NSFileManager defaultManager] fileExistsAtPath:outPath]) {
- NSError *error;
- [[NSFileManager defaultManager] removeItemAtPath:outPath error:&error];
- }
- NSURL *originalUrl = [NSURL fileURLWithPath:originalPath];
- NSURL *outPutUrl = [NSURL fileURLWithPath:outPath];
- AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL:originalUrl options:nil]; //读取原始文件信息
- NSError *error = nil;
- AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:songAsset error:&error];
- if (error) {
- NSLog (@"error: %@", error);
- compltion(nil, error.description);
- return;
- }
- AVAssetReaderOutput *assetReaderOutput = [AVAssetReaderAudioMixOutput assetReaderAudioMixOutputWithAudioTracks:songAsset.tracks audioSettings: nil];
- if (![assetReader canAddOutput:assetReaderOutput]) {
- NSLog (@"can't add reader output... die!");
- compltion(nil, @"can't add reader output... die!");
- return;
- }
- [assetReader addOutput:assetReaderOutput];
-
- AVAssetWriter *assetWriter = [AVAssetWriter assetWriterWithURL:outPutUrl fileType:AVFileTypeCoreAudioFormat error:&error];
- if (error) {
- NSLog (@"error: %@", error);
- compltion(nil, error.description);
- return;
- }
- AudioChannelLayout channelLayout;
- memset(&channelLayout, 0, sizeof(AudioChannelLayout));
- channelLayout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
-
- /** 配置音频参数 */
- NSDictionary *outputSettings = [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey, [NSNumber numberWithFloat:44100.0], AVSampleRateKey, [NSNumber numberWithInt:2], AVNumberOfChannelsKey, [NSData dataWithBytes:&channelLayout length:sizeof(AudioChannelLayout)], AVChannelLayoutKey,[NSNumber numberWithInt:16], AVLinearPCMBitDepthKey, [NSNumber numberWithBool:NO], AVLinearPCMIsNonInterleaved, [NSNumber numberWithBool:NO],AVLinearPCMIsFloatKey, [NSNumber numberWithBool:NO], AVLinearPCMIsBigEndianKey, nil];
- AVAssetWriterInput *assetWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:outputSettings];
- if ([assetWriter canAddInput:assetWriterInput]) {
- [assetWriter addInput:assetWriterInput];
- } else {
- NSLog (@"can't add asset writer input... die!");
- compltion(nil, @"can't add asset writer input... die!");
- return;
- }
- assetWriterInput.expectsMediaDataInRealTime = NO;
- [assetWriter startWriting];
- [assetReader startReading];
- AVAssetTrack *soundTrack = [songAsset.tracks objectAtIndex:0];
- CMTime startTime = CMTimeMake (0, soundTrack.naturalTimeScale);
- [assetWriter startSessionAtSourceTime:startTime];
- __block UInt64 convertedByteCount = 0;
- dispatch_queue_t mediaInputQueue = dispatch_queue_create("mediaInputQueue", NULL);
- [assetWriterInput requestMediaDataWhenReadyOnQueue:mediaInputQueue usingBlock: ^ {
- while (assetWriterInput.readyForMoreMediaData) {
- CMSampleBufferRef nextBuffer = [assetReaderOutput copyNextSampleBuffer];
- if (nextBuffer) {
- // append buffer
- [assetWriterInput appendSampleBuffer: nextBuffer];
- convertedByteCount += CMSampleBufferGetTotalSampleSize (nextBuffer);
- } else {
- [assetWriterInput markAsFinished];
- [assetWriter finishWritingWithCompletionHandler:^{
- }];
- [assetReader cancelReading];
-
- NSDictionary *outputFileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[outPutUrl path] error:nil];
- NSLog (@"FlyElephant %lld",[outputFileAttributes fileSize]);
-
- compltion(outPath, nil);
- break;
- }
- }
- }];
- }
- @end
|