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)")

        }

    }

    

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM