使用Swift 3录制音频并上传到Firebase存储,并进行播放

9
我正在制作一个聊天室应用程序,目前已经可以发送消息、图片和视频。
我使用了一种非常类似的方法来发送视频,它可以正常工作,但是当发送音频时却无法正常工作。
音频文件和音频url已成功上传到Firebase,但是当我尝试回放音频时,会显示此错误:操作无法完成。(OSStatus错误2003334207)。
这个项目变得相当庞大,而我对AVAudio的使用经验很少,如果你们之前遇到过类似的问题,请教我如何解决。谢谢!
以下是设置audioRecorder的代码,我在这里获取url并将其传递给其他函数将音频文件放入Firebase存储。
func startRecording() {
    let settings = [
        AVFormatIDKey: Int(kAudioFormatMPEG4AAC),
        AVSampleRateKey: 12000,
        AVNumberOfChannelsKey: 1,
        AVEncoderAudioQualityKey: AVAudioQuality.low.rawValue
    ]
    
    do {
        let audioFileUrl = getAudiFileURL()
        audioRecorder = try AVAudioRecorder(url: audioFileUrl, settings: settings)
        audioRecorder.delegate = self
        audioRecorder.record()
        blackView.isHidden = false
    } catch {
        finishRecording(success: false)
    }
}

这里是我尝试将音频文件上传到Firebase Storage的位置,它确实打印出了正确的downloadURL。(该URL指向iOS设备中文件的位置。)

func handleAudioSendWith(url: String) {
    guard let fileUrl = URL(string: url) else {
        return
    }
    let fileName = NSUUID().uuidString + ".m4a"
    
    FIRStorage.storage().reference().child("message_voice").child(fileName).putFile(fileUrl, metadata: nil) { (metadata, error) in
        if error != nil {
            print(error ?? "error")
        }
        
        if let downloadUrl = metadata?.downloadURL()?.absoluteString {
            print(downloadUrl)
            let values: [String : Any] = ["audioUrl": downloadUrl]
            self.sendMessageWith(properties: values)
        }
    }
}

这是我如何设置上面的audioRecorder的URL。
func getDocumentsDirectory() -> URL {
    let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
    let documentsDirectory = paths[0]
    return documentsDirectory
}

func getAudiFileURL() -> URL {
    return getDocumentsDirectory().appendingPathComponent(".m4a")
}

这是我播放音频的地方:

func handleAudioPLay() {
    if let audioUrl = message?.audioUrl, let url = URL(string: audioUrl) {
        do {
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
            audioPlayer = try AVAudioPlayer(contentsOf: url)
            audioPlayer?.delegate = self
            audioPlayer?.prepareToPlay()
            audioPlayer?.play()
            print("Audio ready to play")
        } catch let error {
            print(error.localizedDescription)
        }
    }
}

我可以使用URL从Firebase下载声音文件,并在电脑上播放它,这意味着该URL没有问题。

这看起来像是你正在上传一个URL,而不是音频文件。那怎么办?存储在iPhone/iDevice上的音频文件很可能是数据文件,对吧?换句话说,你如何上传一个音频文件,而不是音频文件的URL? - John Pitts
2
@JohnPitts 我首先使用URLSession从iOS设备下载音频文件,然后将其上传到Firebase。URL是指向iOS设备文件管理器中文件位置的指针,您不会上传URL,而是上传URL指向的文件。 - Bryce Chan
1个回答

7
我已经通过使用URLSession下载声音文件并使用AVAudioPlayer(data: data!, fileTypeHint: "aac")播放来解决了这个问题。

嗨,@Bryce,你能提供这个的完整代码吗? - Lakshmi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接