我一直在尝试调试(几天了)这段代码,从CGImages中产生一个视频。 CGImages实际上是由我在应用代码中画进的CGBitMapContext的创建的。 我在这里简化为简单地画一条黄色的对角线,并画出该静态图像的若干帧。 然而,这里是一帧(每一帧都是一样的)fo扭曲的视频,我发现在写到路径。
import Foundation
import CoreGraphics
import CoreMedia
import QuartzCore
import AVFoundation
func exportVideo(
width: Int = 500,
height: Int = 500,
numberOfFrames: Int = 100
) {
let vidURL = NSURL.fileURL(withPath: "/Users/me/Desktop/testVideo.mp4")
try? FileManager.default.removeItem(at: vidURL)
let settings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoWidthKey: width,
AVVideoHeightKey: height
]
let assetWriter = try! AVAssetWriter(url: vidURL, fileType: .m4v)
let writerInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: settings)
assetWriter.add(writerInput)
let queue = DispatchQueue.global(qos: .background)
writerInput.expectsMediaDataInRealTime = false
let inputAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput, sourcePixelBufferAttributes: nil)
assetWriter.startWriting()
assetWriter.startSession(atSourceTime: CMTime.zero)
writerInput.requestMediaDataWhenReady(on: queue) {
for i in 0..<numberOfFrames where writerInput.isReadyForMoreMediaData {
guard let buffer = newPixelBufferFrom(width: width, height: height) else {
fatalError()
}
inputAdaptor.append(
buffer,
withPresentationTime: CMTime(seconds: Double(i), preferredTimescale: CMTimeScale(10))
)
}
writerInput.markAsFinished()
assetWriter.finishWriting { }
}
}
private func newPixelBufferFrom(
width: Int,
height: Int
) -> CVPixelBuffer? {
let options:[String: Any] = [
kCVPixelBufferCGImageCompatibilityKey as String: true,
kCVPixelBufferCGBitmapContextCompatibilityKey as String: true
]
var pxbuffer: CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault,
width,
height,
kCVPixelFormatType_32ARGB,
options as CFDictionary?,
&pxbuffer)
assert(status == kCVReturnSuccess && pxbuffer != nil, "newPixelBuffer failed")
CVPixelBufferLockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0))
let pxdata = CVPixelBufferGetBaseAddress(pxbuffer!)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
guard let context = CGContext(
data: pxdata,
width: width,
height: height,
bitsPerComponent: 8,
bytesPerRow: 4 * width,
space: rgbColorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue
) else {
fatalError()
}
context.setStrokeColor(UIColor.yellow.cgColor)
context.setLineWidth(5)
context.move(to: .init(x: 0, y: 0))
context.addLine(to: .init(x: width, y: height))
context.strokePath()
CVPixelBufferUnlockBaseAddress(pxbuffer!, CVPixelBufferLockFlags(rawValue: 0))
return pxbuffer
}
所以我偶然发现了我的问题的 "答案" 此处.
我只想说,我希望这个帖子能帮助到未来的可怜人,因为错误代码、警告、API成员和文档完全不能帮助我。