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 videoInfo = orientation(from: assetTrack.preferredTransform)
let videoSize: CGSize
if videoInfo.isPortrait {
videoSize = CGSize(
width: assetTrack.naturalSize.height,
height: assetTrack.naturalSize.width)
} else {
videoSize = assetTrack.naturalSize
}
let videoLayer = CALayer()
videoLayer.frame = CGRect(origin: .zero, size: videoSize)
let textLayer = CATextLayer()
textLayer.string = mainTextview.text
textLayer.shouldRasterize = true
textLayer.rasterizationScale = UIScreen.main.scale
//textLayer.backgroundColor = UIColor.black.cgColor
switch textAlignment {
case .center:
textLayer.alignmentMode = .center
case .justified:
textLayer.alignmentMode = .justified
case .left:
textLayer.alignmentMode = .left
case .right:
textLayer.alignmentMode = .right
default:
textLayer.alignmentMode = .center
}
textLayer.isWrapped = true
textLayer.foregroundColor = mainTextview.textColor?.cgColor
textLayer.fontSize = 70
switch textWeight {
case .bold:
textLayer.font = UIFont.systemFont(ofSize: 0, weight: .bold)
case .light:
textLayer.font = UIFont.systemFont(ofSize: 0, weight: .light)
case .regular:
textLayer.font = UIFont.systemFont(ofSize: 0, weight: .regular)
case .medium:
textLayer.font = UIFont.systemFont(ofSize: 0, weight: .medium)
}
switch textviewPosition {
case .Center:
textLayer.frame = CGRect(x: 0, y: videoSize.height * 0.30, width: videoSize.width, height: 500)
case .Top:
textLayer.frame = CGRect(x: 0, y: videoSize.height * 0.60, width: videoSize.width, height: 500)
case .Bottom:
textLayer.frame = CGRect(x: 10, y: 0, width: videoSize.width, height: 500)
}
textLayer.displayIfNeeded()
let outputLayer = CALayer()
outputLayer.frame = CGRect(origin: .zero, size: videoSize)
outputLayer.addSublayer(videoLayer)
outputLayer.addSublayer(textLayer)
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(".mp4")
export.videoComposition = videoComposition
export.outputFileType = .mp4
export.outputURL = exportURL
export.exportAsynchronously {
DispatchQueue.main.async {
switch export.status {
case .completed:
onComplete(exportURL)
default:
onComplete(nil)
break
}
}
}
}
这是我用来在视频上覆盖文本的功能(videoURL),我传入保存在文档目录中的视频的 url,并使用已经为用户创建的 TextView 来检索文本、重量、字体和对齐覆盖谢谢。这个过程的大部分时间需要 15 秒,这对于用户来说是很长的等待时间。
最佳答案
导出视频是劳动密集型的,需要大量时间,对此您无能为力。
但是,该过程是异步的,因此无需让用户“等待”。此外,导出器提供一个 Progress 对象,因此您可以轻松地将进度显示为一种心理技巧(当您观看进度指示器时,时间过得真快)。
关于ios - 在视频上覆盖文本非常慢,任何更快的替代方案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63208051/