我正在创建一个应用程序,可以在其中记录音频,它将自动将音频文件保存在Firebase(已连接到我的项目)中,并显示在下一个视图控制器中。他们将能够播放在视图控制器中播放的文件所保存的内容,以备将来参考。
我的问题是
这是我登录/创建帐户首页的代码:
import UIKit
import SVProgressHUD
import Firebase
import AVFoundation
class ViewController: UIViewController {
@IBOutlet weak var email: UITextField!
@IBOutlet weak var password: UITextField!
@IBAction func logIn(_ sender: Any) {
SVProgressHUD.show()
Auth.auth().signIn(withEmail: email.text!, password: password.text!) { (user, error) in
if error != nil {
print(error!)
} else {
print("Log in Succesful")
SVProgressHUD.dismiss()
self.performSegue(withIdentifier: "logIn", sender: self)
}
}
}
@IBAction func createAccount(_ sender: Any) {
self.performSegue(withIdentifier: "createAccount", sender: self)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
}
public protocol MicrophonePermissions {
typealias PermissionsState = AVAudioSession.RecordPermission
func requestPermissions(handler: @escaping (PermissionsState) -> Void)
func permissionsState() -> PermissionsState
}
open class DefaultMicrophonePermissions: MicrophonePermissions {
public init() {}
public func requestPermissions(handler: @escaping (PermissionsState) -> Void) {
AVAudioSession.sharedInstance().requestRecordPermission { _ in
DispatchQueue.main.async { [weak self] in
guard let `self` = self else { return }
handler(self.permissionsState())
}
}
}
public func permissionsState() -> PermissionsState {
return AVAudioSession.sharedInstance().recordPermission
}
}
这是我创建帐户的代码:
import UIKit
import Firebase
import SVProgressHUD
class CreateAccountViewController: UIViewController, UIApplicationDelegate {
@IBOutlet weak var emailAddress: UITextField!
@IBOutlet weak var password: UITextField!
@IBAction func createAccount(_ sender: Any) {
Auth.auth().createUser(withEmail: emailAddress.text!, password: password.text!) { (user, error) in
if error != nil {
print(error!)
} else {
print("Account Created!")
SVProgressHUD.dismiss()
self.performSegue(withIdentifier: "mainPage", sender: self)
}
}
func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
这是我的代码,它们开始和结束录制的时间以及能够将音频文件保存在下一个视图控制器中的
import UIKit
import AVFoundation
import Firebase
var recordButton: UIButton!
var audioRecorder: AVAudioRecorder!
var recordingSession: AVAudioSession!
class PracticePageViewController: UIViewController, AVAudioPlayerDelegate, AVAudioRecorderDelegate {
@IBOutlet weak var beginRecording: UIButton!
@IBAction func endRecording(_ sender: Any) {
finishRecording(success: true)
func saveTrack(asset: AVURLAsset) {
let exporter = AVAssetExportSession(asset: asset, presetName: AVAssetExportPresetAppleM4A)
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("YourApp/documents/Track01.m4a")
exporter?.outputURL = fileURL
exporter?.outputFileType = AVFileType.m4a
exporter?.exportAsynchronously(completionHandler: {
print(exporter?.status)
print(exporter?.estimatedOutputFileLength)
print(exporter?.maxDuration)
print("Finished Saving File")
})
}
}
@IBAction func beginRecording(_ sender: Any) {
startRecording()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
recordingSession = AVAudioSession.sharedInstance()
do {
try recordingSession.setCategory(.playAndRecord, mode: .default)
try recordingSession.setActive(true)
recordingSession.requestRecordPermission() { [unowned self] allowed in
DispatchQueue.main.async {
if allowed {
loadRecordingUI()
} else {
print("Failed to Record")
}
}
}
} catch {
print("Failed to Record")
}
func loadRecordingUI() {
recordButton = UIButton(frame: CGRect(x: 64, y: 64, width: 128, height: 64))
recordButton.setTitle("Tap to Record", for: .normal)
recordButton.titleLabel?.font = UIFont.preferredFont(forTextStyle: UIFont.TextStyle(rawValue: title!))
recordButton.addTarget(self, action: #selector(recordTapped), for: .touchUpInside)
view.addSubview(recordButton)
}
}
func startRecording() {
let audioFilename = getDocumentsDirectory().appendingPathComponent("recording.m4a")
let settings = [
AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
AVSampleRateKey: 12000,
AVNumberOfChannelsKey: 1,
AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
]
do {
audioRecorder = try AVAudioRecorder(url: audioFilename, settings: settings)
audioRecorder.delegate = self
audioRecorder.record()
recordButton.setTitle("Tap to Stop", for: .normal)
} catch {
finishRecording(success: false)
}
}
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
func finishRecording(success: Bool) {
audioRecorder.stop()
audioRecorder = nil
if success {
recordButton.setTitle("Tap to Re-record", for: .normal)
} else {
recordButton.setTitle("Tap to Record", for: .normal)
}
}
@objc func recordTapped() {
if audioRecorder == nil {
startRecording()
} else {
finishRecording(success: true)
}
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
if !flag {
finishRecording(success: false)
}
}
}
最后,这是我为View Controller提供的代码,其中显示了所有音频文件,并为他们提供了选择发送文件作为附件的选项
import UIKit
import MessageUI
import Firebase
import AVFoundation
import FirebaseStorage
class PracticeSessionsViewController: UIViewController, MFMailComposeViewControllerDelegate {
@IBAction func emailTeacher(_ sender: Any) {
let mailComposeViewController = configureMailController()
if MFMailComposeViewController.canSendMail() {
self.present(mailComposeViewController, animated: true, completion: nil)
} else {
showMailError()
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
func renameAudio(newTitle: String) {
do {
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) [0]
let documentDirectory = URL(fileURLWithPath: path)
let originPath = documentDirectory.appendingPathComponent("audio.m4a")
let destinationPath = documentDirectory.appendingPathComponent("\(newTitle).m4a")
try FileManager.default.moveItem(at: originPath, to: destinationPath)
} catch {
print(error)
}
}
}
func configureMailController() -> MFMailComposeViewController {
let mailComposeVC = MFMailComposeViewController()
mailComposeVC.mailComposeDelegate = self
mailComposeVC.setToRecipients([""])
mailComposeVC.setSubject("Hello")
return mailComposeVC
}
func showMailError() {
let sendMailErrorAlert = UIAlertController(title: "Could not send mail", message: "Your device could not send message", preferredStyle: .alert)
let dismiss = UIAlertAction(title: "Ok", style: .default, handler: nil)
sendMailErrorAlert.addAction(dismiss)
self.present(sendMailErrorAlert, animated: true, completion: nil)
}
func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
controller.dismiss(animated: true, completion: nil)
}
我一直在尝试寻求最佳方法,但无济于事。我的代码在下面。请记住,我是Swift的新手,所以我只想确保自己正在学习正确的方法。谢谢!