【问题标题】:My writing the installTap buffer to an AVAudioFile seems to fail data-wise我将 installTap 缓冲区写入 AVAudioFile 似乎在数据方面失败了
【发布时间】:2022-01-10 04:27:14
【问题描述】:

我正在尝试将 installTap 中的缓冲区保存到文件中。我以 10 个为一组,所以我会得到一个更大的文件。当我尝试播放写入的文件(来自模拟器的目录)时,QuickTime 说它不兼容。

我检查了损坏的 m4a 文件和一个工作文件。坏文件的开头有很多零,后面跟着很多数据。但是,这两个文件似乎具有相同的标题。

很多人提到我必须将 AudioFile 设为 nil,但是:

audioFile = 无

不是有效的语法,我也不能在 AudioFile 中归档关闭方法。

这是完整的代码,编辑成一个工作文件:

import UIKit
import AVFoundation

class ViewController: UIViewController {
    let audioEngine = AVAudioEngine()
    var audioFile = AVAudioFile()
    var x = 0


    override func viewDidLoad() {
        super.viewDidLoad()
        record()
        // Do any additional setup after loading the view.
    }

    func makeFile(format: AVAudioFormat) {
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
        do {
            _ = try FileManager.default.contentsOfDirectory(at: paths!, includingPropertiesForKeys: nil)
        } catch { print ("error")}
        let destinationPath = paths!.appendingPathComponent("audioT.m4a")
        print ("\(destinationPath)")
        do {
            audioFile = try AVAudioFile(forWriting: destinationPath,
                                            settings: format.settings)

            print ("file created")
        } catch { print ("error creating file")}
    }
    
    func record(){
        let node = audioEngine.inputNode
        let recordingFormat = node.inputFormat(forBus: 0)
        makeFile(format: recordingFormat)
        
        
        node.installTap(onBus: 0, bufferSize: 8192, format: recordingFormat, block: { [self]
            
            (buffer, _) in
            do {
                try audioFile.write(from: buffer);
            print ("buffer filled");
                x += 1;
                print("wrote \(x)")
                if x > 9 {
                    endThis()
                }
            } catch {return};})
        
        audioEngine.prepare()
        do {
            try audioEngine.start()
        } catch let error {
            print ("oh catch")
        }
    }
    
    func endThis(){
        audioEngine.stop()
        audioEngine.inputNode.removeTap(onBus: 0)
    }
}

【问题讨论】:

    标签: avaudioengine avaudiofile


    【解决方案1】:

    你需要让你的AVAudioFile 超出范围(nil 在某个时候),这就是你调用AVAudioFileclose() 方法的方式,它大概完成了头信息的写出。

    【讨论】:

    • 如果这个答案是正确的,那么这是 stackoverflow.com/q/42660090/22147 的副本,但是这个问题有一个很好的 hexdump 好的和坏的数据,并且还引用了经典的南半球岩石,所以我让它保持开放
    • 我重新编辑了 OP,所以它都在一个工作文件中。但我似乎无法找到一种方法来消除 audioFile 指针,也无法关闭它。
    • 您需要将 AVAudioFile 设为可选 - 然后您可以将其设为 nil。
    • 你的答案是正确的。在我回答正确之前,我想确保你看到这个。 “什么时候”我把它归零有关系吗?我应该先停止引擎吗?无论哪种方式都有效,必须更正确?如此笨拙的方式(关闭方法会如此糟糕吗?)
    • 在可能的异步点击回调中需要考虑线程安全性,但您可以在点击回调中使用weak 对音频文件的引用并在您喜欢时随时取消,例如在endThis()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-18
    • 2011-05-30
    • 2019-08-13
    • 1970-01-01
    • 2015-07-31
    相关资源
    最近更新 更多