首先,这是一个本地音频播放框架.无法播放网络资源.
/// 初始化方法
- (nullable instancetype)initWithContentsOfURL:(NSURL *)url error:(NSError **)outError;
- (nullable instancetype)initWithData:(NSData *)data error:(NSError **)outError;
- (nullable instancetype)initWithContentsOfURL:(NSURL *)url fileTypeHint:(NSString * __nullable)utiString error:(NSError **)outError API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
- (nullable instancetype)initWithData:(NSData *)data fileTypeHint:(NSString * __nullable)utiString error:(NSError **)outError API_AVAILABLE(macos(10.9), ios(7.0), watchos(2.0), tvos(9.0));
/// 播放前准备方法,play方法会默认执行prepareToPlay方法.(创建的时候就执行此方法可以让播放响应时间更快)
- (BOOL)prepareToPlay; /* get ready to play the sound. happens automatically on play. */
- (BOOL)play; /* sound is played asynchronously. */
/// 执行到某个时间
- (BOOL)playAtTime:(NSTimeInterval)time API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)); /* play a sound some time in the future. time is an absolute time based on and greater than deviceCurrentTime. */
/// 暂停
- (void)pause; /* pauses playback, but remains ready to play. */
/// 停止
- (void)stop; /* stops playback. no longer ready to play. */
/// 是否正在播放(当前播放状态)
@property(readonly, getter=isPlaying) BOOL playing; /* is it playing or not? */
/// 当前音频是几声道的
@property(readonly) NSUInteger numberOfChannels;
/// 音频时长
@property(readonly) NSTimeInterval duration; /* the duration of the sound. */
/// 当前音频设备的UID
@property(copy, nullable) NSString *currentDevice API_AVAILABLE(macos(10.13)) API_UNAVAILABLE(ios, watchos, tvos);
/// AVAudioPlayerDelegate
@property(weak, nullable) id<AVAudioPlayerDelegate> delegate;
/// 创建的url
@property(readonly, nullable) NSURL *url; /* returns nil if object was not created with a URL */
/// 通过data的方式创建的
@property(readonly, nullable) NSData *data; /* returns nil if object was not created with a data object */
/// 左右声道. -1.0为左声道,1.0为右声道.
@property float pan API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));
/// 音量0.0 - 1.0
@property float volume;
/// 在duration的时间内,音量渐渐淡化至volume
- (void)setVolume:(float)volume fadeDuration:(NSTimeInterval)duration API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0));
/// 要为音频播放器启用可调节播放速率,在为播放器调用prepareToPlay(play)方法之前将此属性设置为YES。
@property BOOL enableRate API_AVAILABLE(macos(10.8), ios(5.0), watchos(2.0), tvos(9.0));
/// 播放速率1.0是正常速度.0.5是半速.2.0是双倍速度
@property float rate API_AVAILABLE(macos(10.8), ios(5.0), watchos(2.0), tvos(9.0));
/// 播放器当前时间
@property NSTimeInterval currentTime;
/// 输出设备关联的当前时间
@property(readonly) NSTimeInterval deviceCurrentTime API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0));
/// 循环次数.0表示不循环.1表示播放两次.所有的负数都是无限循环
@property NSInteger numberOfLoops;
/// 设置
@property(readonly) NSDictionary<NSString *, id> *settings API_AVAILABLE(macos(10.7), ios(4.0), watchos(2.0), tvos(9.0)); /* returns a settings dictionary with keys as described in AVAudioSettings.h */
/// 返回音频信息
@property(readonly) AVAudioFormat *format API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0));
// MARK: 测量有关
/// 是否支持测量
@property(getter=isMeteringEnabled) BOOL meteringEnabled;
/// 更新测量的值
- (void)updateMeters;
/// 正在播放声音通道的分贝值
- (float)peakPowerForChannel:(NSUInteger)channelNumber
/// 平均分贝
- (float)averagePowerForChannel:(NSUInteger)channelNumber;
///
@property(nonatomic, copy, nullable) NSArray<AVAudioSessionChannelDescription *> *channelAssignments API_AVAILABLE(ios(7.0), watchos(2.0), tvos(9.0)) API_UNAVAILABLE(macos) ; /* Array of AVAudioSessionChannelDescription objects */;
@end
AVAudioPlayerDelegate
@protocol AVAudioPlayerDelegate <NSObject>
@optional
/// 音频播放完毕后调用.不会被打断调用(类似开启其他App打断)
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
/// 解码错误时调用
- (void)audioPlayerDecodeErrorDidOccur:(AVAudioPlayer *)player error:(NSError * __nullable)error;
// MARK: 下面的AVAudioPlayer的打断通知已经被废弃了.用AVAudioSession去代替(然而下面的代理方法还是有回调)
/// 当player正在播放的时候audio session被打断就会调用此方法.player将会被暂停
- (void)audioPlayerBeginInterruption:(AVAudioPlayer *)player NS_DEPRECATED_IOS(2_2, 8_0);
/// 当打断完成之后的回调代理方法.
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withOptions:(NSUInteger)flags NS_DEPRECATED_IOS(6_0, 8_0);
/// 打断完成后回调代理方法.
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags NS_DEPRECATED_IOS(4_0, 6_0);
/// `- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player withFlags:(NSUInteger)flags`这个代理不实现的话就会走这个
- (void)audioPlayerEndInterruption:(AVAudioPlayer *)player NS_DEPRECATED_IOS(2_2, 6_0);
使用用例
NSString *path = [[NSBundle mainBundle] pathForResource:@"The Cranberries - Just My Imagination" ofType:@"mp3"];
NSURL *fileURL = [NSURL fileURLWithPath:path];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
注意,切换歌曲的时候应该这样
[self.audioPlayer stop];
self.audioPlayer = nil;
NSString *path = [[NSBundle mainBundle] pathForResource:@"The Cranberries - Just My Imagination" ofType:@"mp3"];
NSURL *fileURL = [NSURL fileURLWithPath:path];
self.audioPlayer = [self.audioPlayer initWithContentsOfURL:fileURL error:nil];
[self.audioPlayer prepareToPlay];
[self.audioPlayer play];
不然就会有多个声音同时播放的情况