react-native-compressor 1.8.15 → 1.8.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +36 -9
  2. package/android/src/main/java/com/reactnativecompressor/Audio/AudioCompressor.kt +58 -27
  3. package/android/src/main/java/com/reactnativecompressor/Audio/AudioHelper.kt +49 -0
  4. package/android/src/main/java/com/reactnativecompressor/Audio/AudioMain.kt +2 -6
  5. package/android/src/main/java/com/reactnativecompressor/Utils/createVideoThumbnail.kt +0 -2
  6. package/android/src/main/java/com/reactnativecompressor/Video/VideoMain.kt +6 -6
  7. package/ios/Audio/AudioHelper.swift +49 -0
  8. package/ios/Audio/AudioMain.swift +46 -82
  9. package/ios/Audio/AudioOptions.swift +37 -0
  10. package/ios/Audio/FormatConverter/FormatConverter+Compressed.swift +326 -0
  11. package/ios/Audio/FormatConverter/FormatConverter+PCM.swift +239 -0
  12. package/ios/Audio/FormatConverter/FormatConverter+Utilities.swift +103 -0
  13. package/ios/Audio/FormatConverter/FormatConverter.swift +264 -0
  14. package/ios/Compressor.xcodeproj/xcuserdata/apple.xcuserdatad/xcschemes/xcschememanagement.plist +14 -0
  15. package/ios/Video/NextLevelSessionExporter.swift +694 -0
  16. package/ios/Video/VideoMain.swift +9 -8
  17. package/lib/commonjs/Audio/index.js +1 -3
  18. package/lib/commonjs/Audio/index.js.map +1 -1
  19. package/lib/commonjs/utils/index.js +0 -2
  20. package/lib/commonjs/utils/index.js.map +1 -1
  21. package/lib/module/Audio/index.js +1 -3
  22. package/lib/module/Audio/index.js.map +1 -1
  23. package/lib/module/utils/index.js +0 -3
  24. package/lib/module/utils/index.js.map +1 -1
  25. package/lib/typescript/Audio/index.d.ts.map +1 -1
  26. package/lib/typescript/index.d.ts +7 -1
  27. package/lib/typescript/index.d.ts.map +1 -1
  28. package/lib/typescript/utils/index.d.ts +11 -2
  29. package/lib/typescript/utils/index.d.ts.map +1 -1
  30. package/package.json +1 -1
  31. package/react-native-compressor.podspec +0 -1
  32. package/src/Audio/index.tsx +1 -3
  33. package/src/utils/index.tsx +12 -3
