mke*_*ser 5 macos avfoundation ios avplayer
我正在尝试为其构建电平计量AVPlayer.我正在这样做MTAudioProcessingTap,传递给一个AVAudioMix,然后传递给AVPlayerItem.在MTAudioProcessingTap获取与创建kMTAudioProcessingTapCreationFlag_PostEffects标志.
技术问答QA1783有关于PreEffects和PostEffects标志的以下内容:
当您使用kMTAudioProcessingTapCreationFlag_PreEffects标志创建"预效果"音频抽头时,将在应用AVAudioMixInputParameters指定的任何效果之前调用tap.当您使用kMTAudioProcessingTapCreationFlag_PostEffects标志创建"后效应"点击时,将在应用这些效果后调用点击.目前,AVAudioMixInputParameters支持的唯一"效果"是线性音量斜坡.
问题:
当用the创建时kMTAudioProcessingTapCreationFlag_PostEffects,我希望它接收到的样本MTAudioProcessingTap将反映出设置的音量或音频斜坡AVAudioMixInputParameters.例如,如果我将音量设置为0,我希望得到所有0个样本.然而,我收到的样品似乎完全不受体积或体积斜率的影响.
难道我做错了什么?
这是一个快速的脏操场,说明了这个问题.该示例直接设置音量,但在使用音频斜坡时我发现了同样的问题.在macOS和iOS上测试过:
import Foundation
import XCPlayground
import PlaygroundSupport
import AVFoundation
import Accelerate
PlaygroundPage.current.needsIndefiniteExecution = true;
let assetURL = Bundle.main.url(forResource: "sample", withExtension: "mp3")!
let asset = AVAsset(url: assetURL)
let playerItem = AVPlayerItem(asset: asset)
var audioMix = AVMutableAudioMix()
// The volume. Set to > 0 to hear something.
let kVolume: Float = 0.0
var parameterArray: [AVAudioMixInputParameters] = []
for assetTrack in asset.tracks(withMediaType: .audio) {
let parameters = AVMutableAudioMixInputParameters(track: assetTrack);
parameters.setVolume(kVolume, at: kCMTimeZero)
parameterArray.append(parameters)
// Omitting most callbacks to keep sample short:
var callbacks = MTAudioProcessingTapCallbacks(
version: kMTAudioProcessingTapCallbacksVersion_0,
clientInfo: nil,
init: nil,
finalize: nil,
prepare: nil,
unprepare: nil,
process: { (tap, numberFrames, flags, bufferListInOut, numberFramesOut, flagsOut) in
guard MTAudioProcessingTapGetSourceAudio(tap, numberFrames, bufferListInOut, flagsOut, nil, numberFramesOut) == noErr else {
preconditionFailure()
}
// Assume 32bit float format, native endian:
for i in 0..<bufferListInOut.pointee.mNumberBuffers {
let buffer = bufferListInOut.pointee.mBuffers
let stride: vDSP_Stride = vDSP_Stride(buffer.mNumberChannels)
let numElements: vDSP_Length = vDSP_Length(buffer.mDataByteSize / UInt32(MemoryLayout<Float>.stride))
for j in 0..<Int(buffer.mNumberChannels) {
// Use vDSP_maxmgv tof ind the maximum amplitude
var start = buffer.mData!.bindMemory(to: Float.self, capacity: Int(numElements))
start += Int(j * MemoryLayout<Float>.stride)
var magnitude: Float = 0
vDSP_maxmgv(start, stride, &magnitude, numElements - vDSP_Length(j))
DispatchQueue.main.async {
print("buff: \(i), chan: \(j), max: \(magnitude)")
}
}
}
}
)
var tap: Unmanaged<MTAudioProcessingTap>?
guard MTAudioProcessingTapCreate(kCFAllocatorDefault, &callbacks, kMTAudioProcessingTapCreationFlag_PostEffects, &tap) == noErr else {
preconditionFailure()
}
parameters.audioTapProcessor = tap?.takeUnretainedValue()
}
audioMix.inputParameters = parameterArray
playerItem.audioMix = audioMix
let player = AVPlayer(playerItem: playerItem)
player.rate = 1.0
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
271 次 |
| 最近记录: |