@@ -16,41 +16,19 @@ import UIKit
1616 errorHandler: @escaping ( String ) -> ( )
1717 ) {
1818 let avAsset = AVURLAsset ( url: srcFile, options: nil )
19- let start = CMTimeMakeWithSeconds ( Float64 ( trimSettings. getStartsAt ( ) ) , preferredTimescale: 1 )
20- let end = trimSettings. getEndsAt ( ) > 0
21- ? CMTimeMakeWithSeconds ( Float64 ( trimSettings. getEndsAt ( ) ) , preferredTimescale: 1 )
22- : avAsset. duration
23- let duration = min ( ( end - start) , ( avAsset. duration - start) )
24- let range = CMTimeRangeMake ( start: start, duration: duration)
25-
2619 let videoTrack = avAsset. tracks ( withMediaType: AVMediaType . video) . first!
2720 let mediaSize = videoTrack. naturalSize
2821
29- var videoWidth = videoTrack. naturalSize. width
30- var videoHeight = videoTrack. naturalSize. height
31-
32- // Desired size
33- let outWidth = transcodeSettings. getWidth ( ) != 0 ? CGFloat ( transcodeSettings. getWidth ( ) ) : videoWidth
34- let outHeight = transcodeSettings. getHeight ( ) != 0 ? CGFloat ( transcodeSettings. getHeight ( ) ) : videoHeight
35-
36- // Final size
37- var newWidth = outWidth
38- var newHeight = outHeight
39-
40- var aspectRatio = videoWidth / videoHeight;
22+ // Resolution
23+ let targetVideoSize : CGSize = calculateTargetVideoSize ( sourceVideoSize: mediaSize, transcodeSettings: transcodeSettings) ;
4124
42- // for some portrait videos ios gives the wrong width and height, this fixes that
43- let videoOrientation = self . getOrientationForTrack ( avAsset: avAsset)
44- if ( videoOrientation == " portrait " ) {
45- if ( videoWidth > videoHeight) {
46- videoWidth = mediaSize. height;
47- videoHeight = mediaSize. width;
48- aspectRatio = videoWidth / videoHeight;
49- }
50- }
51-
52- newWidth = ( outWidth != 0 && outHeight != 0 ) ? outHeight * aspectRatio : videoWidth;
53- newHeight = ( outWidth != 0 && outHeight != 0 ) ? newWidth / aspectRatio : videoHeight;
25+ // Trim
26+ let start = CMTimeMakeWithSeconds ( Float64 ( trimSettings. getStartsAt ( ) * 1000 ) , preferredTimescale: 1 )
27+ let end = trimSettings. getEndsAt ( ) > 0
28+ ? CMTimeMakeWithSeconds ( Float64 ( trimSettings. getEndsAt ( ) * 1000 ) , preferredTimescale: 1 )
29+ : avAsset. duration
30+ let duration = min ( ( end - start) , ( avAsset. duration - start) )
31+ let range = CMTimeRangeMake ( start: start, duration: duration)
5432
5533 // Exporter
5634 let exporter = SimpleSessionExporter ( withAsset: avAsset)
@@ -59,12 +37,12 @@ import UIKit
5937 exporter. timeRange = range
6038
6139 exporter. videoOutputConfiguration = [
62- AVVideoWidthKey: NSNumber ( integerLiteral: Int ( newWidth ) ) ,
63- AVVideoHeightKey: NSNumber ( integerLiteral: Int ( newHeight ) ) ,
40+ AVVideoWidthKey: NSNumber ( integerLiteral: Int ( targetVideoSize . width ) ) ,
41+ AVVideoHeightKey: NSNumber ( integerLiteral: Int ( targetVideoSize . height ) ) ,
6442 ]
6543
6644 exporter. export (
67- completionHandler: { status in
45+ completionHandler: { status in
6846 switch status {
6947 case . completed:
7048 completionHandler ( exporter. outputURL!)
@@ -155,4 +133,63 @@ import UIKit
155133
156134 return " portrait " ;
157135 }
136+
137+ func calculateTargetVideoSize( sourceVideoSize: CGSize , transcodeSettings: TranscodeSettings ) -> CGSize {
138+ if ( transcodeSettings. isKeepAspectRatio ( ) ) {
139+ let mostSize = transcodeSettings. getWidth ( ) == 0 && transcodeSettings. getHeight ( ) == 0
140+ ? 1280
141+ : max ( transcodeSettings. getWidth ( ) , transcodeSettings. getHeight ( ) ) ;
142+
143+ return calculateVideoSizeAtMost ( sourceVideoSize: sourceVideoSize, mostSize: mostSize) ;
144+ } else {
145+ if ( transcodeSettings. getWidth ( ) > 0 && transcodeSettings. getHeight ( ) > 0 ) {
146+ return CGSize (
147+ width: transcodeSettings. getWidth ( ) ,
148+ height: transcodeSettings. getHeight ( )
149+ ) ;
150+ } else {
151+ return calculateVideoSizeAtMost ( sourceVideoSize: sourceVideoSize, mostSize: 720 ) ;
152+ }
153+ }
154+ }
155+
156+ func calculateVideoSizeAtMost( sourceVideoSize: CGSize , mostSize: Int ) -> CGSize {
157+ let sourceMajor = Int ( max ( sourceVideoSize. width, sourceVideoSize. height) ) ;
158+
159+ if ( sourceMajor <= mostSize) {
160+ // No resize needed
161+ return CGSize (
162+ width: sourceVideoSize. width,
163+ height: sourceVideoSize. height
164+ ) ;
165+ }
166+
167+ var outWidth : Int ;
168+ var outHeight : Int ;
169+ if ( sourceVideoSize. width >= sourceVideoSize. height) {
170+ // Landscape
171+ let inputRatio : Float = Float ( sourceVideoSize. height) / Float( sourceVideoSize. width) ;
172+
173+ outWidth = mostSize;
174+ outHeight = Int ( Float ( mostSize) * inputRatio) ;
175+ } else {
176+ // Portrait
177+ let inputRatio : Float = Float ( sourceVideoSize. width) / Float( sourceVideoSize. width) ;
178+
179+ outHeight = mostSize;
180+ outWidth = Int ( Float ( mostSize) * inputRatio) ;
181+ }
182+
183+ if ( outWidth % 2 != 0 ) {
184+ outWidth -= 1 ;
185+ }
186+ if ( outHeight % 2 != 0 ) {
187+ outHeight -= 1 ;
188+ }
189+
190+ return CGSize (
191+ width: outWidth,
192+ height: outHeight
193+ ) ;
194+ }
158195}
0 commit comments