如何将音频文件存储和检索到 CloudKit 或从 CloudKit 检索?

问题描述 投票:0回答:1

我试图录制语音消息并将其作为 CKAssets 存储在 CloudKit 上。我将它们转换为 AVAudioFile,并将它们作为 Post 记录中的几个属性之一保存到 CloudKit。

var recordedMessage: AVAudioFile?

var recordedMessageURL: URL? {
    didSet {
        if let recordedMessageURL = recordedMessageURL {
            recordedMessage = try? AVAudioFile(forReading: recordedMessageURL)
        }
    }
}

这部分过程似乎是有效的,尽管当我通过 CloudKit 仪表板访问文件时,我无法播放音频。双击它可以打开iTunes,但无法播放)。

我创建了一个fetchPosts函数,成功地将与记录绑定的图像带下来,但当我试图播放音频时,它给我以下错误。

ExtAudioFile.cpp:192:Open: about to throw -43: open audio file.

我相信这与我无法正确地将资产转换为 AVAudioFile 有关。它似乎不像转换图像资产那样简单。

    var foundAudio: AVAudioFile?
    if let audioAsset = ckRecord[PostStrings.audioAssetKey] as? CKAsset {
        do {
            let audioData = try Data(contentsOf: audioAsset.fileURL!)
            let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
            guard let destinationPath = NSURL(fileURLWithPath: documentsPath).appendingPathComponent("filename.m4a", isDirectory: false) else {return nil}

            FileManager.default.createFile(atPath: destinationPath.path, contents: audioData, attributes: nil)

            foundAudio = try AVAudioFile(forReading: destinationPath)
        } catch {
            print("Could not transform asset into data")
        }
    }

谁能告诉我哪里出了问题?

swift audio cloudkit avaudiofile ckasset
1个回答
0
投票

我花了很多天的时间来改变这些东西,但我已经有了一个可行的解决方案,它不涉及直接将数据作为数据进行操作。相反,我使用了一个URL。我将audioAsset初始化为一个URL。

var opComment: URL?
var audioAsset: CKAsset? {
  get {
    guard let audioURL = opComment else { return nil }
    return CKAsset(fileURL: audioURL)
    }
    set {
      opComment = newValue?.fileURL
    }
  }

我用一个方便的初始化器把ckRecord拉了回来

var opCommentURL: URL?
    if let audioAsset = ckRecord[PostStrings.audioAssetKey] as? CKAsset {
            opCommentURL = audioAsset.fileURL
    }

然后我把它作为一个URL输入到AVAudioPlayer中。

        guard let audioURL = post.opComment else {return}

    if !isTimerRunning {
        do {
            audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
            audioPlayer.play()
        } catch {
            print("Error in \(#function) : \(error.localizedDescription) /n---/n \(error)")
        }
    } else {
        audioPlayer.pause()
        isTimerRunning = false
    }

(如果你在看这个,Sam. 谢谢你在正确的方向上轻轻地推了一把!)。)

© www.soinside.com 2019 - 2024. All rights reserved.