swift - 在 Swift 中降低视频的帧率以获得 GIF 的感觉
问题描述
我一直在尝试将视频的帧速率降低到每秒 10 或 15 帧。4/5 年前有一些与 OBJC 相关的问题。我在swift中找不到任何东西..
这就是我在 Playground 上的工作:
import Cocoa
import AVKit
var assetWriter:AVAssetWriter?
var assetReader:AVAssetReader?
let bitrate:NSNumber = NSNumber(value:8000000)
func compressFile(urlToCompress: URL, outputURL: URL, completion:@escaping (URL)->Void){
var videoFinished = false
let asset = AVAsset(url: urlToCompress);
do{
assetReader = try AVAssetReader(asset: asset)
} catch{
assetReader = nil
}
guard let reader = assetReader else{
fatalError("Could not initalize asset reader probably failed its try catch")
}
let videoTrack = asset.tracks(withMediaType: AVMediaType.video).first!
let videoReaderSettings: [String:Any] = [(kCVPixelBufferPixelFormatTypeKey as String?)!:kCVPixelFormatType_32ARGB ]
let videoSettings:[String:Any] = [
AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey:bitrate],
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoHeightKey: videoTrack.naturalSize.height,
AVVideoWidthKey: videoTrack.naturalSize.width
]
let assetReaderVideoOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: videoReaderSettings)
if reader.canAdd(assetReaderVideoOutput){
reader.add(assetReaderVideoOutput)
}else{
fatalError("Couldn't add video output reader")
}
let videoInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
videoInput.transform = videoTrack.preferredTransform
let videoInputQueue = DispatchQueue(label: "videoQueue")
do{
assetWriter = try AVAssetWriter(outputURL: outputURL, fileType: AVFileType.mov)
assetWriter?.movieTimeScale = 1
}catch{
assetWriter = nil
}
guard let writer = assetWriter else{
fatalError("assetWriter was nil")
}
writer.shouldOptimizeForNetworkUse = true
writer.add(videoInput)
writer.startWriting()
reader.startReading()
writer.startSession(atSourceTime: CMTime.zero)
let closeWriter:()->Void = {
// if (audioFinished && videoFinished){
if (videoFinished){
assetWriter?.finishWriting(completionHandler: {
checkFileSize(sizeUrl: (assetWriter?.outputURL)!, message: "The file size of the compressed file is: ")
completion((assetWriter?.outputURL)!)
})
assetReader?.cancelReading()
}
}
videoInput.requestMediaDataWhenReady(on: videoInputQueue) {
while(videoInput.isReadyForMoreMediaData){
let sample = assetReaderVideoOutput.copyNextSampleBuffer()
if (sample != nil){
videoInput.append(sample!)
}else{
videoInput.markAsFinished()
DispatchQueue.main.async {
videoFinished = true
closeWriter()
}
break;
}
}
}
}
func checkFileSize(sizeUrl: URL, message:String){
let data = NSData(contentsOf: sizeUrl)!
print(message, (Double(data.length) / 1048576.0), " mb")
}
compressFile(urlToCompress: URL(fileURLWithPath: "/Users/koraybirand/Desktop/video.mp4"), outputURL: URL(fileURLWithPath: "/Users/koraybirand/Desktop/video5.mp4")) { (URL) in
}
解决方案
尝试添加AVVideoAverageNonDroppableFrameRateKey
视频设置
推荐阅读
- hive - 将 2 个计数合并为联合表中 hive sql 中的总和
- java - 从 Artifactory 下载文件的 Java 代码不起作用
- angular - 运行 ng serve 时出现 Angular 6 错误 - 发出值而不是错误实例
- testing - 如何在 Flutter 中测试时找到 Widget 的 `text` 属性?
- python - 为什么for会创建一个无限循环?
- node.js - 尽管 git push 成功,Herokuapp 启动失败,页面打开时显示以下标题:错误并在 HTML 中显示“未找到”
- ios - “未能在与其创建相同的运行循环上解除分配 CLLocationManager 可能会导致崩溃”
- ios - UIVIew 上的阴影
- c# - Visual Studio 2017 从专业版升级到企业版后,ASP.NET 应用程序的 /langversion 选项“7.2”无效
- xcode - Xcode 5 安装?