以编程方式在视频Swift上添加UIView层
我试图在视频上添加UIView,我使用的代码来自我在互联网上找到的Tutiarial() 功能代码如下所示:以编程方式在视频Swift上添加UIView层,swift,avassetexportsession,avmutablecomposition,avurlasset,Swift,Avassetexportsession,Avmutablecomposition,Avurlasset,我试图在视频上添加UIView,我使用的代码来自我在互联网上找到的Tutiarial() 功能代码如下所示: func addViewToVideo(fromVideoAt videoURL: URL, withView: UIView, onComplete: @escaping (URL?) -> Void) { let asset = AVURLAsset(url: videoURL) let composition = AVMutableComposition()
func addViewToVideo(fromVideoAt videoURL: URL, withView: UIView, onComplete: @escaping (URL?) -> Void) {
let asset = AVURLAsset(url: videoURL)
let composition = AVMutableComposition()
guard
let compositionTrack = composition.addMutableTrack(
withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid),
let assetTrack = asset.tracks(withMediaType: .video).first
else {
print("Something is wrong with the asset.")
onComplete(nil)
return
}
do {
let timeRange = CMTimeRange(start: .zero, duration: asset.duration)
try compositionTrack.insertTimeRange(timeRange, of: assetTrack, at: .zero)
if let audioAssetTrack = asset.tracks(withMediaType: .audio).first,
let compositionAudioTrack = composition.addMutableTrack(
withMediaType: .audio,
preferredTrackID: kCMPersistentTrackID_Invalid) {
try compositionAudioTrack.insertTimeRange(
timeRange,
of: audioAssetTrack,
at: .zero)
}
} catch {
print(error)
onComplete(nil)
return
}
compositionTrack.preferredTransform = assetTrack.preferredTransform
let videoSize: CGSize = CGSize(width: assetTrack.naturalSize.height, height: assetTrack.naturalSize.width)
let videoLayer = CALayer()
videoLayer.frame = CGRect(origin: .zero, size: videoSize)
let overlayLayer = CALayer()
overlayLayer.frame = CGRect(origin: .zero, size: videoSize)
addImage(imagePassed: self.upperView.asImage(), to: overlayLayer, videoSize: videoSize)
let outputLayer = CALayer()
outputLayer.frame = CGRect(origin: .zero, size: videoSize)
outputLayer.addSublayer(videoLayer)
outputLayer.addSublayer(overlayLayer)
let videoComposition = AVMutableVideoComposition()
videoComposition.renderSize = videoSize
videoComposition.frameDuration = CMTime(value: 1, timescale: 30)
videoComposition.animationTool = AVVideoCompositionCoreAnimationTool(
postProcessingAsVideoLayer: videoLayer,
in: outputLayer)
let instruction = AVMutableVideoCompositionInstruction()
instruction.timeRange = CMTimeRange(
start: .zero,
duration: composition.duration)
videoComposition.instructions = [instruction]
let layerInstruction = compositionLayerInstruction(
for: compositionTrack,
assetTrack: assetTrack)
instruction.layerInstructions = [layerInstruction]
guard let export = AVAssetExportSession(
asset: composition,
presetName: AVAssetExportPresetHighestQuality)
else {
print("Cannot create export session.")
onComplete(nil)
return
}
let videoName = UUID().uuidString
let exportURL = URL(fileURLWithPath: NSTemporaryDirectory())
.appendingPathComponent(videoName)
.appendingPathExtension("mov")
export.videoComposition = videoComposition
export.outputFileType = .mov
export.outputURL = exportURL
export.exportAsynchronously {
DispatchQueue.main.async {
switch export.status {
case .completed:
onComplete(exportURL)
default:
print("Something went wrong during export.")
print(export.error ?? "unknown error")
onComplete(nil)
break
}
}
}
}
private func addImage(imagePassed: UIImage, to layer: CALayer, videoSize: CGSize) {
let image = imagePassed
let imageLayer = CALayer()
let aspect: CGFloat = image.size.width / image.size.height
let width = videoSize.width
let height = width / aspect
imageLayer.frame = CGRect(
x: 0,
y: -height * 0.15,
width: width,
height: height)
imageLayer.contents = image.cgImage
layer.addSublayer(imageLayer)
}
private func compositionLayerInstruction(for track: AVCompositionTrack, assetTrack: AVAssetTrack) -> AVMutableVideoCompositionLayerInstruction {
let instruction = AVMutableVideoCompositionLayerInstruction(assetTrack: track)
let transform = assetTrack.preferredTransform
instruction.setTransform(transform, at: .zero)
return instruction
}
它工作得很好,但我不知道是什么原因,当url来自前摄像头时,视频仅显示在视图的上部。
这就像一半是视频,一半是黑屏。可能是转换的问题。可能会对你有所帮助谢谢,我实现了你链接的问题中的解决方案,但它并没有完全解决问题,我达到的最佳水平是在视频显示时倒置@aheze时对
cAffineTransform(a:0,b:-1,c:1,d:0,tx:0,ty:assetSize.width)