gpt4 book ai didi

ios - 合并视频但 AVAssetExportSession 从未完成

转载 作者:可可西里 更新时间:2023-11-01 03:17:11 31 4
gpt4 key购买 nike

尝试将一些视频合并在一起并将它们导出为单个文件,从教程/示例来看,一切似乎都是正确的,但是我的 AVAssetExportSession 似乎从来没有完成过,我的视频文件也从未导出过,任何帮助非常感谢我遗漏的明显错误。

下面是我合并视频的功能

请注意,循环中的“视频”是一个成员变量 var videos = [AVAsset](),它在调用合并之前被填充(我确实检查过)。

private func merge()
{
// Create AVMutableComposition to contain all AVMutableComposition tracks
var mix_composition = AVMutableComposition()
var total_time_seconds = 0.0
var tracks = [AVCompositionTrack]()

// Loop over videos and create tracks, keep incrementing total duration
for video in videos
{
// Create the composition track for this video
let track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

// Add video duration to total time
total_time_seconds = total_time_seconds + video.duration.seconds

// Add track to array of tracks
tracks.append(track)

// Add time range to track
do
{
try track.insertTimeRange(CMTimeRangeMake(kCMTimeZero, video.duration), ofTrack: video.tracksWithMediaType(AVMediaTypeVideo)[0], atTime: video.duration)
}
catch _
{
}
}

// Set total time
let preferred_time_scale: Int32 = 600;
let total_time = CMTimeMakeWithSeconds(total_time_seconds, preferred_time_scale)

// Create main instrcution for video composition
let main_instruction = AVMutableVideoCompositionInstruction()
main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, total_time)

// Create array to hold instructions
var layer_instructions = [AVVideoCompositionLayerInstruction]()

// Ensure we have the same number of tracks as videos
if videos.count == tracks.count
{
// Loop number of videos and tracks
for var index = 0; index < videos.count; ++index
{
// Create compositioninstruction for each track
let instruction = videoCompositionInstructionForTrack(tracks[index], asset: videos[index])

if(index == 0)
{
instruction.setOpacity(0.0, atTime: videos[index].duration)
}

// Add instruction to instructions array
layer_instructions.append(instruction)
}
}

// Set tack instructions to main instruction
main_instruction.layerInstructions = layer_instructions
let main_composition = AVMutableVideoComposition()
main_composition.instructions = [main_instruction]
main_composition.frameDuration = CMTimeMake(1, 30)
main_composition.renderSize = CGSize(width: UIScreen.mainScreen().bounds.width, height: UIScreen.mainScreen().bounds.height)

// Get path for Final video in the current project directory
let documents_url = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let final_url = documents_url.URLByAppendingPathComponent("TEST.mp4")

// Create AV Export Session
let exporter = AVAssetExportSession(asset: mix_composition, presetName: AVAssetExportPresetHighestQuality)
exporter!.outputURL = final_url
exporter!.outputFileType = AVFileTypeMPEG4
exporter!.shouldOptimizeForNetworkUse = true
exporter!.videoComposition = main_composition

// Perform the Export
exporter!.exportAsynchronouslyWithCompletionHandler() {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
self.exportDidFinish(exporter!)
})
}
}

下面显示了调用 exportAsynchronouslyWithCompletionHandler 时调用的 exportDidFinished 函数。我进入了这个函数,但什么也没有发生,因为 session 状态从未完成。

func exportDidFinish(session: AVAssetExportSession)
{
if session.status == AVAssetExportSessionStatus.Completed
{
let outputURL = session.outputURL
let library = ALAssetsLibrary()
if library.videoAtPathIsCompatibleWithSavedPhotosAlbum(outputURL)
{
library.writeVideoAtPathToSavedPhotosAlbum(outputURL,
completionBlock: { (assetURL:NSURL!, error:NSError!) -> Void in
if error != nil
{
let alert = UIAlertView(title: "Error", message: "Video Not Saved", delegate: nil, cancelButtonTitle: "OK")
alert.show()

}
else
{
let alert = UIAlertView(title: "Success", message: "Video Saved", delegate: nil, cancelButtonTitle: "OK")
alert.show()
}
})
}
}
}

打印的 session 状态显示它是 4,这是失败的,所以我打印了 session.error 并得到了这个,但我不确定这意味着什么,任何帮助都会很好

Optional(Error Domain=AVFoundationErrorDomain Code=-11841 "Operation Stopped" UserInfo={NSLocalizedDescription=Operation Stopped, NSLocalizedFailureReason=The video could not be composed.}) 

最佳答案

如果 exportDidFinish 被调用但没有任何反应,则您的 session 状态不是 AVAssetExportSessionStatus.Completed。它可能是 AVAssetExportSessionStatus.Failed 或其他一些值。检查这些值,如果它确实失败,请检查 session.error 属性以获取更多信息。

编辑:如果您希望一个视频接一个播放,请只创建一个 AVMutableCompositionTrack。请参阅下面的相关更改:

    ...
var mix_composition = AVMutableComposition()

// Create the composition track for the videos
let track = mix_composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: Int32(kCMPersistentTrackID_Invalid))

//keep track of total time
var totalTime = kCMTimeZero

for video in videos
{
// Add time range to track
do
{
let videoTrack = video.tracksWithMediaType(AVMediaTypeVideo)[0]
let videoDuration = videoTrack.duration
let timeRange = CMTimeRangeMake(kCMTimeZero,videoDuration)

try track.insertTimeRange(timeRange, ofTrack: videoTrack, atTime: totalTime)

totalTime = CMTimeAdd(totalTime,videoDuration)
}
catch _
{
}
}

// Create main instruction for video composition
let main_instruction = AVMutableVideoCompositionInstruction()
main_instruction.timeRange = CMTimeRangeMake(kCMTimeZero, totalTime)

// Create array to hold instructions
var layer_instructions = [AVVideoCompositionLayerInstruction]()

// Create layer instruction
let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)

// Add it to the array
layer_instructions.append(layerInstruction)

...

您还需要将 renderSize 调整为合适的值。视频的大小可能不是屏幕的大小。

关于ios - 合并视频但 AVAssetExportSession 从未完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32809076/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com