【iOS开发-118】AVFoundation框架:AudioServices...音效,AVAudioPlayer音乐,AVAudioRecord录音

本文详细介绍iOS平台下音视频开发的核心代码实现,包括音效播放、音乐播放、录音及后台音乐播放等功能。通过具体实例展示了如何使用AVFoundation框架完成音视频的基本操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(1)音效播放,核心代码,主要是创建一个播放器,然后播放。

#import "WPSound.h"
#import <AVFoundation/AVFoundation.h>

@implementation WPSound
static NSMutableDictionary *_soundIDDict;
+(void)initialize{
    _soundIDDict=[NSMutableDictionary dictionary];
}
//不能用懒加载,因为给用户使用的时类方法,所以需要在上面的类初始化中设置
//-(NSMutableDictionary *)soundIDDict{
//    if (_soundIDDict==nil) {
//        _soundIDDict=[NSMutableDictionary dictionary];
//    }
//    return _soundIDDict;
//}

+(void)soundPlay:(NSString *)fileName{
    if (!fileName) return;
    //取出soundID
    SystemSoundID soundID=[_soundIDDict[fileName] unsignedIntValue];
    if (!soundID) {
        NSURL *url=[[NSBundle mainBundle]URLForResource:fileName withExtension:nil];
        if (!url) return;
        AudioServicesCreateSystemSoundID((__bridge CFURLRef)url, &soundID);
        //放入字典
        _soundIDDict[fileName]=@(soundID);
    }
    AudioServicesPlaySystemSound(soundID);
}

+(void)soundDispose:(NSString *)fileName{
    if (fileName) return;
    SystemSoundID soundID=[_soundIDDict[fileName] unsignedIntValue];
    if (!soundID) return;
    AudioServicesDisposeSystemSoundID(soundID);
    //从字典中移除
    [_soundIDDict removeObjectForKey:fileName];
}
@end


(2)音乐播放,核心代码。需要注意的是创建的播放器需要是全局变量。

#import "MusicTool.h"

@implementation MusicTool
static NSMutableDictionary *_audioPlayerDict;
static AVAudioPlayer *_audioPlayer;

+(void)initialize{
    _audioPlayerDict=[NSMutableDictionary dictionary];
    //设置会话类型
    AVAudioSession *session=[AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
    [session setActive:YES error:nil];
}

+(AVAudioPlayer *)musicPlay:(NSString *)fileName{
    if (!fileName) return nil;
    //取出播放器
    AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
    if (!audioPlayer) {
        NSURL *url=[[NSBundle mainBundle]URLForResource:fileName withExtension:nil];
        if (!url) return nil;
        //创建audioPlayer
        AVAudioPlayer *audioPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:NULL];
        _audioPlayer=audioPlayer;
        [_audioPlayer prepareToPlay];
        _audioPlayer.enableRate=YES;
        //以下设置播放速度,可以测试用
//        _audioPlayer.rate=10;
//        _audioPlayerDict[fileName]=audioPlayer;
    }
    if (!_audioPlayer.isPlaying) {
        [_audioPlayer play];
    }
    return _audioPlayer;
}

+(void)musicPause:(NSString *)fileName{
    if (!fileName) return;
    AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
    if (audioPlayer.isPlaying) {
        [audioPlayer pause];
    }
}

+(void)musicStop:(NSString *)fileName{
    if (!fileName) return;
    AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
    if (audioPlayer.isPlaying) {
        [audioPlayer stop];
        [_audioPlayerDict removeObjectForKey:fileName];
    }
}

+(AVAudioPlayer *)currentPlayingAudioPlayer{
    for (NSString *fileName in _audioPlayerDict) {
        AVAudioPlayer *audioPlayer=_audioPlayerDict[fileName];
        if (audioPlayer.isPlaying) {
            return audioPlayer;
        }
    }
    return nil;
}
@end

(3)录音,核心代码。

#import "ViewController.h"
#import <AVFoundation/AVFoundation.h>

@interface ViewController ()
@property(nonatomic,strong) AVAudioRecorder *recorder;
@property(nonatomic,strong) CADisplayLink *link;
@property(nonatomic,assign) float silentDuration;
- (IBAction)recordStart:(id)sender;
- (IBAction)recordStop:(id)sender;
@end

@implementation ViewController

-(CADisplayLink *)link{
    if (_link==nil) {
        _link=[CADisplayLink displayLinkWithTarget:self selector:@selector(update)];
    }
    return _link;
}

-(void)update{
    //更新录音器的测量值
    [self.recorder updateMeters];
    //获得平均分贝
    float power=[self.recorder averagePowerForChannel:0];
    
    if (power<-30) {
        self.silentDuration+=self.link.duration;
        if (self.silentDuration>=2) {
            [self.recorder stop];
            [self.link invalidate];
            self.link=nil;
        }
    }else{
        self.silentDuration=0;
    }
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (IBAction)recordStart:(id)sender {
    NSString *path=[[NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"test.caf"];
    NSURL *url=[NSURL fileURLWithPath:path];
    NSMutableDictionary *setting=[NSMutableDictionary dictionary];
    //音频格式
    setting[AVFormatIDKey]=@(kAudioFormatAppleIMA4);
    //音频采样率
    setting[AVSampleRateKey]=@(8000.0);
    //音频通道数
    setting[AVNumberOfChannelsKey]=@(1);
    //线性音频位深度
    setting[AVLinearPCMBitDepthKey]=@(8);
    
    AVAudioRecorder *recorder=[[AVAudioRecorder alloc]initWithURL:url settings:setting error:nil];
    
    //允许测量分贝
    recorder.meteringEnabled=YES;
    
    //缓冲
    [recorder prepareToRecord];
    //录音
    [recorder record];
    
    self.recorder=recorder;
    
    //开启定时器
    self.silentDuration=0;
    [self.link addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];
}

- (IBAction)recordStop:(id)sender {
    [self.link invalidate];
    self.link=nil;
    [self.recorder stop];
}
@end

(3)后台播放音乐,设置3处地方。

——在AppDelegate.m中设置

- (void)applicationDidEnterBackground:(UIApplication *)application {
    [application beginBackgroundTaskWithExpirationHandler:nil];
}

——在info.plist中设置


——还有一个在程序中设置音频会话类型(可省略)

+(void)initialize{
    _audioPlayerDict=[NSMutableDictionary dictionary];
    //设置会话类型
    AVAudioSession *session=[AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategorySoloAmbient error:nil];
    [session setActive:YES error:nil];
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值