1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > ios 边录音边放_iOS 录音 音频的拼接剪切以及边录边压缩转码

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

时间:2023-07-25 07:54:46

相关推荐

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:可以边播放边录音(也就是平时看到的背景音乐)

*/

[[AVAudioSessionsharedInstance]setCategory:AVAudioSessionCategoryPlayAndRecorderror:nil];

//启动会话

[[AVAudioSessionsharedInstance]setActive:YESerror:nil];

//1.确定录音存放的位置

NSURL*url=[NSURLURLWithString:self.recordPath];

//2.设置录音参数

NSMutableDictionary*recordSettings=[[NSMutableDictionaryalloc]init];

//设置编码格式

/**

kAudioFormatLinearPCM:无损压缩,内容非常大

kAudioFormatMPEG4AAC

*/

[recordSettingssetValue:[NSNumbernumberWithInt:kAudioFormatLinearPCM]forKey:AVFormatIDKey];

//采样率(通过测试的数据,根据公司的要求可以再去调整),必须保证和转码设置的相同

[recordSettingssetValue:[NSNumbernumberWithFloat:11025.0]forKey:AVSampleRateKey];

//通道数(必须设置为双声道,不然转码生成的MP3会声音尖锐变声.)

[recordSettingssetValue:[NSNumbernumberWithInt:2]forKey:AVNumberOfChannelsKey];

//音频质量,采样质量(音频质量越高,文件的大小也就越大)

[recordSettingssetValue:[NSNumbernumberWithInt:AVAudioQualityMin]forKey:AVEncoderAudioQualityKey];

//3.创建录音对象

_audioRecorder=[[AVAudioRecorderalloc]initWithURL:urlsettings:recordSettingserror:nil];

_audioRecorder.meteringEnabled=YES;

}

return_audioRecorder;

}提示:设置 AVAudioSessionCategoryPlayAndRecord: 可以边播放边录音(也就是平时看到的背景音乐)[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayAndRecord error:nil];

AVSampleRateKey 必须保证和转码设置的相同.

AVNumberOfChannelsKey 必须设置为双声道, 不然转码生成的 MP3 会声音尖锐变声.

(2)、开始录音-(void)beginRecordWithRecordPath:(NSString*)recordPath{

//记录录音地址

_recordPath=recordPath;

//准备录音

[self.audioRecorderprepareToRecord];

//开始录音

[self.audioRecorderrecord];

}

(3)、结束录音-(void)endRecord{

[self.audioRecorderstop];

}

(4)、暂停录音-(void)pauseRecord{

[self.audioRecorderpause];

}

(5)、删除录音-(void)deleteRecord{

[self.audioRecorderstop];

[self.audioRecorderdeleteRecording];

}

(6)、重新录音-(void)reRecord{

self.audioRecorder=nil;

[selfbeginRecordWithRecordPath:self.recordPath];

}

(7)、更新音频测量值-(void)updateMeters

{

[self.audioRecorderupdateMeters];

}提示:更新音频测量值,注意如果要更新音频测量值必须设置meteringEnabled为YES,通过音频测量值可以即时获得音频分贝等信息

@property(getter=isMeteringEnabled) BOOL meteringEnabled:是否启用音频测量,默认为NO,一旦启用音频测量可以通过updateMeters方法更新测量值

(8)、获得指定声道的分贝峰值-(float)peakPowerForChannel0{

[self.audioRecorderupdateMeters];

return[self.audioRecorderpeakPowerForChannel:0];

}提示:获得指定声道的分贝峰值,注意如果要获得分贝峰值必须在此之前调用updateMeters方法

二、录音的编辑

2.1、理论基础AVAsset:音频源

AVAssetTrack:素材的轨道

AVMutableComposition :一个用来合成视频的"合成器"

AVMutableCompositionTrack :"合成器"中的轨道,里面可以插入各种对应的素材

2.2、拼接录音#pragmamark音频的拼接:追加某个音频在某个音频的后面

/**

音频的拼接

@paramfromPath前段音频路径

@paramtoPath后段音频路径

@paramoutputPath拼接后的音频路径

*/

+(void)addAudio:(NSString*)fromPathtoAudio:(NSString*)toPathoutputPath:(NSString*)outputPath{

//1.获取两个音频源

AVURLAsset*audioAsset1=[AVURLAssetassetWithURL:[NSURLfileURLWithPath:fromPath]];

AVURLAsset*audioAsset2=[AVURLAssetassetWithURL:[NSURLfileURLWithPath:toPath]];

//2.获取两个音频素材中的素材轨道

AVAssetTrack*audioAssetTrack1=[[audioAsset1tracksWithMediaType:AVMediaTypeAudio]firstObject];

AVAssetTrack*audioAssetTrack2=[[audioAsset2tracksWithMediaType:AVMediaTypeAudio]firstObject];

//3.向音频合成器,添加一个空的素材容器

AVMutableComposition*composition=[AVMutableCompositioncomposition];

AVMutableCompositionTrack*audioTrack=[compositionaddMutableTrackWithMediaType:AVMediaTypeAudiopreferredTrackID:0];

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

[audioTrackinsertTimeRange:CMTimeRangeMake(kCMTimeZero,audioAsset2.duration)ofTrack:audioAssetTrack2atTime:kCMTimeZeroerror:nil];

[audioTrackinsertTimeRange:CMTimeRangeMake(kCMTimeZero,audioAsset1.duration)ofTrack:audioAssetTrack1atTime:audioAsset2.durationerror:nil];

//5.根据合成器,创建一个导出对象,并设置导出参数

AVAssetExportSession*session=[[AVAssetExportSessionalloc]initWithAsset:compositionpresetName:AVAssetExportPresetAppleM4A];

session.outputURL=[NSURLfileURLWithPath:outputPath];

//导出类型

session.outputFileType=AVFileTypeAppleM4A;

//6.开始导出数据

[sessionexportAsynchronouslyWithCompletionHandler:^{

AVAssetExportSessionStatusstatus=session.status;

/**

AVAssetExportSessionStatusUnknown,

AVAssetExportSessionStatusWaiting,

AVAssetExportSessionStatusExporting,

AVAssetExportSessionStatusCompleted,

AVAssetExportSessionStatusFailed,

AVAssetExportSessionStatusCancelled

*/

switch(status){

caseAVAssetExportSessionStatusUnknown:

NSLog(@"未知状态");

break;

caseAVAssetExportSessionStatusWaiting:

NSLog(@"等待导出");

break;

caseAVAssetExportSessionStatusExporting:

NSLog(@"导出中");

break;

caseAVAssetExportSessionStatusCompleted:{

NSLog(@"导出成功,路径是:%@",outputPath);

}

break;

caseAVAssetExportSessionStatusFailed:

NSLog(@"导出失败");

break;

caseAVAssetExportSessionStatusCancelled:

NSLog(@"取消导出");

break;

default:

break;

}

}];

}

