gpt4 book ai didi

ios - 如何录制音频并将其保存到 Sandbox?

转载 作者:行者123 更新时间:2023-11-28 13:29:31 28 4
gpt4 key购买 nike

我正在开发记录用户音频的应用程序,并在表格 View 的另一个屏幕上显示从此应用程序制作的所有早期录音。单击特定行时,必须播放录音。我如何实现这一目标,是否有任何资源可以帮助我实现同样的目标?

我的代码当前保存录音并在同一屏幕上播放。但是,新的录音会覆盖之前的录音,并且只有一个录音会保存到文件管理器中。我在 plist 中添加了“隐私 - 需要使用麦克风”。录音并播放成功。

import UIKit
import AVFoundation
import MobileCoreServices



class ViewController: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate{

@IBOutlet var recordingTimeLabel: UILabel!
@IBOutlet var record_btn_ref: UIButton!
@IBOutlet var play_btn_ref: UIButton!

//Variables:
var audioRecorder: AVAudioRecorder!
var audioPlayer : AVAudioPlayer!
var meterTimer:Timer!
var isAudioRecordingGranted: Bool!
var isRecording = false
var isPlaying = false


override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.

//Check recording permission:

check_record_permission()

//Add right bar button:

navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Documents", style: .plain, target: self, action: #selector(OpenDoc))

}
//Button action to start recording:
@IBAction func start_recording(_ sender: UIButton)
{
//If already recording:
if(isRecording)
{
//Stop recording:
finishAudioRecording(success: true)
//Set the title back to "Record":
record_btn_ref.setTitle("Record", for: .normal)
//Enable the play button:
play_btn_ref.isEnabled = true
//Set the value of the variable "isRecording" to false
isRecording = false
}
//If audio was not being recorded:
else
{
//Setup the recorder:
setup_recorder()
//Start recording:
audioRecorder.record()
//Update label every 1 sec:
meterTimer = Timer.scheduledTimer(timeInterval: 0.1, target:self, selector:#selector(self.updateAudioMeter(timer:)), userInfo:nil, repeats:true)
//Set the title of the label to "Stop":
record_btn_ref.setTitle("Stop", for: .normal)
//Enable the play button:
play_btn_ref.isEnabled = false
//Set "isRecording" to true:
isRecording = true
}
}


//Button action for play/pause:
@IBAction func play_recording(_ sender: Any)
{
//If audio is already being played (i.e. it should pause on being clicked again):
if(isPlaying)
{
//Stop audio player
audioPlayer.stop()
//Enable record button:
record_btn_ref.isEnabled = true
//Set the title to "Play"
play_btn_ref.setTitle("Play", for: .normal)
//Set value of "isPlaying" to false:
isPlaying = false
}
//It is not playing (i.e. it should play when button is clicked)
else
{
//If file path exists:
if FileManager.default.fileExists(atPath: getFileUrl().path)
{
//Disable the record button:
record_btn_ref.isEnabled = false
//Set the title of the button to "Pause":
play_btn_ref.setTitle("Pause", for: .normal)
//Prepare to play:
prepare_play()
//Implement play method of audioPlayer:
audioPlayer.play()
//Set variable "isPlaying" to true:
isPlaying = true
}
//If file path doesn't exist:
else
{
display_alert(msg_title: "Error", msg_desc: "Audio file is missing.", action_title: "OK")
}
}
}


//Function that checks permission to record:

func check_record_permission()
{
//Switch record permission instances:

switch AVAudioSession.sharedInstance().recordPermission {
//Case granted:
case AVAudioSessionRecordPermission.granted:
isAudioRecordingGranted = true
break
//Case denied:
case AVAudioSessionRecordPermission.denied:
isAudioRecordingGranted = false
break
//Case not determined, in which case ask for permission:
case AVAudioSessionRecordPermission.undetermined:
AVAudioSession.sharedInstance().requestRecordPermission({ (allowed) in
if allowed {
self.isAudioRecordingGranted = true
} else {
self.isAudioRecordingGranted = false
}
})
break
//Default case:
default:
break
}
}


//Function that gets the directory path:
func getDocumentsDirectory() -> URL
{
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}

//Function that gets the URL file path:
func getFileUrl() -> URL
{
let filename = "myRecording.m4a"
let filePath = getDocumentsDirectory().appendingPathComponent(filename)

return filePath
}

//Function that sets up the recorder:
func setup_recorder()
{
if isAudioRecordingGranted
{
let session = AVAudioSession.sharedInstance()
do
{
try session.setCategory(AVAudioSession.Category.playAndRecord, options: .defaultToSpeaker)
try session.setActive(true)
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 44100,
AVNumberOfChannelsKey: 2,
AVEncoderAudioQualityKey:AVAudioQuality.high.rawValue
]
audioRecorder = try AVAudioRecorder(url: getFileUrl(), settings: settings)
audioRecorder.delegate = self
audioRecorder.isMeteringEnabled = true
audioRecorder.prepareToRecord()
}
catch let error {
display_alert(msg_title: "Error", msg_desc: error.localizedDescription, action_title: "OK")
}
}
else
{
display_alert(msg_title: "Error", msg_desc: "Don't have access to use your microphone.", action_title: "OK")
}
}



