diff --git a/.gitignore b/.gitignore index 89c499e..420541b 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ profile *.moved-aside DerivedData .idea/ +.build +Release diff --git a/LICENSE b/LICENSE index 7ee23d3..c9da694 100644 --- a/LICENSE +++ b/LICENSE @@ -16,4 +16,3 @@ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..fae959a --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +build: + swift build + +release: clean + swift build --configuration=release --build-path ./Release + +clean: + rm -rf ./.build diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..a1e94e8 --- /dev/null +++ b/Package.swift @@ -0,0 +1,21 @@ +// swift-tools-version:5.2 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "SPMAssetExporter", + products: [ + .library( + name: "SPMAssetExporter", + targets: ["SPMAssetExporter"] + ), + ], + dependencies: [], + targets: [ + .target( + name: "SPMAssetExporter", + dependencies: [] + ), + ] +) diff --git a/README.md b/README.md index a93ff71..8c22094 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +# SPMAssetExporter + SDAVAssetExportSession ====================== @@ -8,48 +10,83 @@ You want the ease of use of `AVAssetExportSession` but default provided presets Usage Example ------------- - +For ObjC: ``` objective-c SDAVAssetExportSession *encoder = [SDAVAssetExportSession.alloc initWithAsset:anAsset]; encoder.outputFileType = AVFileTypeMPEG4; encoder.outputURL = outputFileURL; encoder.videoSettings = @ -{ + { AVVideoCodecKey: AVVideoCodecH264, AVVideoWidthKey: @1920, AVVideoHeightKey: @1080, AVVideoCompressionPropertiesKey: @ - { + { AVVideoAverageBitRateKey: @6000000, AVVideoProfileLevelKey: AVVideoProfileLevelH264High40, - }, -}; + }, + }; encoder.audioSettings = @ { - AVFormatIDKey: @(kAudioFormatMPEG4AAC), - AVNumberOfChannelsKey: @2, - AVSampleRateKey: @44100, - AVEncoderBitRateKey: @128000, + AVFormatIDKey: @(kAudioFormatMPEG4AAC), + AVNumberOfChannelsKey: @2, + AVSampleRateKey: @44100, + AVEncoderBitRateKey: @128000, }; [encoder exportAsynchronouslyWithCompletionHandler:^ { - if (encoder.status == AVAssetExportSessionStatusCompleted) - { - NSLog(@"Video export succeeded"); - } - else if (encoder.status == AVAssetExportSessionStatusCancelled) - { - NSLog(@"Video export cancelled"); - } - else - { - NSLog(@"Video export failed with error: %@ (%d)", encoder.error.localizedDescription, encoder.error.code); - } + if (encoder.status == AVAssetExportSessionStatusCompleted) + { + NSLog(@"Video export succeeded"); + } + else if (encoder.status == AVAssetExportSessionStatusCancelled) + { + NSLog(@"Video export cancelled"); + } + else + { + NSLog(@"Video export failed with error: %@ (%d)", encoder.error.localizedDescription, encoder.error.code); + } }]; ``` +And for Swift: + +* add the package to your Xcode project (https://developer.apple.com/documentation/xcode/adding_package_dependencies_to_your_app) +* import package +* use it in swift code like + +```swift +import SPMAssetExporter + +// ... + +let exporter = SDAVAssetExportSession(asset: asset)! +exporter.outputFileType = processingParameters.outputFileType.rawValue +exporter.outputURL = processingParameters.outputUrl +exporter.videoSettings = [ + AVVideoCodecKey: AVVideoCodecType.h264, + AVVideoWidthKey: targetSize.width, + AVVideoHeightKey: targetSize.height, + AVVideoCompressionPropertiesKey: [AVVideoAverageBitRateKey: 1024_000,AVVideoProfileLevelKey: AVVideoProfileLevelH264High40] +] +exporter.audioSettings = [ + AVFormatIDKey: kAudioFormatMPEG4AAC, + AVNumberOfChannelsKey: 1, + AVSampleRateKey: 44100, + AVEncoderBitRateKey: 96_000 +] +exporter.videoComposition = videoComposition + +exporter.exportAsynchronously(completionHandler: { + switch encoder.status { + // do your work here + } +}) +``` + Licenses -------- diff --git a/SDAVAssetExportSession.h b/Sources/SPMAssetExporter/include/SDAVAssetExportSession.h similarity index 100% rename from SDAVAssetExportSession.h rename to Sources/SPMAssetExporter/include/SDAVAssetExportSession.h diff --git a/SDAVAssetExportSession.m b/Sources/SPMAssetExporter/include/SDAVAssetExportSession.m similarity index 99% rename from SDAVAssetExportSession.m rename to Sources/SPMAssetExporter/include/SDAVAssetExportSession.m index e99993b..6f649fe 100755 --- a/SDAVAssetExportSession.m +++ b/Sources/SPMAssetExporter/include/SDAVAssetExportSession.m @@ -10,7 +10,6 @@ // file that was distributed with this source code. // - #import "SDAVAssetExportSession.h" @interface SDAVAssetExportSession () @@ -168,7 +167,7 @@ - (void)exportAsynchronouslyWithCompletionHandler:(void (^)(void))handler [self.writer addInput:self.audioInput]; } } - + [self.writer startWriting]; [self.reader startReading]; [self.writer startSessionAtSourceTime:self.timeRange.start]; @@ -196,7 +195,7 @@ - (void)exportAsynchronouslyWithCompletionHandler:(void (^)(void))handler else { videoCompleted = YES; } - + if (!self.audioOutput) { audioCompleted = YES; } else { @@ -232,7 +231,7 @@ - (BOOL)encodeReadySamplesFromOutput:(AVAssetReaderOutput *)output toInput:(AVAs handled = YES; error = YES; } - + if (!handled && self.videoOutput == output) { // update the video progress