我正在Video根据Application进行工作Swift。按要求我必须选择多个Videos距离Device Gallery,设置不同的不同的CIFilter影响,并Volume为每个Video Asset然后合并所有的Videos并有保存Final Video。作为输出,当我将扮演Final Video那么Video声音volume应该随之改变。
Video
Application
Swift
Videos
Device Gallery
CIFilter
Volume
Video Asset
Final Video
volume
我已经将所有选择的内容合并Video Assets为一个具有不同CIFilter效果的内容,但是我的问题是,当我尝试Volume为每个内容进行设置时,Video Clips则无法正常工作。我正在Volume为我的默认值Final Video。这是我的代码:
Video Assets
Video Clips
func addFilerEffectAndVolumeToIndividualVideoClip(_ assetURL: URL, video: VideoFileModel, completion : ((_ session: AVAssetExportSession?, _ outputURL : URL?) -> ())?){ let videoFilteredAsset = AVAsset(url: assetURL) print(videoFilteredAsset) createVideoComposition(myAsset: videoFilteredAsset, videos: video) let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] let url = URL(fileURLWithPath: documentDirectory).appendingPathComponent("\(video.fileID)_\("FilterVideo").mov") let filePath = url.path let fileManager = FileManager.default do { if fileManager.fileExists(atPath: filePath) { print("FILE AVAILABLE") try fileManager.removeItem(atPath:filePath) } else { print("FILE NOT AVAILABLE") } } catch _ { } let composition: AVMutableComposition = AVMutableComposition() let compositionVideo: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) let compositionAudioVideo: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) //Add video to the final record do { try compositionVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoFilteredAsset.duration), of: videoFilteredAsset.tracks(withMediaType: AVMediaTypeVideo)[0], at: kCMTimeZero) } catch _ { } //Extract audio from the video and the music let audioMix: AVMutableAudioMix = AVMutableAudioMix() var audioMixParam: [AVMutableAudioMixInputParameters] = [] let assetVideoTrack: AVAssetTrack = videoFilteredAsset.tracks(withMediaType: AVMediaTypeAudio)[0] let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack) videoParam.trackID = compositionAudioVideo.trackID //Set final volume of the audio record and the music videoParam.setVolume(video.videoClipVolume, at: kCMTimeZero) //Add setting audioMixParam.append(videoParam) //Add audio on final record do { try compositionAudioVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, videoFilteredAsset.duration), of: assetVideoTrack, at: kCMTimeZero) } catch _ { assertionFailure() } //Fading volume out for background music let durationInSeconds = CMTimeGetSeconds(videoFilteredAsset.duration) let firstSecond = CMTimeRangeMake(CMTimeMakeWithSeconds(0, 1), CMTimeMakeWithSeconds(1, 1)) let lastSecond = CMTimeRangeMake(CMTimeMakeWithSeconds(durationInSeconds-1, 1), CMTimeMakeWithSeconds(1, 1)) videoParam.setVolumeRamp(fromStartVolume: 0, toEndVolume: video.videoClipVolume, timeRange: firstSecond) videoParam.setVolumeRamp(fromStartVolume: video.videoClipVolume, toEndVolume: 0, timeRange: lastSecond) //Add parameter audioMix.inputParameters = audioMixParam // Export part, left for facility let exporter = AVAssetExportSession(asset: videoFilteredAsset, presetName: AVAssetExportPresetHighestQuality)! exporter.videoComposition = videoFilterComposition exporter.outputURL = url exporter.outputFileType = AVFileTypeQuickTimeMovie exporter.audioMix = audioMix exporter.exportAsynchronously(completionHandler: { () -> Void in completion!(exporter, url) }) }
之后,我再次使用一种方法来合并所有Video Clips使用方法AVAssetExportSession,在此我没有设置任何方法AudioMixInputParameters。
AVAssetExportSession
AudioMixInputParameters
Note:当我使用最后的合并方法设置音量时AVAssetExportSession's AudioMixInputParameters,就会Volume变满Video。
Note:
AVAssetExportSession's
我的问题:是否可以volume为每个设置多个Video Clips。请提出建议。谢谢!
这是我的问题的工作解决方案:
func addVolumeToIndividualVideoClip(_ assetURL: URL, video: VideoFileModel, completion : ((_ session: AVAssetExportSession?, _ outputURL : URL?) -> ())?){ //Create Asset from Url let filteredVideoAsset: AVAsset = AVAsset(url: assetURL) video.fileID = String(video.videoID) //Get the path of App Document Directory let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] let url = URL(fileURLWithPath: documentDirectory).appendingPathComponent("\(video.fileID)_\("FilterVideo").mov") let filePath = url.path let fileManager = FileManager.default do { if fileManager.fileExists(atPath: filePath) { print("FILE AVAILABLE") try fileManager.removeItem(atPath:filePath) } else { print("FILE NOT AVAILABLE") } } catch _ { } let composition: AVMutableComposition = AVMutableComposition() let compositionVideo: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID()) let compositionAudioVideo: AVMutableCompositionTrack = composition.addMutableTrack(withMediaType: AVMediaTypeAudio, preferredTrackID: CMPersistentTrackID()) //Add video to the final record do { try compositionVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, filteredVideoAsset.duration), of: filteredVideoAsset.tracks(withMediaType: AVMediaTypeVideo)[0], at: kCMTimeZero) } catch _ { } //Extract audio from the video and the music let audioMix: AVMutableAudioMix = AVMutableAudioMix() var audioMixParam: [AVMutableAudioMixInputParameters] = [] let assetVideoTrack: AVAssetTrack = filteredVideoAsset.tracks(withMediaType: AVMediaTypeAudio)[0] let videoParam: AVMutableAudioMixInputParameters = AVMutableAudioMixInputParameters(track: assetVideoTrack) videoParam.trackID = compositionAudioVideo.trackID //Set final volume of the audio record and the music videoParam.setVolume(video.videoVolume, at: kCMTimeZero) //Add setting audioMixParam.append(videoParam) //Add audio on final record //First: the audio of the record and Second: the music do { try compositionAudioVideo.insertTimeRange(CMTimeRangeMake(kCMTimeZero, filteredVideoAsset.duration), of: assetVideoTrack, at: kCMTimeZero) } catch _ { assertionFailure() } //Fading volume out for background music let durationInSeconds = CMTimeGetSeconds(filteredVideoAsset.duration) let firstSecond = CMTimeRangeMake(CMTimeMakeWithSeconds(0, 1), CMTimeMakeWithSeconds(1, 1)) let lastSecond = CMTimeRangeMake(CMTimeMakeWithSeconds(durationInSeconds-1, 1), CMTimeMakeWithSeconds(1, 1)) videoParam.setVolumeRamp(fromStartVolume: 0, toEndVolume: video.videoVolume, timeRange: firstSecond) videoParam.setVolumeRamp(fromStartVolume: video.videoVolume, toEndVolume: 0, timeRange: lastSecond) //Add parameter audioMix.inputParameters = audioMixParam //Remove the previous temp video if exist let filemgr = FileManager.default do { if filemgr.fileExists(atPath: "\(video.fileID)_\("FilterVideo").mov") { try filemgr.removeItem(atPath: "\(video.fileID)_\("FilterVideo").mov") } else { } } catch _ { } //Exporte the final record’ let exporter: AVAssetExportSession = AVAssetExportSession(asset: composition, presetName: AVAssetExportPresetHighestQuality)! exporter.outputURL = url exporter.outputFileType = AVFileTypeMPEG4 exporter.audioMix = audioMix exporter.exportAsynchronously(completionHandler: { () -> Void in completion!(exporter, url) // self.saveVideoToLibrary(from: filePath) }) }