iOS Swift实现无画质损失的视频裁剪与缩放
问题描述
我正尝试基于ScrollView的用户输入,实现特定视频的裁剪与缩放功能。现有一个支持图片和视频的可缩放视图,包含ScrollView和AVPlayerLayer,用户可在视图内缩放、平移,后续将进行裁剪。我已能计算裁剪区域并在AVMutableComposition中重新定位视频,但无法在不损失画质的情况下让视频适配渲染尺寸。我希望截图2填充截图3的渲染尺寸,同时呈现截图1的效果。注:请忽略截图画质,为上传至SO我将其转为了JPEG格式。
当前实现代码
if let videoMutableTrack = composition.addMutableTrack(withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid) { do { try videoMutableTrack.insertTimeRange(CMTimeRangeMake(start: .zero, duration: fileAsset.duration), of: videoTrack, at: .zero) } catch { print(error) self.setErrorInfo(error) completionHandler(nil) return } if (fileAsset.duration > maxDuration) { maxDuration = fileAsset.duration } let size = videoMutableTrack.naturalSize.applying(videoMutableTrack.preferredTransform) var scaleRatioX = (renderSize.width / 2) / size.width var scaleRatioY = (renderSize.height) / size.height if (rotate) { scaleRatioX = (renderSize.width) / size.width scaleRatioY = (renderSize.height / 2) / size.height } var scale = CGAffineTransform(scaleX: scaleRatioX, y: scaleRatioY) let offsetX = -currentVideoView.contentOffset.x let offsetY = -currentVideoView.contentOffset.y let layerInstruction = AVMutableVideoCompositionLayerInstruction(assetTrack: videoMutableTrack) if (videoFile.fileId == 1) { var move = CGAffineTransform(translationX: 0, y: 0) if (shouldUseDefaultScaling(currentVideoView)) { scale = CGAffineTransform(scaleX: scaleRatioX * (currentVideoView.zoomScale / 2), y: scaleRatioY * (currentVideoView.zoomScale / 2)) move = CGAffineTransform(translationX: offsetX, y: offsetY) } layerInstruction.setTransform(move.concatenating(scale), at: .zero) } else { var move = CGAffineTransform(translationX: size.width, y: 0) if (rotate) { move = CGAffineTransform(translationX: 0, y: size.height) } if (shouldUseDefaultScaling(currentVideoView)) { scale = CGAffineTransform(scaleX: scaleRatioX * currentVideoView.zoomScale, y: scaleRatioY * currentVideoView.zoomScale) move = CGAffineTransform(translationX: offsetX, y: offsetY) } layerInstruction.setTransform(move.concatenating(scale), at: .zero) } compositionInstruction.layerInstructions.append(layerInstruction) } let currentFrameRate = Int(roundf((videoTrack.nominalFrameRate))) highestFrameRate = (currentFrameRate > highestFrameRate) ? currentFrameRate : highestFrameRate compositionInstruction.timeRange = CMTimeRangeMake(start: .zero, duration: maxDuration) let videoLayer = CALayer() videoLayer.frame = CGRect(origin: .zero, size: renderSize) let mutableVideoComposition = AVMutableVideoComposition() mutableVideoComposition.instructions = [compositionInstruction] mutableVideoComposition.frameDuration = CMTimeMake(value: 1, timescale: Int32(highestFrameRate)) mutableVideoComposition.renderSize = renderSize mutableVideoComposition.animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: outputLayer)
相关截图
- 用户选择视频/照片:

- 裁剪后(无缩放):

- 裁剪后(已缩放):

内容的提问来源于stack exchange,提问作者Joe Ginley
相关产品推荐
相关产品推荐

