// // YMAudioPlayer.m // MSYOUPAI // // Created by YoMi on 2024/2/25. // Copyright © 2024 MS. All rights reserved. // #import "YMAudioPlayer.h" @interface YMAudioPlayer () /** 播放状态 */ @property (nonatomic, readwrite) FSAudioStreamState state; /** 用于总时间的获取 */ @property (nonatomic, copy) NSString *totalTime; @end @implementation YMAudioPlayer - (FSAudioStream *)audioStream { if (!_audioStream) { _audioStream = [[FSAudioStream alloc] init]; _audioStream.strictContentTypeChecking = NO; _audioStream.defaultContentType = @"audio/mpeg"; } return _audioStream; } + (instancetype)sharedInstance { static YMAudioPlayer *instance = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[YMAudioPlayer alloc] init]; }); return instance; } - (instancetype)init { if (self = [super init]) { self.state = kFsAudioStreamStopped; } return self; } #pragma mark - Setter - (void)setPlayUrlStr:(NSString *)playUrlStr { // 当前播放链接与传入链接一致 if ([self.playUrlStr isEqual:playUrlStr]) { if (self.state == kFsAudioStreamPlaying) { return; } if (self.state == kFsAudioStreamPaused) { [self.audioStream play]; return; } if (self.state == kFsAudioStreamBuffering) { return; } } _playUrlStr = playUrlStr; if (self.state == kFsAudioStreamPlaying) { [self stop]; } NSURL *audioUrl = [NSURL URLWithString:playUrlStr]; [self.audioStream playFromURL:audioUrl]; __weak typeof(self) weakSelf = self; // 播放完成回调事件 [self.audioStream setOnCompletion:^{ NSLog(@"完成了"); if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(audioPlayerDidPlayMusicCompleted)]) { [weakSelf.delegate performSelector:@selector(audioPlayerDidPlayMusicCompleted)]; } }]; [self.audioStream setOnStateChange:^(FSAudioStreamState state) { weakSelf.state = state; if (weakSelf.delegate && [weakSelf.delegate respondsToSelector:@selector(audioPlayer:stateChangeWithState:)]) { [weakSelf.delegate audioPlayer:weakSelf stateChangeWithState:weakSelf.state]; } }]; self.audioStream.onFailure = ^(FSAudioStreamError error, NSString *errorDescription) { NSString *errorCategory; switch (error) { case kFsAudioStreamErrorOpen: errorCategory = @"无法打开音频流:"; break; case kFsAudioStreamErrorStreamParse: errorCategory = @"无法读取音频流:"; break; case kFsAudioStreamErrorNetwork: errorCategory = @"网络故障:无法播放音频流:"; break; case kFsAudioStreamErrorUnsupportedFormat: errorCategory = @"不支持的格式:"; break; case kFsAudioStreamErrorStreamBouncing: errorCategory = @"网络故障:无法获得足够的数据进行播放:"; break; default: errorCategory = @"出现未知错误:"; break; } NSString *formattedError = [NSString stringWithFormat:@"%@ %@", errorCategory, errorDescription]; NSLog(@"%@", formattedError); }; } // 设置音频播放进度 - (void)setProgress:(float)progress { FSStreamPosition pos = {0}; pos.position = progress; [self.audioStream seekToPosition:pos]; } #pragma mark - Public Method - (void)play { if (self.state == kFsAudioStreamStopped) { [self.audioStream play]; } if (self.state == kFsAudioStreamPaused) { [self resume]; } } // 暂停 - (void)pause { if (self.state == kFsAudioStreamPlaying) { [self.audioStream pause]; } } // 恢复 - (void)resume { if (self.state == kFsAudioStreamPaused) { [self.audioStream pause]; } } // 停止播放 - (void)stop { if (self.state != kFsAudioStreamStopped) { [self.audioStream stop]; } } @end