我正在制作一款需要向服务器流媒体音频的应用程序。我想要做的是将录制的音频分成块并在录制时上传它们。
我使用了两个录音机来实现这个目标,但效果不佳;我可以听到块之间的差异(停顿几毫秒)。
我该如何解决这个问题?
我正在制作一款需要向服务器流媒体音频的应用程序。我想要做的是将录制的音频分成块并在录制时上传它们。
我使用了两个录音机来实现这个目标,但效果不佳;我可以听到块之间的差异(停顿几毫秒)。
我该如何解决这个问题?
AVAudioEngine
和 AVAudioFile
。下面是一个示例,它以设备默认输入采样率记录块(你可能需要进行速率转换)。cat
一样。遗憾的是,在 iOS 上没有 mp3 编码器,所以这使得 aac 成为你可能的格式,但这取决于你的播放要求。iOS 设备和 Mac 可以肯定地播放它。import AVFoundation
class ViewController: UIViewController {
let engine = AVAudioEngine()
struct K {
static let secondsPerChunk: Float64 = 10
}
var chunkFile: AVAudioFile! = nil
var outputFramesPerSecond: Float64 = 0 // aka input sample rate
var chunkFrames: AVAudioFrameCount = 0
var chunkFileNumber: Int = 0
func writeBuffer(_ buffer: AVAudioPCMBuffer) {
let samplesPerSecond = buffer.format.sampleRate
if chunkFile == nil {
createNewChunkFile(numChannels: buffer.format.channelCount, samplesPerSecond: samplesPerSecond)
}
try! chunkFile.write(from: buffer)
chunkFrames += buffer.frameLength
if chunkFrames > AVAudioFrameCount(K.secondsPerChunk * samplesPerSecond) {
chunkFile = nil // close file
}
}
func createNewChunkFile(numChannels: AVAudioChannelCount, samplesPerSecond: Float64) {
let fileUrl = NSURL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("chunk-\(chunkFileNumber).aac")!
print("writing chunk to \(fileUrl)")
let settings: [String: Any] = [
AVFormatIDKey: kAudioFormatMPEG4AAC,
AVEncoderBitRateKey: 64000,
AVNumberOfChannelsKey: numChannels,
AVSampleRateKey: samplesPerSecond
]
chunkFile = try! AVAudioFile(forWriting: fileUrl, settings: settings)
chunkFileNumber += 1
chunkFrames = 0
}
override func viewDidLoad() {
super.viewDidLoad()
let input = engine.inputNode!
let bus = 0
let inputFormat = input.inputFormat(forBus: bus)
input.installTap(onBus: bus, bufferSize: 512, format: inputFormat) { (buffer, time) -> Void in
DispatchQueue.main.async {
self.writeBuffer(buffer)
}
}
try! engine.start()
}
}