更改 AVAsset 的首选数量

Posted

技术标签:

【中文标题】更改 AVAsset 的首选数量【英文标题】:Change preferred volume of AVAsset 【发布时间】:2018-07-03 11:51:51 【问题描述】:

是否可以增加/减少音频文件的 AVAsset 轨道或 AVMutableComposition 的音量? 我有两个音频文件(背景乐器和录制的歌曲),我想降低一个文件的音量并将其与另一个文件合并。

【问题讨论】:

【参考方案1】:

1。更改音轨的音量

要对物理文件执行此操作,您需要将原始 PCM 数据加载到 Swift 中。下面是通过this SO post:获取浮点数据的示例

import AVFoundation
// ...

let url = NSBundle.mainBundle().URLForResource("your audio file", withExtension: "wav")
let file = try! AVAudioFile(forReading: url!)
let format = AVAudioFormat(commonFormat: .PCMFormatFloat32, sampleRate: file.fileFormat.sampleRate, channels: 1, interleaved: false)

let buf = AVAudioPCMBuffer(PCMFormat: format, frameCapacity: 1024)
try! file.readIntoBuffer(buf)

// this makes a copy, you might not want that
let floatArray = Array(UnsafeBufferPointer(start: buf.floatChannelData[0], count:Int(buf.frameLength)))

print("floatArray \(floatArray)\n")

floatArray 中获得数据后,只需将数组中的每个值乘以 0 到 1 之间的数字即可调整增益。如果您更熟悉分贝,请将您的分贝值放入以下行,并将每个数组值乘以 linGain

var linGain = pow(10.0f, decibelGain/20.0f).

那么问题是在加载音频文件之前再次写回它(credit):

let SAMPLE_RATE =  Float64(16000.0)

let outputFormatSettings = [
    AVFormatIDKey:kAudioFormatLinearPCM,
    AVLinearPCMBitDepthKey:32,
    AVLinearPCMIsFloatKey: true,
    //  AVLinearPCMIsBigEndianKey: false,
    AVSampleRateKey: SAMPLE_RATE,
    AVNumberOfChannelsKey: 1
    ] as [String : Any]

let audioFile = try? AVAudioFile(forWriting: url, settings: outputFormatSettings, commonFormat: AVAudioCommonFormat.pcmFormatFloat32, interleaved: true)

let bufferFormat = AVAudioFormat(settings: outputFormatSettings)

let outputBuffer = AVAudioPCMBuffer(pcmFormat: bufferFormat, frameCapacity: AVAudioFrameCount(buff.count))

// i had my samples in doubles, so convert then write

for i in 0..<buff.count 
    outputBuffer.floatChannelData!.pointee[i] = Float( buff[i] )

outputBuffer.frameLength = AVAudioFrameCount( buff.count )

do
    try audioFile?.write(from: outputBuffer)

 catch let error as NSError 
    print("error:", error.localizedDescription)

2。将曲目混合在一起

一旦您有了新的音频 .wav 文件,您就可以像以前一样将这两个文件加载到您的 AVAsset 中,但这次使用您之前应用的所需增益。

然后看起来你会想要使用AVAssetReaderAudioMixOutput,它有一个专门用于将两个音轨混合在一起的方法。

AVAssetReaderAudioMixOutput.init(audioTracks: [AVAssetTrack], audiosettings: [String : Any]?)

注意: 我不会连续使用步骤 1 和 2,例如,如果您想用滑块混合歌曲并听到结果,我建议使用 AVPlayer 并调整它们的音量然后当用户准备好时,调用这个文件 IO 和混合。

【讨论】:

以上是关于更改 AVAsset 的首选数量的主要内容,如果未能解决你的问题,请参考以下文章

MPMediaItem 到 AVAsset 到 .MP3

Swift 3 将数据转换为 AVAsset 或 PHAsset

AVAsset "tracksWithMediaType" 返回一个空数组

为啥 AVAsset 轨道对于同一个视频文件有不同的 timeRange?

UIActivity 和 AVAsset 数据类型使用

将AVAsset视频文件拆分为块