-
Notifications
You must be signed in to change notification settings - Fork 56
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cannot Provide Dynamic duration to each image. #24
Comments
DevAK0000001
changed the title
Cannot Provide Dynamic duration to per image.
Cannot Provide Dynamic duration to each image.
Jul 12, 2022
I think you can create extension of There are two duration:
Something like following (not tested, do not know if this works) extension MTMovieMaker {
public func createVideo(with images: [MTIImage],
effects: [MTTransition.Effect],
frameDurations: [TimeInterval] = [1],
transitionDuration: TimeInterval = 0.8,
audioURL: URL? = nil,
completion: MTMovieMakerCompletion? = nil) throws {
guard images.count >= 2 else {
throw MTMovieMakerError.imagesMustMoreThanTwo
}
guard effects.count == images.count - 1 else {
throw MTMovieMakerError.imagesAndEffectsDoesNotMatch
}
guard frameDurations.count == effects.count else {
throw MTMovieMakerError.imagesAndEffectsDoesNotMatch
}
if FileManager.default.fileExists(atPath: outputURL.path) {
try FileManager.default.removeItem(at: outputURL)
}
writer = try AVAssetWriter(outputURL: outputURL, fileType: .mp4)
let outputSize = images.first!.size
let videoSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: outputSize.width,
AVVideoHeightKey: outputSize.height
]
let writerInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)
let attributes = sourceBufferAttributes(outputSize: outputSize)
let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput,
sourcePixelBufferAttributes: attributes)
writer?.add(writerInput)
guard let success = writer?.startWriting(), success == true else {
fatalError("Can not start writing")
}
guard let pixelBufferPool = pixelBufferAdaptor.pixelBufferPool else {
fatalError("AVAssetWriterInputPixelBufferAdaptor pixelBufferPool empty")
}
self.writer?.startSession(atSourceTime: .zero)
writerInput.requestMediaDataWhenReady(on: self.writingQueue) {
var index = 0
while index < (images.count - 1) {
let frameDuration = frameDurations[index]
var presentTime = CMTimeMake(value: Int64(frameDuration * Double(index) * 1000), timescale: 1000)
let transition = effects[index].transition
transition.inputImage = images[index]
transition.destImage = images[index + 1]
transition.duration = transitionDuration
let frameBeginTime = presentTime
let frameCount = 29
for counter in 0 ... frameCount {
autoreleasepool {
while !writerInput.isReadyForMoreMediaData {
Thread.sleep(forTimeInterval: 0.01)
}
let progress = Float(counter) / Float(frameCount)
transition.progress = progress
let frameTime = CMTimeMake(value: Int64(transitionDuration * Double(progress) * 1000), timescale: 1000)
presentTime = CMTimeAdd(frameBeginTime, frameTime)
var pixelBuffer: CVPixelBuffer?
CVPixelBufferPoolCreatePixelBuffer(kCFAllocatorDefault, pixelBufferPool, &pixelBuffer)
if let buffer = pixelBuffer, let frame = transition.outputImage {
try? MTTransition.context?.render(frame, to: buffer)
pixelBufferAdaptor.append(buffer, withPresentationTime: presentTime)
}
}
}
index += 1
}
writerInput.markAsFinished()
self.writer?.finishWriting {
if let audioURL = audioURL, self.writer?.error == nil {
do {
let audioAsset = AVAsset(url: audioURL)
let videoAsset = AVAsset(url: self.outputURL)
try self.mixAudio(audioAsset, video: videoAsset, completion: completion)
} catch {
completion?(.failure(error))
}
} else {
DispatchQueue.main.async {
if let error = self.writer?.error {
completion?(.failure(error))
} else {
completion?(.success(self.outputURL))
}
}
}
}
}
}
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hi , i am using this library and its way too good but i am stuck when trying to add dynamic duration to each image in array
for example there are 6 images and adding duration to each image like [0.0,4.0,2.0,0.5,5.0,6.0].
it only works fine when i am adding static duration for all images like [2.0], then all images duration will be 2.0.
Pleas help me to provide flexible duration for each image while creating video of images.
Below is the Error:-
Error Domain=AVFoundationErrorDomain Code=-11800 "The operation could not be completed" UserInfo={NSLocalizedFailureReason=An unknown error occurred (-16364), NSLocalizedDescription=The operation could not be completed, NSUnderlyingError=0x28023c5a0 {Error Domain=NSOSStatusErrorDomain Code=-16364 ["(null)"}}``](url
)
The text was updated successfully, but these errors were encountered: