Swift实现iOS录音与播放音频功能

  • 作用
    AVPLayer:可以用来播放在线及本地音视频
    AVAudioSession:音频会话,主要用来管理音频设置与硬件交互
    使用时需要导入
#import <AVFoundation/AVFoundation.h>
  • AVAudioSession中配置选项:
AVAudioSessionCategory
注意:除了 AVAudioSessionCategoryMultiRoute 外,其他的 Category 都遵循 last in wins 原则,即最后接入的音频设备作为输入或输出的主设备。
1.AVAudioSessionCategoryAmbient
当前App的播放声音可以和其他app播放的声音共存,当锁屏或按静音时停止。

2.AVAudioSessionCategorySoloAmbient
只能播放当前App的声音,其他app的声音会停止,当锁屏或按静音时停止。

3.AVAudioSessionCategoryPlayback
只能播放当前App的声音,其他app的声音会停止,当锁屏或按静音时不会停止。

4.AVAudioSessionCategoryRecord
只能用于录音,其他app的声音会停止,当锁屏或按静音时不会停止

5.AVAudioSessionCategoryPlayAndRecord
在录音的同时播放其他声音,当锁屏或按静音时不会停止
可用于听筒播放,比如微信语音消息听筒播放

6.AVAudioSessionCategoryAudioProcessing
使用硬件解码器处理音频,该音频会话使用期间,不能播放或录音

7.AVAudioSessionCategoryMultiRoute
多种音频输入输出,例如可以耳机、USB设备同时播放等
AVAudioSessionCategoryOptions
1.AVAudioSessionModeDefault
默认的模式,适用于所有的场景,可用于场景还原

2.AVAudioSessionModeVoiceChat
适用类别 :
AVAudioSessionCategoryPlayAndRecord 
应用场景VoIP

3.AVAudioSessionModeGameChat
适用类别:
AVAudioSessionCategoryPlayAndRecord 
应用场景游戏录制,由GKVoiceChat自动设置,无需手动调用

4.AVAudioSessionModeVideoRecording
适用类别:
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryRecord 
应用场景视频录制

5.AVAudioSessionModeMoviePlayback
适用类别:
AVAudioSessionCategoryPlayBack
应用场景视频播放

6.AVAudioSessionModeVideoChat
适用类别:
AVAudioSessionCategoryPlayAndRecord
应用场景视频通话

7.AVAudioSessionModeMeasurement
适用类别:
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryRecord
AVAudioSessionCategoryPlayback
AVAudioSessionModeSpokenAudio
AVAudioSessionMode

1.AVAudioSessionCategoryOptionMixWithOthers
适用于:
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryPlayback
AVAudioSessionCategoryMultiRoute 
用于可以和其他app进行混音

2.AVAudioSessionCategoryOptionDuckOthers
适用于:
AVAudioSessionCategoryAmbient
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryPlayback
AVAudioSessionCategoryMultiRoute
用于压低其他声音播放的音量,使期音量变小

3.AVAudioSessionCategoryOptionAllowBluetooth
适用于:
AVAudioSessionCategoryRecord and AVAudioSessionCategoryPlayAndRecord
用于是否支持蓝牙设备耳机等

4.AVAudioSessionCategoryOptionDefaultToSpeaker
适用于:
AVAudioSessionCategoryPlayAndRecord
用于将声音从Speaker播放,外放,即免提

5.AVAudioSessionCategoryOptionInterruptSpokenAudioAndMixWithOthers
适用于:
AVAudioSessionCategoryPlayAndRecord
AVAudioSessionCategoryPlayback
AVAudioSessionCategoryMultiRoute

6.AVAudioSessionCategoryOptionAllowBluetoothA2DP
适用于:
AVAudioSessionCategoryPlayAndRecord
蓝牙和a2dp

7.AVAudioSessionCategoryOptionAllowAirPlay
适用于:
AVAudioSessionCategoryPlayAndRecord
airplay

Swift实现iOS录音与播放音频功能

pastedGraphic.png 狂奔的胖蜗牛 关注

2017.05.01 15:41* 字数 97 阅读 4275评论 2喜欢 6

自己写的一个类,用于swift实现了录音与播放录制的音频的功能。详细的注意点见注释:

import Foundation

import AVFoundation

 

class RecordManager {

    

    

    var recorder: AVAudioRecorder?

    var player: AVAudioPlayer?

    let file_path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first?.appending("/record.wav")

    

    

    //开始录音

    func beginRecord() {

        let session = AVAudioSession.sharedInstance()

        //设置session类型

        do {

            try session.setCategory(AVAudioSessionCategoryPlayAndRecord)

        } catch let err{

            print("设置类型失败:\(err.localizedDescription)")

        }

        //设置session动作

        do {

            try session.setActive(true)

        } catch let err {

            print("初始化动作失败:\(err.localizedDescription)")

        }

        //录音设置,注意,后面需要转换成NSNumber,如果不转换,你会发现,无法录制音频文件,我猜测是因为底层还是用OC写的原因

        let recordSetting: [String: Any] = [AVSampleRateKey: NSNumber(value: 16000),//采样率

                                            AVFormatIDKey: NSNumber(value: kAudioFormatLinearPCM),//音频格式

                                            AVLinearPCMBitDepthKey: NSNumber(value: 16),//采样位数

                                            AVNumberOfChannelsKey: NSNumber(value: 1),//通道数

                                            AVEncoderAudioQualityKey: NSNumber(value: AVAudioQuality.min.rawValue)//录音质量

        ];

        //开始录音

        do {

            let url = URL(fileURLWithPath: file_path!)

            recorder = try AVAudioRecorder(url: url, settings: recordSetting)

            recorder!.prepareToRecord()

            recorder!.record()

            print("开始录音")

        } catch let err {

            print("录音失败:\(err.localizedDescription)")

        }

    }

    

    

