swift4 - 更改 AVAsset 的首选数量
问题描述
是否可以增加/减少音频文件的 AVAsset 轨道或 AVMutableComposition 的音量?我有两个音频文件(背景乐器和录制的歌曲),我想降低一个文件的音量并将其与另一个文件合并。
解决方案
1.改变音轨的音量
要对物理文件执行此操作,您需要将原始 PCM 数据加载到 Swift 中。以下是通过此 SO 帖子获取浮点数据的示例:
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)
.
然后是在加载之前再次写回音频文件的问题(信用):
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 文件,你可以像以前一样将它们加载到 AVAssets 中,但这次使用你之前应用的所需增益。
然后看起来你会想要使用AVAssetReaderAudioMixOutput,它有一个专门用于将两个音轨混合在一起的方法。
AVAssetReaderAudioMixOutput.init(audioTracks: [AVAssetTrack], audioSettings: [String : Any]?)
注意: 我不会连续使用第 1 步和第 2 步,例如,如果你想用滑块混合歌曲并听到结果,我建议使用 AVPlayer 并调整它们的音量,然后当用户准备好时,调用这个文件 IO 和混合。
推荐阅读
- css - 如何在 Bootstrap 中设置卡片的最小宽度?
- android - 如何在 Bazel 项目中为 d8 设置命令行标志?
- c# - 无法从 ASP.NET MVC 项目插入 PostgreSQL 表
- sql - SQL查询出多个连接表数据
- python - 如何用项目计数填充列表/字典?
- c++ - 一旦我有了一个字符串的长度,我如何将长度数捕获为一个整数变量以便在其他地方使用?
- javascript - 为什么服务器在发布身份验证信息时说需要“名称”?
- numbers - 从 Hazelcast 中查找范围
- oracle - ORA-00942: Spring Boot 中的 Spring JDBC 模板不存在表或视图
- java - Spark读取文本文件在线程“main”org.apache.spark.SparkException中本地抛出异常:任务不可序列化