Ich arbeite an einer App, die mehrere Videoclips zu einem endgültigen Video zusammenführt. Ich möchte den Benutzern die Möglichkeit geben, einzelne Clips bei Bedarf stummzuschalten (so werden nur Teile des endgültigen zusammengeführten Videos stumm geschaltet). Ich habe die AVAssets in eine Klasse namens "Video" eingepackt, die eine "shouldMute" -Eigenschaft hat.AVMutableAudioMix mehrere Volumenänderungen an einem Track
Mein Problem ist, wenn ich die Lautstärke eines der AVAssetTracks auf Null setzt, bleibt es für den Rest des endgültigen Videos stummgeschaltet. Hier ist mein Code:
var completeDuration : CMTime = CMTimeMake(0, 1)
var insertTime = kCMTimeZero
var layerInstructions = [AVVideoCompositionLayerInstruction]()
let mixComposition = AVMutableComposition()
let audioMix = AVMutableAudioMix()
let videoTrack =
mixComposition.addMutableTrack(withMediaType: AVMediaType.video,
preferredTrackID: kCMPersistentTrackID_Invalid)
let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid)
// iterate through video assets and merge together
for (i, video) in clips.enumerated() {
let videoAsset = video.asset
var clipDuration = videoAsset.duration
do {
if video == clips.first {
insertTime = kCMTimeZero
} else {
insertTime = completeDuration
}
if let videoAssetTrack = videoAsset.tracks(withMediaType: .video).first {
try videoTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, clipDuration), of: videoAssetTrack, at: insertTime)
completeDuration = CMTimeAdd(completeDuration, clipDuration)
}
if let audioAssetTrack = videoAsset.tracks(withMediaType: .audio).first {
try audioTrack?.insertTimeRange(CMTimeRangeMake(kCMTimeZero, clipDuration), of: audioAssetTrack, at: insertTime)
if video.shouldMute {
let audioMixInputParams = AVMutableAudioMixInputParameters()
audioMixInputParams.trackID = audioTrack!.trackID
audioMixInputParams.setVolume(0.0, at: insertTime)
audioMix.inputParameters.append(audioMixInputParams)
}
}
} catch let error as NSError {
print("error: \(error)")
}
let videoInstruction = videoCompositionInstructionForTrack(track: videoTrack!, video: video)
if video != clips.last{
videoInstruction.setOpacity(0.0, at: completeDuration)
}
layerInstructions.append(videoInstruction)
} // end of video asset iteration
Wenn ich hinzufügen, eine andere setVolume: atTime Anweisung die Lautstärke wieder auf 1,0 am Ende des Clips zu erhöhen, dann der erste Band-Befehl vollständig ignoriert und das komplette Video spielt bei voller Lautstärke .
Mit anderen Worten, das funktioniert nicht:
if video.shouldMute {
let audioMixInputParams = AVMutableAudioMixInputParameters()
audioMixInputParams.trackID = audioTrack!.trackID
audioMixInputParams.setVolume(0.0, at: insertTime)
audioMixInputParams.setVolume(1.0, at: completeDuration)
audioMix.inputParameters.append(audioMixInputParams)
}
ich die AUDIOMIX auf meinem AVPlayerItem und AVAssetExportSession beide gesetzt haben. Was mache ich falsch? Was kann ich tun, damit Benutzer die Zeitbereiche einzelner Clips stummschalten können, bevor sie zum endgültigen Video hinzugefügt werden?