forked from whydna/Reverse-AVAsset-Efficient
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathAVAsset.swift
74 lines (60 loc) · 2.83 KB
/
AVAsset.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//
// AVAsset.swift
// Capture
//
// Created by Glen Hinkle on 2/2/16.
// Copyright © 2016 Zombie Dolphin. All rights reserved.
//
import Foundation
import AVKit
extension AVAsset {
func reversedAsset(outputURL: NSURL) -> AVAsset? {
do {
let reader = try AVAssetReader(asset: self)
guard let videoTrack = tracksWithMediaType(AVMediaTypeVideo).last else {
return .None
}
let readerOutputSettings: [String:AnyObject] = [
"\(kCVPixelBufferPixelFormatTypeKey)": Int(kCVPixelFormatType_420YpCbCr8BiPlanarFullRange)
]
let readerOutput = AVAssetReaderTrackOutput(track: videoTrack, outputSettings: readerOutputSettings)
reader.addOutput(readerOutput)
reader.startReading()
// Read in frames (CMSampleBuffer is a frame)
var samples = [CMSampleBuffer]()
while let sample = readerOutput.copyNextSampleBuffer() {
samples.append(sample)
}
// Write to AVAsset
let writer = try AVAssetWriter(URL: outputURL, fileType: AVFileTypeMPEG4)
let writerOutputSettings: [String:AnyObject] = [
AVVideoCodecKey: AVVideoCodecH264,
AVVideoWidthKey: videoTrack.naturalSize.width,
AVVideoHeightKey: videoTrack.naturalSize.height,
AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey: videoTrack.estimatedDataRate]
]
let sourceFormatHint = videoTrack.formatDescriptions.last as! CMFormatDescriptionRef
let writerInput = AVAssetWriterInput(mediaType: AVMediaTypeVideo, outputSettings: writerOutputSettings, sourceFormatHint: sourceFormatHint)
writerInput.expectsMediaDataInRealTime = false
let pixelBufferAdaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writerInput, sourcePixelBufferAttributes: .None)
writer.addInput(writerInput)
writer.startWriting()
writer.startSessionAtSourceTime(CMSampleBufferGetPresentationTimeStamp(samples[0]))
for (index, sample) in samples.enumerate() {
let presentationTime = CMSampleBufferGetPresentationTimeStamp(sample)
if let imageBufferRef = CMSampleBufferGetImageBuffer(samples[samples.count - index - 1]) {
pixelBufferAdaptor.appendPixelBuffer(imageBufferRef, withPresentationTime: presentationTime)
}
while !writerInput.readyForMoreMediaData {
NSThread.sleepForTimeInterval(0.1)
}
}
writer.finishWritingWithCompletionHandler { }
return AVAsset(URL: outputURL)
}
catch let error as NSError {
print("\(error)")
return .None
}
}
}