2.3、音频的剪切/**

音频的剪切

@paramaudioPath要剪切的音频路径

@paramfromTime开始剪切的时间点

@paramtoTime结束剪切的时间点

@paramoutputPath剪切成功后的音频路径

*/

+(void)cutAudio:(NSString*)audioPathfromTime:(NSTimeInterval)fromTimetoTime:(NSTimeInterval)toTimeoutputPath:(NSString*)outputPath{

//1.获取音频源

AVURLAsset*asset=[AVURLAssetassetWithURL:[NSURLfileURLWithPath:audioPath]];

//2.创建一个音频会话,并且,设置相应的配置

AVAssetExportSession*session=[AVAssetExportSessionexportSessionWithAsset:assetpresetName:AVAssetExportPresetAppleM4A];

session.outputFileType=AVFileTypeAppleM4A;

session.outputURL=[NSURLfileURLWithPath:outputPath];

CMTimestartTime=CMTimeMake(fromTime,1);

CMTimeendTime=CMTimeMake(toTime,1);

session.timeRange=CMTimeRangeFromTimeToTime(startTime,endTime);

//3.导出

[sessionexportAsynchronouslyWithCompletionHandler:^{

AVAssetExportSessionStatusstatus=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+xbuild-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

如果录音时间比较长的话,会要等待几秒...

@paramsourcePath转mp3的caf路径

@paramisDelete是否删除原来的caf文件,YES:删除、NO:不删除

@paramsuccess成功的回调

@paramfail失败的回调

*/

+(void)audioToMP3:(NSString*)sourcePathisDeleteSourchFile:(BOOL)isDeletewithSuccessBack:(void(^)(NSString*resultPath))successwithFailBack:(void(^)(NSString*error))fail{

dispatch_async(dispatch_get_global_queue(0,0),^{

//输入路径

NSString*inPath=sourcePath;

//判断输入路径是否存在

NSFileManager*fm=[NSFileManagerdefaultManager];

if(![fmfileExistsAtPath:sourcePath])

{

if(fail){

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

}

return;

}

//输出路径

NSString*outPath=[[sourcePathstringByDeletingPathExtension]stringByAppendingString:@".mp3"];

@try{

intread,write;

//source被转换的音频文件位置

FILE*pcm=fopen([inPathcStringUsingEncoding:1],"rb");

//skipfileheader

fseek(pcm,4*1024,SEEK_CUR);

//output输出生成的Mp3文件位置

FILE*mp3=fopen([outPathcStringUsingEncoding:1],"wb");

constintPCM_SIZE=8192;

constintMP3_SIZE=8192;

shortintpcm_buffer[PCM_SIZE*2];

unsignedcharmp3_buffer[MP3_SIZE];

lame_tlame=lame_init();

lame_set_in_samplerate(lame,11025.0);

lame_set_VBR(lame,vbr_default);

lame_init_params(lame);

do{

size_tsize=(size_t)(2*sizeof(shortint));

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(@"%@",[exceptiondescription]);

}

@finally{

if(isDelete){

NSError*error;

[fmremoveItemAtPath:sourcePatherror:&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:录音的格式

[[JKAudioToolshareJKAudioTool]beginRecordWithRecordName:@"test2"withRecordType:@"caf"withIsConventToMp3:YES];

完成录音[[JKAudioToolshareJKAudioTool]endRecord];

暂停录音[[JKAudioToolshareJKAudioTool]pauseRecord];

删除录音[[JKAudioToolshareJKAudioTool]deleteRecord];

caf 转 mp3,第一个参数是原音频的路径,第二个参数是转换为 MP3 后是否删除原来的路径[JKLameToolaudioToMP3:[cachesRecorderPathstringByAppendingPathComponent:@"test2.caf"]isDeleteSourchFile:YESwithSuccessBack:^(NSString*_NonnullresultPath){

NSLog(@"转为MP3后的路径=%@",resultPath);

}withFailBack:^(NSString*_Nonnullerror){

NSLog(@"转换失败:%@",error);

}];提示:更多的内容请看demo里面的封装

补充:封装类的说明JKLameTool:对 lame静态库的使用

JKSingle:单利的封装

JKAudioTool:录音的封装

JKAudioFileTool:录音文件的操作,音频拼接,剪切,m4a格式转caf格式,caf格式转m4a格式

JKAudioPlayerTool:音频的简单播放封装

JKAudioFilePathTool:沙盒路径的一些操作

最后:测试的 demo

推荐博客如下:作者:IIronMan

链接:/p/1a752b92070b

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。