可以直接拷贝到工具类中使用
import UIKit
import AVFoundation
enum AnimationType {
case fromRightToLeft
case fromLowerToUpper
case zoomOut
case zoomIn
case rotate
case fadeInFadeOut
}
class ImageAnimationTool {
static let shared = ImageAnimationTool()
private let outputPath: URL = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("imagesComposition.mp4")
private let url = URL(fileURLWithPath: NSTemporaryDirectory()).appendingPathComponent("baseVideo.mp4")
private var eachImageDuration: CGFloat = 3//每张图片默认三秒
private var animationDuration: CGFloat = 0.5
private var alphaAnimationDuration: CGFloat = 0.3
private var videoWidth: Int = 720
private var videoHeight: Int = 1280
private var FPS: Int32 = 30
private var videoResource: String?
private var videoDuration: CGFloat = 0
private var zoomRate: CGFloat = 1.2
private var animationType: AnimationType = .fromRightToLeft
private var mouldArray: [AnimationType] = [.fadeInFadeOut, .fadeInFadeOut, .fadeInFadeOut, .fadeInFadeOut, .fadeInFadeOut, .fadeInFadeOut,.fadeInFadeOut,.fadeInFadeOut,.fadeInFadeOut]
private lazy var videoSetting = [AVVideoCodecKey: AVVideoCodecType.h264, AVVideoWidthKey: NSNumber(value: videoWidth), AVVideoHeightKey: NSNumber(value: videoHeight)] as [String : Any]
func transacformImages(images: [UIImage?], audioUrl: URL? = nil, animationType: AnimationType = .fromRightToLeft, animationDuration: CGFloat = 0.5, alphaAnimationDuration: CGFloat = 0.3, zoomRate: CGFloat = 1.2, FPS: Int32 = 30, videoFrameWidth: Int = 720, videoFrameHeight: Int = 1280, eachImageDuration: CGFloat = 3, success: @escaping (URL) -> Void, failure: @escaping (Error?) -> Void) {
self.animationDuration = animationDuration
self.FPS = FPS
self.videoWidth = videoFrameWidth
self.videoHeight = videoFrameHeight
self.eachImageDuration = eachImageDuration
self.animationType = animationType
self.alphaAnimationDuration = alphaAnimationDuration
self.zoomRate = zoomRate
removeFileIfExist(url: url)
removeFileIfExist(url: outputPath)
do {
let videoWriter = try AVAssetWriter(outputURL: url, fileType: AVFileType.mov)
let writerInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSetting)
let zeroTime = CMTimeMake(value: Int64(0),timescale: self.FPS)
videoWriter.canAdd(writerInput)
videoWriter.add(writerInput)
let bufferAttributes:[String: Any] = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32ARGB)]
let bufferAdapter = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput, sourcePixelBufferAttributes: bufferAttributes)
videoWriter.startWriting()
videoWriter.startSession(atSourceTime: zeroTime)
let _ = images.enumerated().map {
(index, image) in
while !writerInput.isReadyForMoreMediaData {
}
guard let buffer = newPixelBufferFrom(image: UIImage()) else {
return }
let lastTime = CMTimeMake(value: Int64(index - 1) * Int64(FPS), timescale: self.FPS)
let presentTime = CMTimeAdd(lastTime, CMTimeMake(value: Int64(FPS), timescale: FPS))
bufferAdapter.append(buffer, withPresentationTime: index == 0 ? CMTime.zero : presentTime)
}
writerInput.markAsFinished()
videoWriter.finishWriting {
[weak self] in
switch videoWriter.status