gpt4 book ai didi

swift - 如何合并 2 个带有淡入淡出过渡的视频?

转载 作者:行者123 更新时间:2023-12-04 01:38:57 25 4
gpt4 key购买 nike

我正在尝试合并两个重叠 2 秒的视频。在这个重叠中,我想淡入第二个视频(或淡出第一个以显示第二个,任何一个都很棒)。

第一个视频在结束前 2 秒按预期淡出,但随着它的淡出,我得到一个黑屏,而不是第二个视频淡入。在视频 1 的结尾,视频 2 出现在其淡入动画的一半。

我看不到它们重叠的轨道有什么问题?下面是我的代码

func setupVideo() {

let url = URL(fileURLWithPath: Bundle.main.path(forResource: "demoVideoTwo", ofType: "mp4")!)
let assetOne = AVAsset(url: url)

let urlTwo = URL(fileURLWithPath: Bundle.main.path(forResource: "demoVideoThree", ofType: "mp4")!)
let assetTwo = AVAsset(url: urlTwo)

let mixComposition = AVMutableComposition()
var instructions = [AVMutableVideoCompositionLayerInstruction]()
var mainInstructionList = [AVMutableVideoCompositionInstruction]()
var lastTime = CMTime.zero

// Create Track One

guard let videoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)), let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else {
return
}

// Setup AVAsset 1

let timeRange = CMTimeRangeMake(start: CMTime.zero, duration: assetOne.duration)

do {
try videoTrack.insertTimeRange(timeRange, of: assetOne.tracks(withMediaType: .video)[0], at: lastTime)

try audioTrack.insertTimeRange(timeRange, of: assetOne.tracks(withMediaType: .audio)[0], at: lastTime)

} catch {
print(error)
}

// Setup Layer Instruction 1

let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

let duration = CMTime(seconds: 2, preferredTimescale: 60)
let transitTime = CMTime(seconds: 2, preferredTimescale: 60)
let insertTime = CMTimeSubtract(assetOne.duration, transitTime)
let instRange = CMTimeRangeMake(start: insertTime, duration: duration)
layerInstruction.setOpacityRamp(fromStartOpacity: 1.0, toEndOpacity: 0.0, timeRange: instRange)
instructions.append(layerInstruction)

let mainInstruction = AVMutableVideoCompositionInstruction()
mainInstruction.timeRange = CMTimeRangeMake(start: lastTime, duration: assetOne.duration)
mainInstruction.layerInstructions = instructions

mainInstructionList.append(mainInstruction)

lastTime = CMTimeAdd(lastTime, assetOne.duration)


// Create Track One

guard let videoTrackTwo = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)), let audioTrackTwo = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else {
return
}

// Setup AVAsset 2

let transitionTime = CMTime(seconds: 2, preferredTimescale: 60)
let newLastTime = CMTimeSubtract(assetOne.duration, transitionTime)

let timeRangeTwo = CMTimeRangeMake(start: CMTime.zero, duration: assetTwo.duration)

do {
try videoTrackTwo.insertTimeRange(timeRangeTwo, of: assetTwo.tracks(withMediaType: .video)[0], at: newLastTime)

try audioTrackTwo.insertTimeRange(timeRangeTwo, of: assetTwo.tracks(withMediaType: .audio)[0], at: newLastTime)

} catch {
print(error)
}


// Setup Layer Instruction 2

let layerInstructionTwo = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrackTwo)
let durationTwo = CMTime(seconds: 4, preferredTimescale: 60)
let instRangeTwo = CMTimeRangeMake(start: newLastTime, duration: durationTwo)
layerInstructionTwo.setOpacityRamp(fromStartOpacity: 0.0, toEndOpacity: 1.0, timeRange: instRangeTwo)
instructions.append(layerInstructionTwo)

let mainInstructionTwo = AVMutableVideoCompositionInstruction()
mainInstructionTwo.timeRange = CMTimeRangeMake(start: lastTime, duration: assetTwo.duration)
mainInstructionTwo.layerInstructions = instructions

mainInstructionList.append(mainInstructionTwo)

// Setup Video Composition

let mainComposition = AVMutableVideoComposition()
mainComposition.instructions = mainInstructionList
mainComposition.frameDuration = CMTimeMake(value: 1, timescale: 60)
mainComposition.renderSize = videoTrack.naturalSize

let item = AVPlayerItem(asset: mixComposition)
item.videoComposition = mainComposition

player = AVPlayer(playerItem: item)

let playerLayer: AVPlayerLayer = {
let layer = AVPlayerLayer(player: player)
layer.videoGravity = .resizeAspectFill
return layer
}()

