如何使用 Swift 5 /SwiftUI 将 AVAudioRecorder 文件上传到 Firebase 存储?

问题描述

嗨,我知道这已经被问过几次了,但我需要帮助将用户录音上传到 Firebase。当用户在应用中录制音频并按下停止按钮时,我希望将录制内容上传并存储在 Firebase 而不是用户的手机中。

这里是录音功能

func startRecording() {
    
    let recordingSession = AVAudioSession.sharedInstance()
    
    do {
        try recordingSession.setCategory(.playAndRecord,mode: .default)
        try recordingSession.setActive(true)
    } catch {
        print("Failed to set up recording session")
    }
    let documentPath = FileManager.default.urls(for: .documentDirectory,in: .userDomainMask)[0]
    let audioFilename = documentPath.appendingPathComponent("\(Date().toString(dateFormat: "dd-MM-YY_'at'_HH:mm:ss")).m4a")
    let settings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),AVSampleRateKey: 12000,AVNumberOfChannelsKey: 1,AVEncoderAudioQualityKey: AVAudioQuality.high.rawValue
    ]
    
    do {
        audioRecorder = try AVAudioRecorder(url: audioFilename,settings: settings)
        audioRecorder.record()
        
        recording = true
    } catch {
        print("Could not start recording")
    }
}

这里是用户停止录制时的功能

func saveRecording() {
    
    let path = FileManager.default.urls(for: .documentDirectory,in: .userDomainMask)[0]
       let directoryContents = try! FileManager.default.contentsOfDirectory(at: path,includingPropertiesForKeys: nil)

       for i in directoryContents {
        user.answeRSSent.append(CardModel(fullname: question.fullname,username: question.username,imageURL: question.imageURL,question: question.question,fileURL: i,createdAt: getCreationDate(for: i),colorChoice: question.colorChoice))
       }
   
      
            
            user.answeRSSent.sort(by: { $0.createdAt?.compare($1.createdAt!) == .orderedDescending})
           
            
        
        }
    }
    

非常感谢您花时间阅读。我花了将近两天的时间试图弄清楚。

解决方法

  1. 不要让您的 URL 立即超出范围,而是将其存储在运行此函数的任何类的属性中(如果您在 View 中执行此操作,请移动所有记录逻辑到ObservableObject)。

  2. 在录制结束时,既然您有了 URL,您就不必进行 createdAt 排序,我假设您可能正在这样做以获取最新的文件 (我现在有点不清楚)。

  3. 使用 Firebase 文档 (https://firebase.google.com/docs/storage/ios/upload-files#upload_from_a_local_file) 中描述的方法上传本地文件:

// File located on disk
// Create a reference to the file you want to upload
let audioFileRef = storageRef.child("audioFiles/audioFile.m4a") //adjust this to have a unique name

let uploadTask = audioFileRef.putFile(from: localAudioURL,metadata: nil) { metadata,error in
  guard let metadata = metadata else {
    // Uh-oh,an error occurred!
    return
  }
  //optionally,delete original local file here
}
  1. 或者,在上传完成后删除您的本地文件。此外,您可以选择使用临时目录而不是文档目录来存储初始录音。