Requirement :
It sounds like litte different but this is what I want to achieve. I want to make movie (.mov) file in reverse. Just like how we rewind the movie file. I also want maintain same frame rate as my video is containing.
NOTE: I do not just want to play video file in reverse order. I want to generate new movie file playing in reverse order.
My Exploration :
I thought of below steps to perform to do the same.
AVAssetExportSession
AVMutableComposition
and AVAssetExportSession
. Using above steps , I am able to achieve resulting video file in reverse but I am having below concerns.
Does anybody is having any other optimized way to achieve this? Any suggestion will be appreciated.
Here is my solution , maybe it can help you. https://github.com/KayWong/VideoReverse
Swift 5, credit to Andy Hin as I based this on http://www.andyhin.com/post/5/reverse-video-avfoundation
class func reverseVideo(inURL: URL, outURL: URL, queue: DispatchQueue, _ completionBlock: ((Bool)->Void)?) {
let asset = AVAsset.init(url: inURL)
guard
let reader = try? AVAssetReader.init(asset: asset),
let videoTrack = asset.tracks(withMediaType: .video).first
else {
assert(false)
completionBlock?(false)
return
}
let width = videoTrack.naturalSize.width
let height = videoTrack.naturalSize.height
let readerSettings: [String : Any] = [
String(kCVPixelBufferPixelFormatTypeKey) : kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange,
]
let readerOutput = AVAssetReaderTrackOutput.init(track: videoTrack, outputSettings: readerSettings)
reader.add(readerOutput)
reader.startReading()
var buffers = [CMSampleBuffer]()
while let nextBuffer = readerOutput.copyNextSampleBuffer() {
buffers.append(nextBuffer)
}
let status = reader.status
reader.cancelReading()
guard status == .completed, let firstBuffer = buffers.first else {
assert(false)
completionBlock?(false)
return
}
let sessionStartTime = CMSampleBufferGetPresentationTimeStamp(firstBuffer)
let writerSettings: [String:Any] = [
AVVideoCodecKey : AVVideoCodecType.h264,
AVVideoWidthKey : width,
AVVideoHeightKey: height,
]
let writerInput: AVAssetWriterInput
if let formatDescription = videoTrack.formatDescriptions.last {
writerInput = AVAssetWriterInput.init(mediaType: .video, outputSettings: writerSettings, sourceFormatHint: (formatDescription as! CMFormatDescription))
} else {
writerInput = AVAssetWriterInput.init(mediaType: .video, outputSettings: writerSettings)
}
writerInput.transform = videoTrack.preferredTransform
writerInput.expectsMediaDataInRealTime = false
guard
let writer = try? AVAssetWriter.init(url: outURL, fileType: .mp4),
writer.canAdd(writerInput)
else {
assert(false)
completionBlock?(false)
return
}
let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor.init(assetWriterInput: writerInput, sourcePixelBufferAttributes: nil)
let group = DispatchGroup.init()
group.enter()
writer.add(writerInput)
writer.startWriting()
writer.startSession(atSourceTime: sessionStartTime)
var currentSample = 0
writerInput.requestMediaDataWhenReady(on: queue) {
for i in currentSample..<buffers.count {
currentSample = i
if !writerInput.isReadyForMoreMediaData {
return
}
let presentationTime = CMSampleBufferGetPresentationTimeStamp(buffers[i])
guard let imageBuffer = CMSampleBufferGetImageBuffer(buffers[buffers.count - i - 1]) else {
WLog("VideoWriter reverseVideo: warning, could not get imageBuffer from SampleBuffer...")
continue
}
if !pixelBufferAdaptor.append(imageBuffer, withPresentationTime: presentationTime) {
WLog("VideoWriter reverseVideo: warning, could not append imageBuffer...")
}
}
// finish
writerInput.markAsFinished()
group.leave()
}
group.notify(queue: queue) {
writer.finishWriting {
if writer.status != .completed {
WLog("VideoWriter reverseVideo: error - \(String(describing: writer.error))")
completionBlock?(false)
} else {
completionBlock?(true)
}
}
}
}
you need to refer AVFoundation library to achieve your task..
i have done only 30 seconds video edit with AVAssetExportSession
& AVMutableComposition
.
this is the link which you need to refer and its very help full.
http://www.subfurther.com/blog/category/avfoundation/
And also if you wants to refer WWDC conference PDF for Editing Media it would be better.
this link total source : https://developer.apple.com/videos/wwdc/2010/ And this link covers Editing Media With AVFoundation
About memory cycles.. it also consumes more memory while Exporting.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.