iPhone11 неожиданное количество образцов аудио - PullRequest
0 голосов
/ 26 января 2020

У меня есть приложение, которое захватывает аудио и видео с помощью AVAssetWriter. Он выполняет быстрое преобразование Фурье (БПФ) для аудио, чтобы создать визуальный спектр захваченного звука в режиме реального времени.

Вплоть до выхода iPhone11 все это работало нормально. Однако пользователи с iPhone 11 сообщают, что звук вообще не записывается. Мне удалось сузить проблему - количество сэмплов, возвращаемых в captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection), равно 940 или 941. - На предыдущих моделях телефонов это всегда 1024 сэмпла. Я использую CMSampleBufferGetNumSamples, чтобы получить количество образцов. Мои расчеты БПФ основаны на том, что количество сэмплов должно быть степенью 2, поэтому оно сбрасывает все кадры на новых моделях iPhone.

Кто-нибудь может пролить свет на то, почему новый iPhone11 возвращает необычное количество сэмплов? Вот как я настроил AVAssetWriter:

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!)
}


1 Ответ

1 голос
/ 09 марта 2020

Нельзя принимать фиксированную частоту дискретизации. В зависимости от микрофона и многих других факторов устройства, вы не всегда можете предполагать, что оно будет одинаковым. Это не помогает с библиотекой FFT, которую я использую (TempiFFT). Чтобы это работало, вам нужно заранее определить частоту дискретизации.

Вместо:

let fft = TempiFFT(withSize: 1024, sampleRate: Constants.AUDIO_SAMPLE_RATE)

Мне нужно сначала определить частоту дискретизации при запуске AVCaptureSession, а затем передать это обнаруженное значение в библиотеку FFT:

//During initialization of AVCaptureSession
audioSampleRate = Float(AVAudioSession.sharedInstance().sampleRate)
...
//Run FFT calculations
let fft = TempiFFT(withSize: 1024, sampleRate: audioSampleRate)
...