I wrote a program in Swift.I want to merge a video with an audio file, but got this error.
"failed Error Domain=AVFoundationErrorDomain Code=-11838 "Operation Stopped" UserInfo=0x17da4230 {NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The operation is not supported for this media.}" Code
func mergeVideoWithAudio(videoUrl: URL, audioUrl: URL, success: @escaping ((URL) -> Void), failure: @escaping ((Error?) -> Void)) {
let mixComposition: AVMutableComposition = AVMutableComposition()
var mutableCompositionVideoTrack: [AVMutableCompositionTrack] = []
var mutableCompositionAudioTrack: [AVMutableCompositionTrack] = []
let totalVideoCompositionInstruction : AVMutableVideoCompositionInstruction = AVMutableVideoCompositionInstruction()
let aVideoAsset: AVAsset = AVAsset(url: videoUrl)
let aAudioAsset: AVAsset = AVAsset(url: audioUrl)
if let videoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid), let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: kCMPersistentTrackID_Invalid) {
mutableCompositionVideoTrack.append(videoTrack)
mutableCompositionAudioTrack.append(audioTrack)
if let aVideoAssetTrack: AVAssetTrack = aVideoAsset.tracks(withMediaType: .video).first, let aAudioAssetTrack: AVAssetTrack = aAudioAsset.tracks(withMediaType: .audio).first {
do {
try mutableCompositionVideoTrack.first?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aVideoAssetTrack, at: CMTime.zero)
try mutableCompositionAudioTrack.first?.insertTimeRange(CMTimeRangeMake(start: CMTime.zero, duration: aVideoAssetTrack.timeRange.duration), of: aAudioAssetTrack, at: CMTime.zero)
videoTrack.preferredTransform = aVideoAssetTrack.preferredTransform
} catch{
print(error)
}
totalVideoCompositionInstruction.timeRange = CMTimeRangeMake(start: CMTime.zero,duration: videoTrack.timeRange.duration)
}
}
let mutableVideoComposition: AVMutableVideoComposition = AVMutableVideoComposition()
mutableVideoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30)
mutableVideoComposition.renderSize = CGSize(width: 480, height: 640)
if let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first {
let outputURL = URL(fileURLWithPath: documentsPath).appendingPathComponent("\("fileName").mp4")
do {
if FileManager.default.fileExists(atPath: outputURL.path) {
try FileManager.default.removeItem(at: outputURL)
}
} catch { }
// var outputURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("temp_video_data.mp4", isDirectory: false)
// outputURL = URL(fileURLWithPath: outputURL.path)
// let mediaItems = MPMediaQuery.songs().items
// let mediaCollection = MPMediaItemCollection(items: mediaItems ?? [])
// let player1 = MPMusicPlayerController.systemMusicPlayer
// player1.setQueue(with: mediaCollection)
// player1.play()
// guard let url = URL(string: url )else {return}
// let player = AVPlayer(url: url)
// let playerController = AVPlayerViewController()
// playerController.player = player
// playerController.allowsPictureInPicturePlayback = true
// playerController.delegate = self
// playerController.player?.play()
// present(playerController, animated: true, completion: nil)
// let player3 = AVPlayer(url: vidUrl!)
// let playerLayer3 = AVPlayerLayer(player: player3)
// playerLayer3.videoGravity = .resizeAspect
// playerLayer3.needsDisplayOnBoundsChange = true //
// playerLayer3.frame = self.videoImg.bounds // 1
//
// self.videoImg.layer.masksToBounds = true // 2
// self.videoImg.layer.addSublayer(playerLayer3)
// player3.play()
// let assetsLib = PHPhotoLibrary()
// assetsLib.
// assetsLib.writeVideoAtPath(toSavedPhotosAlbum: outputURL, completionBlock: nil)
print(outputURL, "outputURL.....")
if let exportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality) {
exportSession.outputURL = NSURL.fileURL(withPath: outputURL.path)
exportSession.outputFileType = AVFileType.mov
exportSession.shouldOptimizeForNetworkUse = true
// try to export the file and handle the status cases
exportSession.exportAsynchronously(completionHandler: {
switch exportSession.status {
case .failed:
if let _error = exportSession.error {
print("failedddd",_error)
failure(_error)
}
case .cancelled:
if let _error = exportSession.error {
print("cancellled")
failure(_error)
}
default:
print("finished")
success(outputURL)
}
})
} else {
print("failurrrrrrrr")
failure(nil)
}
}
}
Here the calling of Function
let vidUrl! = file:///private/var/mobile/Containers/Data/PluginKitPlugin/C6BD4529-DF11-4A67-B56E-C3A841D86D75/tmp/trim.CC7EABA8-08EC-4C33-8E6A-E85A5EBCFB64.MOV
let outputURL! = file:///var/mobile/Containers/Data/Application/9115DCFE-4134-48AD-84BF-452AC0D33278/Documents/y2matecom-ChallaOfficialFullVideoKhanSaabAYMediaRecordsLatestPunjabiSongs2016.mp3
mergeVideoWithAudio(videoUrl: vidUrl!, audioUrl: outputURL!) { resultUrl in
print("sucessssssssss",resultUrl)
} failure: { error in
print(error?.localizedDescription,"hgjjhfghdg")
}
Note:Every time the Failure Block calls and cause operation stopped
In my idea media type like mpeg4 is wrong. Where is the problem? What am i missing?