Comments (9)
Hi. You haven't told us what you're trying to do, what versions of Xcode and Swift you're using, what changes you've made to the code, or what you mean by "too fast". Please provide a clearer bug report.
from timelapsebuilder-swift.
import Foundation
import AVFoundation
import UIKit
class VideoCreator {
let photoURLs: [UIImage]
var videoWriter: AVAssetWriter?
let width: Int
let height: Int
init(photoURLs: [UIImage],width: Int, height: Int) {
self.photoURLs = photoURLs
self.width = width
self.height = height
}
func build(_ progress: @escaping ((Progress) -> Void), success: @escaping ((URL) -> Void), failure: ((NSError) -> Void)){
let inputSize = CGSize(width: width, height: height)
let outputSize = CGSize(width: width, height: height)
var error: NSError?
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let videoOutputURL = URL(fileURLWithPath: documentsPath.appendingPathComponent("AssembledVideo.mp4"))
do {
try FileManager.default.removeItem(at: videoOutputURL)
} catch {}
do {
try videoWriter = AVAssetWriter(outputURL: videoOutputURL, fileType: AVFileType.mp4)
} catch let writerError as NSError {
error = writerError
videoWriter = nil
}
if let videoWriter = videoWriter{
let videoSettings: [String:AnyObject] = [
AVVideoCodecKey: AVVideoCodecType.h264 as AnyObject,
AVVideoWidthKey: outputSize.width as AnyObject,
AVVideoHeightKey: outputSize.height as AnyObject,
]
let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
let sourceBufferAttributes = [
(kCVPixelBufferPixelFormatTypeKey as String): Int(kCVPixelFormatType_32ARGB),
(kCVPixelBufferWidthKey as String): Float(inputSize.width),
(kCVPixelBufferHeightKey as String): Float(inputSize.height)] as [String : Any]
let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(
assetWriterInput: videoWriterInput,
sourcePixelBufferAttributes: sourceBufferAttributes
)
assert(videoWriter.canAdd(videoWriterInput))
videoWriter.add(videoWriterInput)
if videoWriter.startWriting(){
videoWriter.startSession(atSourceTime: CMTime.zero)
assert(pixelBufferAdaptor.pixelBufferPool != nil)
let media_queue = DispatchQueue(label: "mediaInputQueue")
videoWriterInput.requestMediaDataWhenReady(on: media_queue) {
let fps: Int32 = 24
let frameDuration = CMTimeMake(value: 3, timescale: fps)
let currentProgress = Progress(totalUnitCount: Int64(self.photoURLs.count))
var frameCount: Int64 = 0
var remainingPhotoURLs = [UIImage](self.photoURLs)
while videoWriterInput.isReadyForMoreMediaData && !remainingPhotoURLs.isEmpty {
let nextPhotoURL = remainingPhotoURLs.remove(at: 0)
let lastFrameTime = CMTimeMake(value: frameCount, timescale: fps)
let presentationTime = frameCount == 0 ? lastFrameTime : CMTimeAdd(lastFrameTime, frameDuration)
if !self.appendPixelBufferForImageAtURL(nextPhotoURL, pixelBufferAdaptor: pixelBufferAdaptor, presentationTime: presentationTime) {
error = NSError(
domain: kErrorDomain,
code: kFailedToAppendPixelBufferError,
userInfo: ["description": "AVAssetWriterInputPixelBufferAdapter failed to append pixel buffer"]
)
break
}
frameCount += 1
currentProgress.completedUnitCount = frameCount
progress(currentProgress)
}
videoWriterInput.markAsFinished()
videoWriter.finishWriting {
if error == nil {
success(videoOutputURL)
}
self.videoWriter = nil
}
}
} else{
error = NSError(
domain: kErrorDomain,
code: kFailedToStartAssetWriterError,
userInfo: ["description": "AVAssetWriter failed to start writing"]
)
}
}
if let error = error {
failure(error)
}
}
func appendPixelBufferForImageAtURL(_ url: UIImage, pixelBufferAdaptor: AVAssetWriterInputPixelBufferAdaptor, presentationTime: CMTime) -> Bool{
var appendSucceeded = false
autoreleasepool{
let image = url
if let pixelBufferPool = pixelBufferAdaptor.pixelBufferPool {
let pixelBufferPointer = UnsafeMutablePointer<CVPixelBuffer?>.allocate(capacity: 1)
let status: CVReturn = CVPixelBufferPoolCreatePixelBuffer(
kCFAllocatorDefault,
pixelBufferPool,
pixelBufferPointer
)
if let pixelBuffer = pixelBufferPointer.pointee, status == 0 {
fillPixelBufferFromImage(image, pixelBuffer: pixelBuffer)
appendSucceeded = pixelBufferAdaptor.append(
pixelBuffer,
withPresentationTime: presentationTime
)
pixelBufferPointer.deinitialize(count: 1)
} else {
NSLog("error: Failed to allocate pixel buffer from pool")
}
pixelBufferPointer.deallocate()
}
}
return appendSucceeded
}
func fillPixelBufferFromImage(_ image: UIImage, pixelBuffer: CVPixelBuffer) {
CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer)
let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(
data: pixelData,
width: Int(image.size.width),
height: Int(image.size.height),
bitsPerComponent: 8,
bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer),
space: rgbColorSpace,
bitmapInfo: CGImageAlphaInfo.premultipliedFirst.rawValue
)
context?.draw(image.cgImage!, in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags(rawValue: 0))
}
}
from timelapsebuilder-swift.
hey there i'm using xcode 11.3 and swift v5.1. when i trying to play "AssembledVideo.mp4" file it's playing too fast. Please help me to solve this issue
from timelapsebuilder-swift.
Please answer my other questions: what changes have you made to the code, and what does "too fast" mean?
Have you tried tuning these values?
let fps: Int32 = 24
let frameDuration = CMTimeMake(value: 3, timescale: fps)
from timelapsebuilder-swift.
yes i'm change the frame duration
from timelapsebuilder-swift.
Please answer my other questions.
from timelapsebuilder-swift.
yes i tried with that value, and too fast means when video is created then i play that video that playing too fast, and the changes in code i already send to you
from timelapsebuilder-swift.
yes i tried with that value, and too fast means when video is created then i play that video that playing too fast
What I mean is that "too fast" is a subjective thing. Based on your code, I would expect each frame to take 3/24 seconds, yielding roughly 8 fps. Does that match what you're seeing? And if not, what are you expecting to see?
the changes in code i already send to you
You posted what looks like a copy of the TimeLapseBuilder class, not what you've changed. Could you please post a diff instead?
from timelapsebuilder-swift.
Closing for lack of response
from timelapsebuilder-swift.
Related Issues (8)
- TimeLapseBuilder build not running? HOT 5
- Support for PNG with Alpha channel HOT 3
- How can we append Audio too ? HOT 1
- how to set duration on picture frames? HOT 1
- Is there any simple way to loop over the image array ? HOT 1
- Video content start from left. HOT 3
- Frame time calculation is a tiny bit out of whack HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from timelapsebuilder-swift.