@@ -0,0 +1,264 @@
1
+ // Copyright AudioKit. All Rights Reserved. Revision History at http://github.com/AudioKit/AudioKit/
2
+
3
+ import AVFoundation
4
+
5
+ /**
6
+ FormatConverter wraps the more complex AVFoundation and CoreAudio audio conversions in an easy to use format.
7
+ ```swift
8
+ let options = FormatConverter.Options()
9
+
10
+ // any options left nil will adopt the value of the input file
11
+ options.format = "wav"
12
+ options.sampleRate = 48000
13
+ options.bitDepth = 24
14
+
15
+ let converter = FormatConverter(inputURL: oldURL, outputURL: newURL, options: options)
16
+
17
+ converter.start { error in
18
+ // the error will be nil on success
19
+ }
20
+ ```
21
+ */
22
+ public class FormatConverter {
23
+ // MARK: - properties
24
+
25
+ /// The source audio file
26
+ public var inputURL: URL?
27
+
28
+ /// The audio file to be created after conversion
29
+ public var outputURL: URL?
30
+
31
+ /// Options for conversion
32
+ public var options: Options?
33
+
34
+ // MARK: - private properties
35
+
36
+ // The reader needs to exist outside the start func otherwise the async nature of the
37
+ // AVAssetWriterInput will lose its reference
38
+ var reader: AVAssetReader?
39
+ var writer: AVAssetWriter?
40
+
41
+ // MARK: - initialization
42
+
43
+ /// init with input, output and options - then start()
44
+ public init(inputURL: URL,
45
+ outputURL: URL,
46
+ options: Options? = nil)
47
+ {
48
+ self.inputURL = inputURL
49
+ self.outputURL = outputURL
50
+ self.options = options ?? Options()
51
+ }
52
+
53
+ deinit {
54
+ reader = nil
55
+ writer = nil
56
+ inputURL = nil
57
+ outputURL = nil
58
+ options = nil
59
+ }
60
+
61
+ // MARK: - functions
62
+
63
+ /// The entry point for file conversion
64
+ /// - Parameter completionHandler: the callback that will be triggered when process has completed.
65
+ public func start(completionHandler: FormatConverterCallback? = nil) {
66
+ guard let inputURL = inputURL else {
67
+ completionHandler?(Self.createError(message: "Input file can't be nil."))
68
+ return
69
+ }
70
+
71
+ guard let outputURL = outputURL else {
72
+ completionHandler?(Self.createError(message: "Output file can't be nil."))
73
+ return
74
+ }
75
+
76
+ let inputFormat = AudioFileFormat(rawValue: inputURL.pathExtension.lowercased()) ?? .unknown
77
+ // verify inputFormat, only allow files with path extensions for speed?
78
+ guard FormatConverter.inputFormats.contains(inputFormat) else {
79
+ completionHandler?(Self.createError(message: "The input file format is in an incompatible format: \(inputFormat)"))
80
+ return
81
+ }
82
+
83
+ if FileManager.default.fileExists(atPath: outputURL.path) {
84
+ if options?.eraseFile == true {
85
+ print("Warning: removing existing file at", outputURL.path)
86
+ try? FileManager.default.removeItem(at: outputURL)
87
+ } else {
88
+ let message = "The output file exists already. You need to choose a unique URL or delete the file."
89
+ completionHandler?(Self.createError(message: message))
90
+ return
91
+ }
92
+ }
93
+
94
+ if options?.format == nil {
95
+ options?.format = AudioFileFormat(rawValue: outputURL.pathExtension.lowercased()) ?? .unknown
96
+ }
97
+
98
+ // Format checks are necessary as AVAssetReader has opinions about compressed
99
+
100
+ // PCM output, any supported input
101
+ if Self.isPCM(url: outputURL) == true {
102
+ // PCM output
103
+ convertToPCM(completionHandler: completionHandler)
104
+
105
+ // PCM input, compressed output
106
+ } else if Self.isPCM(url: inputURL) == true,
107
+ Self.isCompressed(url: outputURL) == true
108
+ {
109
+ convertPCMToCompressed(completionHandler: completionHandler)
110
+
111
+ // Compressed input and output, won't do sample rate
112
+ } else if Self.isCompressed(url: inputURL) == true,
113
+ Self.isCompressed(url: outputURL) == true
114
+ {
115
+ convertCompressed(completionHandler: completionHandler)
116
+
117
+ } else {
118
+ completionHandler?(Self.createError(message: "Unable to determine formats for conversion"))
119
+ }
120
+ }
121
+ }
122
+
123
+ // MARK: - Definitions
124
+
125
+ public enum AudioFileFormat: String {
126
+ case aac
127
+ case aif
128
+ case aifc
129
+ case aiff
130
+ case au
131
+ case caf
132
+ case m4a
133
+ case m4v
134
+ case mov
135
+ case mp3
136
+ case mp4
137
+ case sd2
138
+ case snd
139
+ case ts
140
+ case unknown
141
+ case wav
142
+ }
143
+
144
+ public extension FormatConverter {
145
+
146
+ /// FormatConverterCallback is the callback format for start()
147
+ /// - Parameter: error This will contain one parameter of type Error which is nil if the conversion was successful.
148
+ typealias FormatConverterCallback = (_ error: Error?) -> Void
149
+
150
+ /// Formats that this class can write
151
+ static let outputFormats: [AudioFileFormat] = [.wav, .aif, .caf, .m4a]
152
+
153
+ static let defaultOutputFormat: AudioFileFormat = .wav
154
+
155
+ /// Formats that this class can read
156
+ static let inputFormats: [AudioFileFormat] = FormatConverter.outputFormats + [
157
+ .mp3, .snd, .au, .sd2,
158
+ .aif, .aiff, .aifc, .aac,
159
+ .mp4, .m4v, .mov, .ts,
160
+ .unknown, // allow files with no extension. convertToPCM can still read the type
161
+ ]
162
+
163
+ /// An option to block upsampling to a higher bit depth than the source.
164
+ /// For example, converting to 24bit from 16 doesn't have much benefit
165
+ enum BitDepthRule {
166
+ /// Don't allow upsampling to 24bit if the src is 16
167
+ case lessThanOrEqual
168
+
169
+ /// allow any conversaion
170
+ case any
171
+ }
172
+
173
+ /// The conversion options, leave any property nil to adopt the value of the input file
174
+ /// bitRate assumes a stereo bit rate and the converter will half it for mono
175
+ struct Options {
176
+ /// Audio Format
177
+ public var format: AudioFileFormat?
178
+ /// Sample Rate in Hertz
179
+ public var sampleRate: Double?
180
+ /// used only with PCM data
181
+ public var bitDepth: UInt32?
182
+ /// used only when outputting compressed audio
183
+ public var bitRate: UInt32 = 128000 {
184
+ didSet {
185
+ bitRate = bitRate.clamped(to: 64000 ... 320000)
186
+ }
187
+ }
188
+
189
+ /// An option to block upsampling to a higher bit depth than the source.
190
+ /// default value is `.lessThanOrEqual`
191
+ public var bitDepthRule: BitDepthRule = .lessThanOrEqual
192
+
193
+ /// How many channels to convert to. Typically 1 or 2
194
+ public var channels: UInt32?
195
+
196
+ /// Maps to PCM Conversion format option `AVLinearPCMIsNonInterleaved`
197
+ public var isInterleaved: Bool?
198
+
199
+ /// Overwrite existing files, set false if you want to handle this before you call start()
200
+ public var eraseFile: Bool = true
201
+
202
+ public init() {}
203
+
204
+ /// Create options by parsing the contents of the url and using the audio settings
205
+ /// in the file
206
+ /// - Parameter url: The audio file to open and parse
207
+ public init?(url: URL) {
208
+ guard let avFile = try? AVAudioFile(forReading: url) else { return nil }
209
+ self.init(audioFile: avFile)
210
+ }
211
+
212
+ /// Create options by parsing the audioFile for its settings
213
+ /// - Parameter audioFile: an AVAudioFile to parse
214
+ public init?(audioFile: AVAudioFile) {
215
+ let streamDescription = audioFile.fileFormat.streamDescription.pointee
216
+
217
+ format = AudioFileFormat(rawValue: audioFile.url.pathExtension) ?? .unknown
218
+ // FormatConverter.formatIDToString(streamDescription.mFormatID)
219
+ sampleRate = streamDescription.mSampleRate
220
+ bitDepth = streamDescription.mBitsPerChannel
221
+ channels = streamDescription.mChannelsPerFrame
222
+ }
223
+
224
+ /// Create PCM Options
225
+ /// - Parameters:
226
+ /// - pcmFormat: wav, aif, or caf
227
+ /// - sampleRate: Sample Rate
228
+ /// - bitDepth: Bit Depth, or bits per channel
229
+ /// - channels: How many channels
230
+ public init?(pcmFormat: AudioFileFormat,
231
+ sampleRate: Double? = nil,
232
+ bitDepth: UInt32? = nil,
233
+ channels: UInt32? = nil)
234
+ {
235
+ format = pcmFormat
236
+ self.sampleRate = sampleRate
237
+ self.bitDepth = bitDepth
238
+ self.channels = channels
239
+ }
240
+ }
241
+
242
+ internal func completionProxy(error: Error?,
243
+ deleteOutputOnError: Bool = true,
244
+ completionHandler: FormatConverterCallback? = nil)
245
+ {
246
+ guard error != nil,
247
+ deleteOutputOnError,
248
+ let outputURL = outputURL,
249
+ FileManager.default.fileExists(atPath: outputURL.path)
250
+ else {
251
+ completionHandler?(error)
252
+ return
253
+ }
254
+
255
+ do {
256
+ print("Deleting on error", outputURL.path)
257
+ try FileManager.default.removeItem(at: outputURL)
258
+ } catch let err as NSError {
259
+ print("Failed to remove file", outputURL, err)
260
+ }
261
+
262
+ completionHandler?(error)
263
+ }
264
+ }
@@ -0,0 +1,14 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>SchemeUserState</key>
6
+ <dict>
7
+ <key>Compressor.xcscheme_^#shared#^_</key>
8
+ <dict>
9
+ <key>orderHint</key>
10
+ <integer>56</integer>
11
+ </dict>
12
+ </dict>
13
+ </dict>
14
+ </plist>