音频录制和本地音频播放:
/*
音频录制和播放类
*/
var recorder: AVAudioRecorder?
var player: AVAudioPlayer?
let file_path = PATH_OF_CACHE.appending("/record.wav")
var mp3file_path = PATH_OF_CACHE.appending("/audio.mp3")
private static var _sharedInstance: AudioRecordManager?
private override init() { } // 私有化init方法
/// 单例
///
/// - Returns: 单例对象
class func shared() -> AudioRecordManager {
guard let instance = _sharedInstance else {
_sharedInstance = AudioRecordManager()
return _sharedInstance!
}
return instance
}
/// 销毁单例
class func destroy() {
_sharedInstance = nil
}
//开始录音
func beginRecord() {
let session = AVAudioSession.sharedInstance()
//设置session类型
do {
try session.setCategory(AVAudioSessionCategoryPlayAndRecord)
} catch let err{
Dprint("设置类型失败:\(err.localizedDescription)")
}
//设置session动作
do {
try session.setActive(true)
} catch let err {
Dprint("初始化动作失败:\(err.localizedDescription)")
}
//录音设置,注意,后面需要转换成NSNumber,如果不转换,你会发现,无法录制音频文件,我猜测是因为底层还是用OC写的原因
let recordSetting: [String: Any] = [AVSampleRateKey: NSNumber(value: 44100.0),//采样率
AVFormatIDKey: NSNumber(value: kAudioFormatLinearPCM),//音频格式
AVLinearPCMBitDepthKey: NSNumber(value: 16),//采样位数
AVNumberOfChannelsKey: NSNumber(value: 2),//通道数
AVEncoderAudioQualityKey: NSNumber(value: AVAudioQuality.min.rawValue)//录音质量
];
//开始录音
do {
let url = URL(fileURLWithPath: file_path)
recorder = try AVAudioRecorder(url: url, settings: recordSetting)
recorder!.prepareToRecord()
recorder!.record()
Dprint("开始录音")
} catch let err {
Dprint("录音失败:\(err.localizedDescription)")
}
}
var stopRecordBlock:((_ audioPath:String,_ audioFormat:String)->())?
//结束录音
func stopRecord() {
let session = AVAudioSession.sharedInstance()
//设置session类型
do {
try session.setCategory(AVAudioSessionCategoryPlayback)
} catch let err{
Dprint("设置类型失败:\(err.localizedDescription)")
}
//设置session动作
do {
try session.setActive(true)
} catch let err {
Dprint("初始化动作失败:\(err.localizedDescription)")
}
if let recorder = self.recorder {
if recorder.isRecording {
Dprint("正在录音,马上结束它,文件保存到了:\(file_path)")
let manager = FileManager.default
if manager.fileExists(atPath: mp3file_path) {
do {
try manager.removeItem(atPath: mp3file_path)
} catch let err {
Dprint(err)
}
}
AudioWrapper.audioPCMtoMP3(file_path, andPath: mp3file_path)
Dprint("正在录音,马上结束它,文件保存到了:\(mp3file_path)")
if let block = stopRecordBlock {
block("/audio.mp3","mp3")
}
}else {
Dprint("没有录音,但是依然结束它")
}
recorder.stop()
self.recorder = nil
}else {
Dprint("没有初始化")
}
}
//取消录制
func cancelRecord() {
if let recorder = self.recorder {
if recorder.isRecording {
recorder.stop()
self.recorder = nil
}
}
}
///初始化
func initLocalPlay() {
do {
Dprint(mp3file_path)
player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: mp3file_path))
player?.delegate = self
Dprint("歌曲长度:\(player!.duration)")
} catch let err {
Dprint("播放失败:\(err.localizedDescription)")
}
}
//播放本地音频文件
func play() {
player?.play()
}
//暂停本地音频
func stop() {
player?.pause()
}
var localPlayFinishBlock:(()->())?
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
if let block = AudioRecordManager.shared().localPlayFinishBlock {
block()
}
}
//进度条相关
func progress()->Double{
return (player?.currentTime)!/(player?.duration)!
}
使用时根据单例调用方式调用即可:
AudioRecordManager.shared().beginRecord() //开始录音 AudioRecordManager.shared().stopRecord() //停止录音 AudioRecordManager.shared().initLocalPlay() //初始化本地的音频 AudioRecordManager.shared().play() //播放 AudioRecordManager.shared().stop() //暂停 AudioRecordManager.shared().cancelRecord() //取消录制
// MARK: - 播放流音频
//初始化音频播放,返回音频时长
//播放器相关
var playerItem:AVPlayerItem!
var audioPlayer:AVPlayer!
var audioUrl:String = "" {
didSet{
self.setupPlayerItem()
}
} // 音频url
func initPlay() {
//初始化播放器
audioPlayer = AVPlayer()
//监听音频播放结束
NotificationCenter.default.addObserver(self, selector: #selector(playItemDidReachEnd), name: NSNotification.Name.AVPlayerItemDidPlayToEndTime, object: AudioRecordManager.shared().playerItem)
}
//设置资源
private func setupPlayerItem() {
guard let url = URL(string: audioUrl) else {
return
}
self.playerItem = AVPlayerItem(url: url)
self.audioPlayer.replaceCurrentItem(with: playerItem)
}
//获取音频时长
func getDuration() -> Float64 {
if AudioRecordManager.shared().playerItem == nil {
return 0.0
}
let duration : CMTime = playerItem!.asset.duration
let seconds : Float64 = CMTimeGetSeconds(duration)
return seconds
}
func getCurrentTime() -> Float64 {
if AudioRecordManager.shared().playerItem == nil {
return 0.0
}
let duration : CMTime = playerItem!.currentTime()
let seconds : Float64 = CMTimeGetSeconds(duration)
return seconds
}
//播放结束
var audioPlayEndBlock:(()->())?
func playItemDidReachEnd(notifacation:NSNotification) {
audioPlayer?.seek(to: kCMTimeZero)
if let block = audioPlayEndBlock {
block()
}
}
//播放
func playAudio() {
if audioPlayer != nil {
audioPlayer?.play()
}
}
//暂停
var audioStopBlock:(()->())?
func stopAudio() {
if audioPlayer != nil {
audioPlayer?.pause()
if let block = audioStopBlock {
block()
}
}
}
//销毁
func destroyPlayer() {
if AudioRecordManager.shared().playerItem != nil {
AudioRecordManager.shared().audioPlayer?.pause()
AudioRecordManager.shared().playerItem?.cancelPendingSeeks()
AudioRecordManager.shared().playerItem?.asset.cancelLoading()
}
}
使用方法和上面一样:
AudioRecordManager.shared().initPlay() //初始化
AudioRecordManager.shared().audioUrl = "" // 设置音频资源
let second = AudioRecordManager.shared().getDuration() //获取音频时长
网友评论