日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios 边录音边放_iOS 录音、音频的拼接剪切以及边录边压缩转码

發布時間:2023/12/31 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios 边录音边放_iOS 录音、音频的拼接剪切以及边录边压缩转码 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

總體內容

1、錄音實現

2、錄音的編輯 (拼接音頻:可以設置多段,音頻的剪切:按照時間段剪切)

3、lame靜態庫進行壓縮轉碼

一、錄音實現

1.1、導入 AVFoundation 框架,多媒體的處理, 基本上都使用這個框架#import?

1.2、使用 AVAudioRecorder 進行錄音,定義一個JKAudioTool 管理錄音的類

(1)、定義一個錄音對象,懶加載@property?(nonatomic,?strong)?AVAudioRecorder?*audioRecorder;

-(AVAudioRecorder?*)audioRecorder

{

if?(!_audioRecorder)?{

//?0.?設置錄音會話

/**

AVAudioSessionCategoryPlayAndRecord:?可以邊播放邊錄音(也就是平時看到的背景音樂)

*/

[[AVAudioSession?sharedInstance]?setCategory:AVAudioSessionCategoryPlayAndRecord?error:nil];

//?啟動會話

[[AVAudioSession?sharedInstance]?setActive:YES?error:nil];

//?1.?確定錄音存放的位置

NSURL?*url?=?[NSURL?URLWithString:self.recordPath];

//?2.?設置錄音參數

NSMutableDictionary?*recordSettings?=?[[NSMutableDictionary?alloc]?init];

//?設置編碼格式

/**

kAudioFormatLinearPCM:?無損壓縮,內容非常大

kAudioFormatMPEG4AAC

*/

[recordSettings?setValue?:[NSNumber?numberWithInt:?kAudioFormatLinearPCM]?forKey:?AVFormatIDKey];

//?采樣率(通過測試的數據,根據公司的要求可以再去調整),必須保證和轉碼設置的相同

[recordSettings?setValue?:[NSNumber?numberWithFloat:11025.0]?forKey:?AVSampleRateKey];

//?通道數(必須設置為雙聲道,?不然轉碼生成的?MP3?會聲音尖銳變聲.)

[recordSettings?setValue?:[NSNumber?numberWithInt:2]?forKey:?AVNumberOfChannelsKey];

//音頻質量,采樣質量(音頻質量越高,文件的大小也就越大)

[recordSettings?setValue:[NSNumber?numberWithInt:AVAudioQualityMin]?forKey:AVEncoderAudioQualityKey];

//?3.?創建錄音對象

_audioRecorder?=?[[AVAudioRecorder?alloc]?initWithURL:url?settings:recordSettings?error:nil];

_audioRecorder.meteringEnabled?=?YES;

}

return?_audioRecorder;

}提示:設置 AVAudioSessionCategoryPlayAndRecord: 可以邊播放邊錄音(也就是平時看到的背景音樂)[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

AVSampleRateKey 必須保證和轉碼設置的相同.

AVNumberOfChannelsKey 必須設置為雙聲道, 不然轉碼生成的 MP3 會聲音尖銳變聲.

(2)、開始錄音-?(void)beginRecordWithRecordPath:?(NSString?*)recordPath?{

//?記錄錄音地址

_recordPath?=?recordPath;

//?準備錄音

[self.audioRecorder?prepareToRecord];

//?開始錄音

[self.audioRecorder?record];

}

(3)、結束錄音-?(void)endRecord?{

[self.audioRecorder?stop];

}

(4)、暫停錄音-?(void)pauseRecord?{

[self.audioRecorder?pause];

}

(5)、刪除錄音-?(void)deleteRecord?{

[self.audioRecorder?stop];

[self.audioRecorder?deleteRecording];

}

(6)、重新錄音-?(void)reRecord?{

self.audioRecorder?=?nil;

[self?beginRecordWithRecordPath:self.recordPath];

}

(7)、更新音頻測量值-(void)updateMeters

{

[self.audioRecorder?updateMeters];

}提示:更新音頻測量值,注意如果要更新音頻測量值必須設置meteringEnabled為YES,通過音頻測量值可以即時獲得音頻分貝等信息

@property(getter=isMeteringEnabled) BOOL meteringEnabled:是否啟用音頻測量,默認為NO,一旦啟用音頻測量可以通過updateMeters方法更新測量值

(8)、獲得指定聲道的分貝峰值-?(float)peakPowerForChannel0{

[self.audioRecorder?updateMeters];

return?[self.audioRecorder?peakPowerForChannel:0];

}提示:獲得指定聲道的分貝峰值,注意如果要獲得分貝峰值必須在此之前調用updateMeters方法

二、錄音的編輯

2.1、理論基礎AVAsset:音頻源

AVAssetTrack:素材的軌道

AVMutableComposition :一個用來合成視頻的"合成器"

AVMutableCompositionTrack :"合成器"中的軌道,里面可以插入各種對應的素材

2.2、拼接錄音#pragma?mark?音頻的拼接:追加某個音頻在某個音頻的后面

/**

音頻的拼接

@param?fromPath?前段音頻路徑

@param?toPath?后段音頻路徑

@param?outputPath?拼接后的音頻路徑

*/

+(void)addAudio:(NSString?*)fromPath?toAudio:(NSString?*)toPath?outputPath:(NSString?*)outputPath{

//?1.?獲取兩個音頻源

AVURLAsset?*audioAsset1?=?[AVURLAsset?assetWithURL:[NSURL?fileURLWithPath:fromPath]];

AVURLAsset?*audioAsset2?=?[AVURLAsset?assetWithURL:[NSURL?fileURLWithPath:toPath]];

//?2.?獲取兩個音頻素材中的素材軌道

AVAssetTrack?*audioAssetTrack1?=?[[audioAsset1?tracksWithMediaType:AVMediaTypeAudio]?firstObject];

AVAssetTrack?*audioAssetTrack2?=?[[audioAsset2?tracksWithMediaType:AVMediaTypeAudio]?firstObject];

//?3.?向音頻合成器,?添加一個空的素材容器

AVMutableComposition?*composition?=?[AVMutableComposition?composition];

AVMutableCompositionTrack?*audioTrack?=?[composition?addMutableTrackWithMediaType:AVMediaTypeAudio?preferredTrackID:0];

//?4.?向素材容器中,?插入音軌素材

[audioTrack?insertTimeRange:CMTimeRangeMake(kCMTimeZero,?audioAsset2.duration)?ofTrack:audioAssetTrack2?atTime:kCMTimeZero?error:nil];

[audioTrack?insertTimeRange:CMTimeRangeMake(kCMTimeZero,?audioAsset1.duration)?ofTrack:audioAssetTrack1?atTime:audioAsset2.duration?error:nil];

//?5.?根據合成器,?創建一個導出對象,?并設置導出參數

AVAssetExportSession?*session?=?[[AVAssetExportSession?alloc]?initWithAsset:composition?presetName:AVAssetExportPresetAppleM4A];

session.outputURL?=?[NSURL?fileURLWithPath:outputPath];

//?導出類型

session.outputFileType?=?AVFileTypeAppleM4A;

//?6.?開始導出數據

[session?exportAsynchronouslyWithCompletionHandler:^{

AVAssetExportSessionStatus?status?=?session.status;

/**

AVAssetExportSessionStatusUnknown,

AVAssetExportSessionStatusWaiting,

AVAssetExportSessionStatusExporting,

AVAssetExportSessionStatusCompleted,

AVAssetExportSessionStatusFailed,

AVAssetExportSessionStatusCancelled

*/

switch?(status)?{

case?AVAssetExportSessionStatusUnknown:

NSLog(@"未知狀態");

break;

case?AVAssetExportSessionStatusWaiting:

NSLog(@"等待導出");

break;

case?AVAssetExportSessionStatusExporting:

NSLog(@"導出中");

break;

case?AVAssetExportSessionStatusCompleted:{

NSLog(@"導出成功,路徑是:%@",?outputPath);

}

break;

case?AVAssetExportSessionStatusFailed:

NSLog(@"導出失敗");

break;

case?AVAssetExportSessionStatusCancelled:

NSLog(@"取消導出");

break;

default:

break;

}

}];

}

2.3、音頻的剪切/**

音頻的剪切

@param?audioPath?要剪切的音頻路徑

@param?fromTime?開始剪切的時間點

@param?toTime?結束剪切的時間點

@param?outputPath?剪切成功后的音頻路徑

*/

+(void)cutAudio:(NSString?*)audioPath?fromTime:(NSTimeInterval)fromTime?toTime:(NSTimeInterval)toTime?outputPath:(NSString?*)outputPath{

//?1.?獲取音頻源

AVURLAsset?*asset?=?[AVURLAsset?assetWithURL:[NSURL?fileURLWithPath:audioPath]];

//?2.?創建一個音頻會話,?并且,設置相應的配置

AVAssetExportSession?*session?=?[AVAssetExportSession?exportSessionWithAsset:asset?presetName:AVAssetExportPresetAppleM4A];

session.outputFileType?=?AVFileTypeAppleM4A;

session.outputURL?=?[NSURL?fileURLWithPath:outputPath];

CMTime?startTime?=?CMTimeMake(fromTime,?1);

CMTime?endTime?=?CMTimeMake(toTime,?1);

session.timeRange?=?CMTimeRangeFromTimeToTime(startTime,?endTime);

//?3.?導出

[session?exportAsynchronouslyWithCompletionHandler:^{

AVAssetExportSessionStatus?status?=?session.status;

if?(status?==?AVAssetExportSessionStatusCompleted)

{

NSLog(@"導出成功");

}

}];

}

三、lame靜態庫

3.1、lame 靜態庫簡介

LAME 是一個開源的MP3音頻壓縮軟件。LAME是一個遞歸縮寫,來自LAME Ain't an MP3 Encoder(LAME不是MP3編碼器)。它自1998年以來由一個開源社區開發,目前是公認有損品質MP3中壓縮效果最好的編碼器。

Lame 的轉碼壓縮, 是把錄制的 PCM 轉碼成 MP3, 所以錄制的 AVFormatIDKey 設置成 kAudioFormatLinearPCM(無損壓縮,內容非常大) , 生成的文件可以是 caf 或者 wav.

3.2、如何使用lame

第一步: 下載 lame 的最新版本并解壓

第二步: 把下載的 lame 生成靜態庫,我們使用腳本

下載 build 的腳本

創建一個文件夾放 腳本 與 下載的lame

修改腳本里面的 SOURCE="lame" 名字與 下載的lame名字一致,也可以把 下載的lame名字 改為 lame,那么就不需要改腳本的內容

修改腳本里面的 `SOURCE="lame"` 名字與 下載的lame名字一致,也可以把 下載的lame名字 改為 `lame`,那么就不需要改腳本的內容

改腳本為可執行腳本chmod?+x?build-lame.sh

執行腳本./build-lame.sh

執行腳本的結果如下:生成三個文件

執行腳本的結果如下:生成三個文件提示:我們要的是支持多種架構的 fat-lame 文件,把 fat-lame 里面的 lame.h 與 libmp3lame.a 拖走即可

第三步: 導入靜態庫到工程, 開始使用,我們把代碼都寫在 JKLameTool 類里面,具體的分析放在 3.3

3.3、lame 的使用,代碼都在 JKLameTool 里面

<1>、錄完音頻 統一 caf 轉 mp3,核心代碼如下/**

caf?轉?mp3

如果錄音時間比較長的話,會要等待幾秒...

@param?sourcePath?轉?mp3?的caf?路徑

@param?isDelete?是否刪除原來的?caf?文件,YES:刪除、NO:不刪除

@param?success?成功的回調

@param?fail?失敗的回調

*/

+?(void)audioToMP3:(NSString?*)sourcePath?isDeleteSourchFile:?(BOOL)isDelete?withSuccessBack:(void(^)(NSString?*resultPath))success?withFailBack:(void(^)(NSString?*error))fail{

dispatch_async(dispatch_get_global_queue(0,?0),?^{

//?輸入路徑

NSString?*inPath?=?sourcePath;

//?判斷輸入路徑是否存在

NSFileManager?*fm?=?[NSFileManager?defaultManager];

if?(![fm?fileExistsAtPath:sourcePath])

{

if?(fail)?{

fail(@"文件不存在");

}

return;

}

//?輸出路徑

NSString?*outPath?=?[[sourcePath?stringByDeletingPathExtension]?stringByAppendingString:@".mp3"];

@try?{

int?read,?write;

//source?被轉換的音頻文件位置

FILE?*pcm?=?fopen([inPath?cStringUsingEncoding:1],?"rb");

//skip?file?header

fseek(pcm,?4*1024,?SEEK_CUR);

//output?輸出生成的Mp3文件位置

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_in_samplerate(lame,?11025.0);

lame_set_VBR(lame,?vbr_default);

lame_init_params(lame);

do?{

size_t?size?=?(size_t)(2?*?sizeof(short?int));

read?=?(int)fread(pcm_buffer,?size,?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]);

}

@finally?{

if?(isDelete)?{

NSError?*error;

[fm?removeItemAtPath:sourcePath?error:&error];

if?(error?==?nil)

{

//?NSLog(@"刪除源文件成功");

}

}

if?(success)?{

success(outPath);

}

}

});

}

<2>、caf 轉 mp3 : 錄音的同時轉碼,這個是學習iOS 使用 Lame 轉碼 MP3 的最正確姿勢,代碼結構上在此基礎上進行了封裝和改進,具體的請看 JKLameTool 類,在此不再重復,核心思想如下:邊錄邊轉碼, 只是我們在可以錄制后,重新開一個線程來進行文件的轉碼

當錄音進行中時, 會持續讀取到指定大小文件,進行編碼, 讀取不到,則線程休眠

在 while 的條件中, 我們收到 錄音結束的條件,則會結束 do while 的循環.

我們需要在錄制結束后發送一個信號, 讓 do while 跳出循環

四、上面那么的內容封裝之后使用方式如下

4.1、導入 #import "JKRecorderKit.h",錄音都存在 /Library/Caches/JKRecorder 里面

4.2、使用 JKAudioTool 類進行調用 錄音的一系列操作,如下

開始錄音//?目前使用?caf?格式,?test2:錄音的名字??caf:錄音的格式

[[JKAudioTool?shareJKAudioTool]beginRecordWithRecordName:@"test2"?withRecordType:@"caf"?withIsConventToMp3:YES];

完成錄音[[JKAudioTool?shareJKAudioTool]endRecord];

暫停錄音[[JKAudioTool?shareJKAudioTool]pauseRecord];

刪除錄音[[JKAudioTool?shareJKAudioTool]deleteRecord];

caf 轉 mp3,第一個參數是原音頻的路徑,第二個參數是轉換為 MP3 后是否刪除原來的路徑[JKLameTool?audioToMP3:[cachesRecorderPath?stringByAppendingPathComponent:@"test2.caf"]?isDeleteSourchFile:YES?withSuccessBack:^(NSString?*?_Nonnull?resultPath)?{

NSLog(@"轉為MP3后的路徑=%@",resultPath);

}?withFailBack:^(NSString?*?_Nonnull?error)?{

NSLog(@"轉換失敗:%@",error);

}];提示:更多的內容請看demo里面的封裝

補充:封裝類的說明JKLameTool:對 lame靜態庫的使用

JKSingle:單利的封裝

JKAudioTool:錄音的封裝

JKAudioFileTool:錄音文件的操作,音頻拼接,剪切,m4a格式轉caf格式,caf格式轉m4a格式

JKAudioPlayerTool:音頻的簡單播放封裝

JKAudioFilePathTool:沙盒路徑的一些操作

最后:測試的 demo

推薦博客如下:作者:IIronMan

鏈接:https://www.jianshu.com/p/1a752b92070b

總結

以上是生活随笔為你收集整理的ios 边录音边放_iOS 录音、音频的拼接剪切以及边录边压缩转码的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。