//Objective C function to update text of the timer label:
@objc func updateAudioMeter(timer: Timer)
{
if audioRecorder.isRecording
{
let hr = Int((audioRecorder.currentTime / 60) / 60)
let min = Int(audioRecorder.currentTime / 60)
let sec = Int(audioRecorder.currentTime.truncatingRemainder(dividingBy: 60))
let totalTimeString = String(format: "%02d:%02d:%02d", hr, min, sec)
recordingTimeLabel.text = totalTimeString
audioRecorder.updateMeters()
}
}

//Function for finish audio recording:
func finishAudioRecording(success: Bool)
{
//If recording was successful:
if success
{
audioRecorder.stop()
audioRecorder = nil
meterTimer.invalidate()
print("recorded successfully.")


}
//If recording was not successful:
else
{
display_alert(msg_title: "Error", msg_desc: "Recording failed.", action_title: "OK")
}
}


//Prepare to play:
func prepare_play()
{
do
{
audioPlayer = try AVAudioPlayer(contentsOf: getFileUrl())
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
}
catch{
print("Error")
}
}




//Function for audio record did finish recording:

func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool)
{
if !flag
{
finishAudioRecording(success: false)
}
play_btn_ref.isEnabled = true



}

//If recorded audio was played:

func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool)
{
record_btn_ref.isEnabled = true
play_btn_ref.setTitle("Play", for: .normal)
}

//Function to display alerts:

func display_alert(msg_title : String , msg_desc : String ,action_title : String)
{
let ac = UIAlertController(title: msg_title, message: msg_desc, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: action_title, style: .default)
{
(result : UIAlertAction) -> Void in
_ = self.navigationController?.popViewController(animated: true)
})
present(ac, animated: true)
}




@objc func OpenDoc()
{
let documentPicker = UIDocumentPickerViewController(documentTypes: [kUTTypeMPEG4Audio as String], in: .import)
documentPicker.delegate = self as? UIDocumentPickerDelegate
documentPicker.allowsMultipleSelection = false
present(documentPicker, animated: true, completion: nil)
}

}

最佳答案

My code currently saves the recording and plays it on the same screen. However, new recordings overwrite earlier ones and only one recording is saved into the file manager.

据我所知,您在此函数 func getFileUrl() 中为录音指定了相同的名称。使每个记录具有不同名称的最简单方法是为其添加时间戳,例如使用 Date()timeIntervalSince1970

func getFileUrl() -> URL
{
let currentTime = Date().timeIntervalSince1970
let filename = "myRecording-\(currentTime).m4a"
let filePath = getDocumentsDirectory().appendingPathComponent(filename)

return filePath
}

接下来,您的 play_recording 函数应该从另一个屏幕上的 TableView 获取录音的 URL 作为参数。

关于ios - 如何录制音频并将其保存到 Sandbox?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57624706/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com