    //结束录音

    func stopRecord() {

        if let recorder = self.recorder {

            if recorder.isRecording {

                print("正在录音,马上结束它,文件保存到了:\(file_path!)")

            }else {

                print("没有录音,但是依然结束它")

            }

            recorder.stop()

            self.recorder = nil

        }else {

            print("没有初始化")

        }

    }

    

    

    //播放

    func play() {

        do {

            player = try AVAudioPlayer(contentsOf: URL(fileURLWithPath: file_path!))

            print("歌曲长度:\(player!.duration)")

            player!.play()

        } catch let err {

            print("播放失败:\(err.localizedDescription)")

        }

    }

    

}

使用的时候,只需要在要录音的地方导入该类,初始化后,使用即可

let recoder_manager = RecordManager()//初始化

recoder_manager.beginRecord()//开始录音

recoder_manager.stopRecord()//结束录音

recoder_manager.play()//播放录制的音频

更多的功能,就需要看各自的项目需求,然后去做相应的修改了。

 

 

 

 

将原生社交分享整合到应用中

import UIKit

import Social

class ViewController: UIViewController {

 

    override func viewDidLoad() {

        super.viewDidLoad()

        let serviceType = SLServiceTypeTwitter

        if SLComposeViewController.isAvailable(forServiceType: serviceType) {

            let controller = SLComposeViewController(forServiceType: serviceType)

            controller?.setInitialText("设置想与别人分享的文字")

            controller?.add(UIImage(named: "风向文章中附带的图片"))

            controller?.add(NSURL(string: "为分享文字和图片添加一个URL")! as URL)

            controller?.completionHandler = {

                (result: SLComposeViewControllerResult) in

                print("completed")

            }

        }

        

    }

 

 

}

 

 

 

 

播放音频文件和录音

 

//

//  ViewController.swift

//  SwiftExample

//

//  Created by administrator on 2019/2/15.

//  Copyright © 2019 administrator. All rights reserved.

//

 

import UIKit

import AVFoundation

 

class ViewController: UIViewController,AVAudioPlayerDelegate,AVAudioRecorderDelegate {

 

    var audioPlayer: AVAudioPlayer?

    var audioRecoder: AVAudioRecorder?

    

    /**通知消息,播放器完成播放音频文件的通知**/

    func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flay:  Bool) {

        print("Finish playing the song")

    }

    

    

    override func viewDidLoad() {

        super.viewDidLoad()

       

        DispatchQueue.global().async {[weak self] in

            self?.playAudio()

        }

        let workItem = DispatchWorkItem{

            self.playAudio()

        }

        DispatchQueue.global().async(execute: workItem)

        

        //录音

        let session = AVAudioSession.sharedInstance()

        do {

            if #available(iOS 10.0, *) {

                try session.setCategory(.playAndRecord, mode: .default, options: .duckOthers)

            } else {

                try session.setMode(.default)

                try session.setActive(true, options: .notifyOthersOnDeactivation)

            }

            session.requestRecordPermission { [weak self](allowed: Bool) in

                if allowed {

                    self?.startRecordingAudio()

                }else{

                    print("have no permission")

                }

            }

        } catch let error as NSError {

            print("error \(error)")

        }

        

    }

 

    func playAudio() {

        let mainBundle = Bundle.main

        let filePath = mainBundle.path(forResource: "MySong", ofType: ".mp3")

        if let path = filePath {

            let fileData = NSData(contentsOf: URL(fileURLWithPath: path))

            var error: NSError

            

            do {

                self.audioPlayer = try AVAudioPlayer(data: fileData! as Data)

//                try AVAudioPlayer(contentsOf: URL(fileURLWithPath: path))

                if let player = self.audioPlayer{

                    player.delegate = self

                    if player.prepareToPlay() && player.play(){

                        print("play success")

                    } else {

                        print("play failor")

                    }

                }

            }catch let error as NSError{

                if error != nil{

                    print("创建播放器失败")

                    self.audioPlayer = nil

                }

                

            }

        }

        

    }

    func audioRecodingPath() -> NSURL {

        let fileManager = FileManager()

        var documentsFolderUrl:URL?

    

        do {

            documentsFolderUrl = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

        } catch let error as NSError {

            print("error \(error)")

        }

        return documentsFolderUrl?.appendingPathComponent("recording.m4a") as! NSURL

        

    }

    func audioRecordingSettings() -> NSDictionary {

        //音频录制选项

        return [AVFormatIDKey : kAudioFormatMPEG4AAC,

                AVSampleRateKey : 16000.0 as NSNumber,

                AVNumberOfChannelsKey : 1 as NSNumber,

                AVEncoderAudioQualityKey : AVAudioQuality.low.rawValue as NSNumber]

    }

    func startRecordingAudio() {

        let audioRecordingURL = self.audioRecodingPath()

        do {

            audioRecoder = try AVAudioRecorder(url: audioRecordingURL as URL, settings: self.audioRecordingSettings() as! [String : Any])

            if let recorder = audioRecoder {

                recorder.delegate = self

                if recorder.prepareToRecord() && recorder.record(){

                    let delayInSeconds = 5.0

                    DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delayInSeconds) {

                        self.audioRecoder?.stop()

                    }

//                    DispatchQueue.global().asyncAfter(deadline: DispatchTime.now() + delayInSeconds){}

                    

                }else{

                    print("error")

                }

            }

        } catch let error as NSError {

            print("error \(error)")

        }

    }

    

}

 

posted @ 2019-02-16 10:22  sundayswift  阅读(4413)  评论(0编辑  收藏  举报