-3
我希望用戶播放音頻,更改某些部分的音量,然後使用新的音量級別保存該文件。具有不同音量級別的音頻文件
我改變了與AVAssetExportSession和AVMutableAudioMixInputParameters音頻的音量和工作,問題是,我需要創建這個音頻音頻循環,所以首先我創造了這個循環,然後我需要改變音量
這裏是我的代碼
let type = "m4a"
let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("mixedAudio.m4a")
var backgroundUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("background.m4a")
override func viewDidLoad() {
super.viewDidLoad()
playButotn.isEnabled = false
let mainUrl = Bundle.main.url(forResource: "prueba1", withExtension: type, subdirectory: "Audios")
let mainDurations = AVAsset(url: mainUrl!).duration
let secondAudioUrl = Bundle.main.url(forResource: "walk", withExtension: type, subdirectory: "Audios")
let backgroundDuration = AVAsset(url: secondAudioUrl!).duration
if mainDurations > backgroundDuration {
var times = Int(mainDurations.seconds/backgroundDuration.seconds)
let rem = mainDurations.seconds.truncatingRemainder(dividingBy: backgroundDuration.seconds)
if rem > 0 {
times = times + 1
}
createLoopAudio(times: times) {
self.createFade {
self.createMix(mainUrl: mainUrl!, backgroundUrl: self.backgroundUrl)
}
}
}else {
backgroundUrl = secondAudioUrl!
createMix(mainUrl: mainUrl!, backgroundUrl: backgroundUrl)
}
}
func createMix(mainUrl: URL, backgroundUrl: URL){
let composition = AVMutableComposition()
let mainAsset = AVAsset(url: mainUrl)
let backgroundAsset = AVAsset(url: backgroundUrl)
let mainDurations = AVAsset(url: mainUrl).duration
let mainAudioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
let backgroundAudioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
let timeRange = CMTimeRangeMake(kCMTimeZero, mainDurations)
do {
try mainAudioTrack.insertTimeRange(timeRange, of: mainAsset.tracks(withMediaType: AVMediaTypeAudio)[0], at: kCMTimeZero)
try backgroundAudioTrack.insertTimeRange(timeRange, of: backgroundAsset.tracks(withMediaType: AVMediaTypeAudio)[0], at: kCMTimeZero)
}catch {
print(error.localizedDescription)
}
let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)
assetExport?.outputFileType = AVFileTypeMPEG4
assetExport?.outputURL = documentsDirectory
assetExport?.shouldOptimizeForNetworkUse = true
if FileManager.default.fileExists(atPath: documentsDirectory.path) {
try! FileManager.default.removeItem(atPath: documentsDirectory.path)
}
assetExport?.exportAsynchronously(completionHandler: {
switch assetExport!.status
{
case AVAssetExportSessionStatus.failed:
print("failed \(assetExport?.error)")
case AVAssetExportSessionStatus.cancelled:
print("cancelled \(assetExport?.error)")
case AVAssetExportSessionStatus.unknown:
print("unknown\(assetExport?.error)")
case AVAssetExportSessionStatus.waiting:
print("waiting\(assetExport?.error)")
case AVAssetExportSessionStatus.exporting:
print("exporting\(assetExport?.error)")
case AVAssetExportSessionStatus.completed:
print("complete")
DispatchQueue.main.async {
self.playButotn.isEnabled = true
}
}
})
}
func createLoopAudio(times: Int, completion: @escaping() -> Void){
let composition = AVMutableComposition()
var nextTimeStartClip = kCMTimeZero
for _ in 1...times {
let url = Bundle.main.url(forResource: "walk", withExtension: type, subdirectory: "Audios")
let audioAsset = AVAsset(url: url!)
print("tracks walk \(audioAsset.tracks.count)")
let audioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
let timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
do {
try audioTrack.insertTimeRange(timeRange, of: audioAsset.tracks(withMediaType: AVMediaTypeAudio)[0], at: nextTimeStartClip)
}catch {
print(error.localizedDescription)
}
nextTimeStartClip = CMTimeAdd(nextTimeStartClip, audioAsset.duration)
}
let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetPassthrough)
assetExport?.outputFileType = AVFileTypeMPEG4
assetExport?.outputURL = backgroundUrl
assetExport?.shouldOptimizeForNetworkUse = true
if FileManager.default.fileExists(atPath: backgroundUrl.path) {
try! FileManager.default.removeItem(atPath: backgroundUrl.path)
}
assetExport?.exportAsynchronously(completionHandler: {
switch assetExport!.status
{
case AVAssetExportSessionStatus.failed:
print("failed \(assetExport?.error)")
case AVAssetExportSessionStatus.cancelled:
print("cancelled \(assetExport?.error)")
case AVAssetExportSessionStatus.unknown:
print("unknown\(assetExport?.error)")
case AVAssetExportSessionStatus.waiting:
print("waiting\(assetExport?.error)")
case AVAssetExportSessionStatus.exporting:
print("exporting\(assetExport?.error)")
case AVAssetExportSessionStatus.completed:
print("loop complete")
completion()
}
})
}
func createFade(completion: @escaping() -> Void) {
let exportAudioMix = AVMutableAudioMix()
let audioAsset = AVAsset(url: backgroundUrl)
let exportAudioMixInputParameters = AVMutableAudioMixInputParameters(track: audioAsset.tracks(withMediaType: AVMediaTypeAudio)[0])
let start = 2
let length = 3
exportAudioMixInputParameters.setVolume(0.0, at: CMTimeMakeWithSeconds(Float64(start - 1), 1))
exportAudioMixInputParameters.setVolume(0.1, at: CMTimeMakeWithSeconds(Float64(start), 1))
exportAudioMixInputParameters.setVolume(0.5, at: CMTimeMakeWithSeconds(Float64(start + 1), 1))
exportAudioMixInputParameters.setVolume(1.0, at: CMTimeMakeWithSeconds(Float64(start + 2), 1))
exportAudioMixInputParameters.setVolume(1.0, at: CMTimeMakeWithSeconds(Float64(start + length - 2), 1))
exportAudioMixInputParameters.setVolume(0.5, at: CMTimeMakeWithSeconds(Float64(start + length - 1), 1))
exportAudioMixInputParameters.setVolume(0.1, at: CMTimeMakeWithSeconds(Float64(start + length), 1))
exportAudioMix.inputParameters = [exportAudioMixInputParameters]
let composition = AVMutableComposition()
print("tracks loop \(audioAsset.tracks.count)")
let audioTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: kCMPersistentTrackID_Invalid)
let timeRange = CMTimeRangeMake(kCMTimeZero, audioAsset.duration)
do {
try audioTrack.insertTimeRange(timeRange, of: audioAsset.tracks(withMediaType: AVMediaTypeAudio)[0], at: kCMTimeZero)
}catch {
print(error.localizedDescription)
}
let assetExport = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetAppleM4A)
assetExport?.outputFileType = AVFileTypeAppleM4A
assetExport?.outputURL = backgroundUrl
assetExport?.shouldOptimizeForNetworkUse = true
if FileManager.default.fileExists(atPath: backgroundUrl.path) {
try! FileManager.default.removeItem(atPath: backgroundUrl.path)
}
assetExport?.exportAsynchronously(completionHandler: {
switch assetExport!.status
{
case AVAssetExportSessionStatus.failed:
print("failed \(assetExport?.error)")
case AVAssetExportSessionStatus.cancelled:
print("cancelled \(assetExport?.error)")
case AVAssetExportSessionStatus.unknown:
print("unknown\(assetExport?.error)")
case AVAssetExportSessionStatus.waiting:
print("waiting\(assetExport?.error)")
case AVAssetExportSessionStatus.exporting:
print("exporting\(assetExport?.error)")
case AVAssetExportSessionStatus.completed:
print("faded complete")
completion()
}
})
你到目前爲止嘗試過什麼? –
這是您給我們的一項廣泛任務 – jhhoff02
如果文件被移動到另一個應用程序,或者只有在應用程序中播放時纔會發生音量變化? –