求助: AVAssetExportSession 在正常runtime下不工作
我想把一个音频和视频merge到一起,但是output的时候总是会跳出NSUncaught exception,奇怪的是如果是一行一行stepover就可以正常工作。我感觉应该是thread出了问题,但是找不到具体的点。
这是我merge的函数。
这是我call function的地方。
这是我merge的函数。
/// Merges video and sound while keeping sound of the video too
///
/// - Parameters:
/// - videoUrl: URL to video file
/// - audioUrl: URL to audio file
/// - shouldFlipHorizontally: pass True if video was recorded using frontal camera otherwise pass False
/// - completion: completion of saving: error or url with final video
func mergeVideoAndAudio(videoUrl: URL,
audioUrl: URL,
shouldFlipHorizontally: Bool = false,
completion: @escaping (_ error: Error?, _ url: URL?) -> Void) {
let mixComposition = AVMutableComposition()
var mutableCompositionVideoTrack = [AVMutableCompositionTrack]()
var mutableCompositionAudioTrack = [AVMutableCompositionTrack]()
var mutableCompositionAudioOfVideoTrack = [AVMutableCompositionTrack]()
//start merge
let aVideoAsset = AVAsset(url: videoUrl)
let aAudioAsset = AVAsset(url: audioUrl)
let compositionAddVideo = mixComposition.addMutableTrack(withMediaType: AVMediaType.video,
preferredTrackID: kCMPersistentTrackID_Invalid)
let compositionAddAudio = mixComposition.addMutableTrack(withMediaType: AVMediaType.audio,
preferredTrackID: kCMPersistentTrackID_Invalid)
let compositionAddAudioOfVideo = mixComposition.addMutableTrack(withMediaType: AVMediaType.audio,
preferredTrackID: kCMPersistentTrackID_Invalid)
let aVideoAssetTrack: AVAssetTrack = aVideoAsset.tracks(withMediaType: AVMediaType.video)[0]
let aAudioOfVideoAssetTrack: AVAssetTrack? = aVideoAsset.tracks(withMediaType: AVMediaType.audio).first
let aAudioAssetTrack: AVAssetTrack = aAudioAsset.tracks(withMediaType: AVMediaType.audio)[0]
// Default must have tranformation
compositionAddVideo?.preferredTransform = aVideoAssetTrack.preferredTransform
if shouldFlipHorizontally {
// Flip video horizontally
var frontalTransform: CGAffineTransform = CGAffineTransform(scaleX: -1.0, y: 1.0)
frontalTransform = frontalTransform.translatedBy(x: -aVideoAssetTrack.naturalSize.width, y: 0.0)
frontalTransform = frontalTransform.translatedBy(x: 0.0, y: -aVideoAssetTrack.naturalSize.width)
compositionAddVideo?.preferredTransform = frontalTransform
}
mutableCompositionVideoTrack.append(compositionAddVideo!)
mutableCompositionAudioTrack.append(compositionAddAudio!)
mutableCompositionAudioOfVideoTrack.append(compositionAddAudioOfVideo!)
do {
try mutableCompositionVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero,
aVideoAssetTrack.timeRange.duration),
of: aVideoAssetTrack,
at: kCMTimeZero)
//In my case my audio file is longer then video file so i took videoAsset duration
//instead of audioAsset duration
try mutableCompositionAudioTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero,
aVideoAssetTrack.timeRange.duration),
of: aAudioAssetTrack,
at: kCMTimeZero)
// adding audio (of the video if exists) asset to the final composition
if let aAudioOfVideoAssetTrack = aAudioOfVideoAssetTrack {
try mutableCompositionAudioOfVideoTrack[0].insertTimeRange(CMTimeRangeMake(kCMTimeZero,
aVideoAssetTrack.timeRange.duration),
of: aAudioOfVideoAssetTrack,
at: kCMTimeZero)
}
} catch {
print(error.localizedDescription)
}
// Exporting
let savePathUrl: URL = URL(fileURLWithPath: NSHomeDirectory() + "/Documents/newVideo.mp4")
do { // delete old video
try FileManager.default.removeItem(at: savePathUrl)
} catch { print(error.localizedDescription) }
let assetExport: AVAssetExportSession = AVAssetExportSession(asset: mixComposition, presetName: AVAssetExportPresetHighestQuality)!
assetExport.outputFileType = AVFileType.mp4
assetExport.outputURL = savePathUrl
assetExport.shouldOptimizeForNetworkUse = true
assetExport.exportAsynchronously{ () -> Void in
switch assetExport.status {
case AVAssetExportSessionStatus.completed:
print("success")
completion(nil, savePathUrl)
case AVAssetExportSessionStatus.failed:
print("failed \(assetExport.error?.localizedDescription ?? "error nil")")
completion(assetExport.error, nil)
case AVAssetExportSessionStatus.cancelled:
print("cancelled \(assetExport.error?.localizedDescription ?? "error nil")")
completion(assetExport.error, nil)
default:
print("complete")
completion(assetExport.error, nil)
}
}
}这是我call function的地方。
@objc func touchCameraButton(){
soundFileURL!, completion: {(err, url) in print("fuck")})
if isVideoRecordingOn{
if isFirstTouch{
startCapture()
recordAudio()
isFirstTouch = false
}else{
startCapture()
recordAudio()
self.mergeVideoAndAudio(videoUrl: videoFileURL, audioUrl: soundFileURL!, shouldFlipHorizontally: true, completion: {(err, url) in DispatchQueue.main.async {
self.videoWithAudioURL = url
if (err != nil){
print(err?.localizedDescription ?? "Error in merging video and audio")
}
self.isFirstTouch = true
}
})
}
}
}
...全文
相关推荐
VC++ Runtime
需要的朋友可以下載
STM32上电复位不正常 手动复位正常的原因
电路上电不复位的原因可能是多方面的,特别是stm32f030和外围电路均需要复位的情况,因此各个模块可能需要隔离测试,最终锁定问题才能找到解决的方法。
Failed shutdown of Apache Portable Runtime 解决办法
NULL 博文链接:https://huanyue.iteye.com/blog/479413
office2021文档图标显示不正常怎么办?.docx
office2021文档图标显示不正常怎么办?.docx
如何判断集成电路IC是否正常工作?
如何准确判断电路中集成电路 IC 是否“偷懒”没处在工作状态,是好是坏是修理电视、音响、录像设备的一个重要内容,判断不准,往往花大力气换上新集成电路而故障依然存在,所以要对集成电路作出正确判断。 1、首先要掌握该电路中 IC 的用途、内部结构原理、主要电特性等,必要时还要分析内部电原理图。除了这些,如果再有各引脚对地直流电压、波形、对地正反向直流电阻值,那么,对检查前判断提供了更有利条件; 2、然后按故障现象判断其部位,再按部位查找故障元件。有时需要多种判断方法去证明该器件是否确属损坏。 3、一般对电路中 IC 的检查判断方法有两种:一是不在线判断,即电路中 IC 未焊入印刷电路板的判断


