首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >iPhone11音频样本的意外数量

iPhone11音频样本的意外数量
EN

Stack Overflow用户
提问于 2020-01-26 12:03:18
回答 1查看 101关注 0票数 1

我有一个应用程序,可以用AVAssetWriter捕捉音频和视频。它在音频上运行快速傅里叶变换(FFT),实时生成捕捉到的音频的可视频谱。

直到iPhone11发布之前,这一切都很好。然而,使用iPhone 11的用户报告说,音频根本没有被捕获。我已经设法缩小了这个问题--在captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection)中返回的样本数量要么是940个,要么是941个--在以前的手机模型中,这始终是1024个样本。我使用CMSampleBufferGetNumSamples获取样本的数量。我的快速傅立叶变换的计算依赖于样本数为2的幂,因此它会将所有帧丢弃在较新的模型iPhones上。

有人能解释一下为什么新的iPhone11会返回异常数量的样本吗?下面是我如何配置AVAssetWriter

代码语言:javascript
复制
self.videoWriter = try AVAssetWriter(outputURL: self.outputURL, fileType: AVFileType.mp4)
var videoSettings: [String : Any]
if #available(iOS 11.0, *) {
    videoSettings = [
        AVVideoCodecKey  : AVVideoCodecType.h264,
        AVVideoWidthKey  : Constants.VIDEO_WIDTH,
        AVVideoHeightKey : Constants.VIDEO_HEIGHT,
    ]
} else {
    videoSettings = [
        AVVideoCodecKey  : AVVideoCodecH264,
        AVVideoWidthKey  : Constants.VIDEO_WIDTH,
        AVVideoHeightKey : Constants.VIDEO_HEIGHT,
    ]
}

//Video Input
videoWriterVideoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
videoWriterVideoInput?.expectsMediaDataInRealTime = true;
if (videoWriter?.canAdd(videoWriterVideoInput!))!
{
    videoWriter?.add(videoWriterVideoInput!)
}

//Audio Settings
let audioSettings : [String : Any] = [
    AVFormatIDKey : kAudioFormatMPEG4AAC,
    AVSampleRateKey : Constants.AUDIO_SAMPLE_RATE, //Float(44100.0)
    AVEncoderBitRateKey : Constants.AUDIO_BIT_RATE, //64000
    AVNumberOfChannelsKey: Constants.AUDIO_NUMBER_CHANNELS //1
]

//Audio Input
videoWriterAudioInput = AVAssetWriterInput(mediaType: AVMediaType.audio, outputSettings: audioSettings)
videoWriterAudioInput?.expectsMediaDataInRealTime = true;
if (videoWriter?.canAdd(videoWriterAudioInput!))!
{
    videoWriter?.add(videoWriterAudioInput!)
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-03-08 22:35:02

你不能假设固定的抽样率。取决于麦克风和设备的许多其他因素,您不能总是假设它将是相同的。这对我使用的FFT库(TempiFFT)没有帮助--为了让它正常工作,您需要提前检测采样率。

而不是:

代码语言:javascript
复制
let fft = TempiFFT(withSize: 1024, sampleRate: Constants.AUDIO_SAMPLE_RATE)

我需要首先检测启动AVCaptureSession时的采样率,然后将检测到的值传递给FFT库:

代码语言:javascript
复制
//During initialization of AVCaptureSession
audioSampleRate = Float(AVAudioSession.sharedInstance().sampleRate)
...
//Run FFT calculations
let fft = TempiFFT(withSize: 1024, sampleRate: audioSampleRate)

更新

在某些设备上,您可能不会在循环中接收到完整的1024个示例(在iPhone 11上我得到了941个)--如果它没有正确的帧数,您可能会从快速傅立叶变换中得到意想不到的行为。我需要创建一个循环缓冲区来在每个输出返回时存储样本,直到我至少有1024个样本来执行FFT。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59918124

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档