let playerWidth: CGFloat = UIScreen.main.bounds.size.width
let videoHeight = UIScreen.main.bounds.size.width * 9 / 16

playerLayer.frame = CGRect(x: 0, y: 0, width: playerWidth, height: videoHeight)
self.layer.addSublayer(playerLayer)
}

最佳答案

不要为每个创建 AVMutableVideoCompositionInstruction
视频轨道,不要每次都为其分配指令。相反,在创建 AVMutableVideoComposition 之前只创建一次 AVMutableVideoCompositionInstruction 然后为其分配指令。

这是按照您想要的方式工作的代码。

func setupVideo() {

let url = URL(fileURLWithPath: Bundle.main.path(forResource: "demoVideoTwo", ofType: "mp4")!)
let assetOne = AVAsset(url: url)

let urlTwo = URL(fileURLWithPath: Bundle.main.path(forResource: "demoVideoTwo", ofType: "mp4")!)
let assetTwo = AVAsset(url: urlTwo)

let mixComposition = AVMutableComposition()
var instructions = [AVMutableVideoCompositionLayerInstruction]()
var lastTime = CMTime.zero

// Create Track One

guard let videoTrack = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)), let audioTrack = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else {
return
}

// Setup AVAsset 1

let timeRange = CMTimeRangeMake(start: CMTime.zero, duration: assetOne.duration)

do {
try videoTrack.insertTimeRange(timeRange, of: assetOne.tracks(withMediaType: .video)[0], at: lastTime)

try audioTrack.insertTimeRange(timeRange, of: assetOne.tracks(withMediaType: .audio)[0], at: lastTime)

} catch {
print(error)
}

// Setup Layer Instruction 1

let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack)

let duration = CMTime(seconds: 2, preferredTimescale: 60)
let transitTime = CMTime(seconds: 2, preferredTimescale: 60)
let insertTime = CMTimeSubtract(assetOne.duration, transitTime)
let instRange = CMTimeRangeMake(start: insertTime, duration: duration)
layerInstruction.setOpacityRamp(fromStartOpacity: 1.0, toEndOpacity: 0.0, timeRange: instRange)
instructions.append(layerInstruction)

lastTime = CMTimeAdd(lastTime, assetOne.duration)


// Create Track One

guard let videoTrackTwo = mixComposition.addMutableTrack(withMediaType: .video, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)), let audioTrackTwo = mixComposition.addMutableTrack(withMediaType: .audio, preferredTrackID: Int32(kCMPersistentTrackID_Invalid)) else {
return
}

// Setup AVAsset 2

let transitionTime = CMTime(seconds: 2, preferredTimescale: 60)
let newLastTime = CMTimeSubtract(assetOne.duration, transitionTime)

let timeRangeTwo = CMTimeRangeMake(start: CMTime.zero, duration: assetTwo.duration)

do {
try videoTrackTwo.insertTimeRange(timeRangeTwo, of: assetTwo.tracks(withMediaType: .video)[0], at: newLastTime)

try audioTrackTwo.insertTimeRange(timeRangeTwo, of: assetTwo.tracks(withMediaType: .audio)[0], at: newLastTime)

} catch {
print(error)
}

// Setup Layer Instruction 2

let layerInstructionTwo = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrackTwo)
layerInstructionTwo.setOpacity(1.0, at: newLastTime)
instructions.append(layerInstructionTwo)

// Setup Video Composition

let mainInstruction = AVMutableVideoCompositionInstruction()
mainInstruction.timeRange = CMTimeRangeMake(start: .zero, duration: CMTimeAdd(newLastTime, assetTwo.duration))
mainInstruction.layerInstructions = instructions

let mainComposition = AVMutableVideoComposition()
mainComposition.instructions = [mainInstruction]
mainComposition.frameDuration = CMTimeMake(value: 1, timescale: 60)
mainComposition.renderSize = videoTrack.naturalSize

let item = AVPlayerItem(asset: mixComposition)
item.videoComposition = mainComposition

player = AVPlayer(playerItem: item)

let playerLayer: AVPlayerLayer = {
let layer = AVPlayerLayer(player: player)
layer.videoGravity = .resizeAspectFill
return layer
}()

let playerWidth: CGFloat = UIScreen.main.bounds.size.width
let videoHeight = UIScreen.main.bounds.size.width * 9 / 16

playerLayer.frame = CGRect(x: 0, y: 0, width: playerWidth, height: videoHeight)
self.layer.addSublayer(playerLayer)
}

关于swift - 如何合并 2 个带有淡入淡出过渡的视频?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58386937/

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