@capgo/native-audio 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/CapgoNativeAudio.podspec +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +394 -0
  4. package/android/build.gradle +55 -0
  5. package/android/src/main/AndroidManifest.xml +5 -0
  6. package/android/src/main/java/ee/forgr/audio/AudioAsset.java +140 -0
  7. package/android/src/main/java/ee/forgr/audio/AudioDispatcher.java +178 -0
  8. package/android/src/main/java/ee/forgr/audio/Constant.java +18 -0
  9. package/android/src/main/java/ee/forgr/audio/NativeAudio.java +471 -0
  10. package/android/src/main/res/layout/bridge_layout_main.xml +15 -0
  11. package/android/src/main/res/values/colors.xml +3 -0
  12. package/android/src/main/res/values/strings.xml +3 -0
  13. package/android/src/main/res/values/styles.xml +3 -0
  14. package/dist/docs.json +279 -0
  15. package/dist/esm/audio-asset.d.ts +4 -0
  16. package/dist/esm/audio-asset.js +6 -0
  17. package/dist/esm/audio-asset.js.map +1 -0
  18. package/dist/esm/definitions.d.ts +53 -0
  19. package/dist/esm/definitions.js +2 -0
  20. package/dist/esm/definitions.js.map +1 -0
  21. package/dist/esm/index.d.ts +4 -0
  22. package/dist/esm/index.js +7 -0
  23. package/dist/esm/index.js.map +1 -0
  24. package/dist/esm/web.d.ts +52 -0
  25. package/dist/esm/web.js +113 -0
  26. package/dist/esm/web.js.map +1 -0
  27. package/dist/plugin.cjs.js +134 -0
  28. package/dist/plugin.cjs.js.map +1 -0
  29. package/dist/plugin.js +137 -0
  30. package/dist/plugin.js.map +1 -0
  31. package/ios/Plugin/AudioAsset.swift +184 -0
  32. package/ios/Plugin/Constant.swift +20 -0
  33. package/ios/Plugin/Info.plist +24 -0
  34. package/ios/Plugin/Plugin.h +10 -0
  35. package/ios/Plugin/Plugin.m +19 -0
  36. package/ios/Plugin/Plugin.swift +276 -0
  37. package/package.json +91 -0
@@ -0,0 +1,276 @@
1
+ import AVFoundation
2
+ import Foundation
3
+ import Capacitor
4
+ import CoreAudio
5
+
6
+ enum MyError: Error {
7
+ case runtimeError(String)
8
+ }
9
+
10
+ /**
11
+ * Please read the Capacitor iOS Plugin Development Guide
12
+ * here: https://capacitor.ionicframework.com/docs/plugins/ios
13
+ */
14
+ @objc(NativeAudio)
15
+ public class NativeAudio: CAPPlugin {
16
+
17
+ var audioList: [String : Any] = [:]
18
+ var fadeMusic = false
19
+ var session = AVAudioSession.sharedInstance()
20
+
21
+ public override func load() {
22
+ super.load()
23
+
24
+ self.fadeMusic = false
25
+
26
+ do {
27
+ try self.session.setCategory(AVAudioSession.Category.playback)
28
+ try self.session.setActive(false)
29
+ } catch {
30
+ print("Failed to set session category")
31
+ }
32
+ }
33
+
34
+ @objc func configure(_ call: CAPPluginCall) {
35
+ if let fade = call.getBool(Constant.FadeKey) {
36
+ self.fadeMusic = fade
37
+ }
38
+ if let focus = call.getBool(Constant.FocusAudio) {
39
+ do {
40
+ if focus {
41
+ try self.session.setCategory(AVAudioSession.Category.playback)
42
+ } else {
43
+ try self.session.setCategory(AVAudioSession.Category.ambient)
44
+ }
45
+ } catch {
46
+ print("Failed to set setCategory audio")
47
+ }
48
+ }
49
+ }
50
+
51
+ @objc func preload(_ call: CAPPluginCall) {
52
+ preloadAsset(call, isComplex: true)
53
+ }
54
+
55
+ @objc func play(_ call: CAPPluginCall) {
56
+ let audioId = call.getString(Constant.AssetIdKey) ?? ""
57
+ let time = call.getDouble("time") ?? 0
58
+ if audioId != "" {
59
+ let queue = DispatchQueue(label: "ee.forgr.audio.complex.queue", qos: .userInitiated)
60
+
61
+ queue.async {
62
+ if self.audioList.count > 0 {
63
+ let asset = self.audioList[audioId]
64
+
65
+ if asset != nil {
66
+ if asset is AudioAsset {
67
+ let audioAsset = asset as? AudioAsset
68
+
69
+ if self.fadeMusic {
70
+ audioAsset?.playWithFade(time: time)
71
+ } else {
72
+ audioAsset?.play(time: time)
73
+ }
74
+ call.resolve()
75
+ } else if (asset is Int32) {
76
+ let audioAsset = asset as? NSNumber ?? 0
77
+ AudioServicesPlaySystemSound(SystemSoundID(audioAsset.intValue ))
78
+ call.resolve()
79
+ } else {
80
+ call.reject(Constant.ErrorAssetNotFound)
81
+ }
82
+ }
83
+ }
84
+ }
85
+ }
86
+ }
87
+
88
+ @objc private func getAudioAsset(_ call: CAPPluginCall) -> AudioAsset? {
89
+ let audioId = call.getString(Constant.AssetIdKey) ?? ""
90
+ if audioId == "" {
91
+ call.reject(Constant.ErrorAssetId)
92
+ return nil
93
+ }
94
+ if self.audioList.count > 0 {
95
+ let asset = self.audioList[audioId]
96
+ if asset != nil && asset is AudioAsset {
97
+ return asset as? AudioAsset
98
+ }
99
+ }
100
+ call.reject(Constant.ErrorAssetNotFound + " - " + audioId)
101
+ return nil
102
+ }
103
+
104
+
105
+ @objc func getDuration(_ call: CAPPluginCall) {
106
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
107
+ return
108
+ }
109
+
110
+ call.resolve([
111
+ "duration": audioAsset.getDuration()
112
+ ])
113
+ }
114
+
115
+ @objc func getCurrentTime(_ call: CAPPluginCall) {
116
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
117
+ return
118
+ }
119
+
120
+ call.resolve([
121
+ "currentTime": audioAsset.getCurrentTime()
122
+ ])
123
+ }
124
+
125
+ @objc func resume(_ call: CAPPluginCall) {
126
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
127
+ return
128
+ }
129
+
130
+ audioAsset.resume()
131
+ call.resolve()
132
+ }
133
+
134
+ @objc func pause(_ call: CAPPluginCall) {
135
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
136
+ return
137
+ }
138
+
139
+ audioAsset.pause()
140
+ call.resolve()
141
+ }
142
+
143
+ @objc func stop(_ call: CAPPluginCall) {
144
+ let audioId = call.getString(Constant.AssetIdKey) ?? ""
145
+
146
+ do {
147
+ try stopAudio(audioId: audioId)
148
+ } catch {
149
+ call.reject(Constant.ErrorAssetNotFound)
150
+ }
151
+ }
152
+
153
+ @objc func loop(_ call: CAPPluginCall) {
154
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
155
+ return
156
+ }
157
+
158
+ audioAsset.loop()
159
+ call.resolve()
160
+ }
161
+
162
+ @objc func unload(_ call: CAPPluginCall) {
163
+ let audioId = call.getString(Constant.AssetIdKey) ?? ""
164
+ if self.audioList.count > 0 {
165
+ let asset = self.audioList[audioId]
166
+ if asset != nil && asset is AudioAsset {
167
+ let audioAsset = asset as! AudioAsset
168
+ audioAsset.unload();
169
+ self.audioList[audioId] = nil
170
+ }
171
+ }
172
+ call.resolve()
173
+ }
174
+
175
+ @objc func setVolume(_ call: CAPPluginCall) {
176
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
177
+ return
178
+ }
179
+
180
+ let volume = call.getFloat(Constant.Volume) ?? 1.0
181
+
182
+ audioAsset.setVolume(volume: volume as NSNumber)
183
+ call.resolve()
184
+ }
185
+
186
+ @objc func isPlaying(_ call: CAPPluginCall) {
187
+ guard let audioAsset: AudioAsset = self.getAudioAsset(call) else {
188
+ return
189
+ }
190
+
191
+ call.resolve([
192
+ "isPlaying": audioAsset.isPlaying()
193
+ ])
194
+ }
195
+
196
+ private func preloadAsset(_ call: CAPPluginCall, isComplex complex: Bool) {
197
+ let audioId = call.getString(Constant.AssetIdKey) ?? ""
198
+ let channels: NSNumber?
199
+ let volume: Float?
200
+ let delay: NSNumber?
201
+ let isUrl: Bool?
202
+
203
+ if audioId != "" {
204
+ let assetPath: String = call.getString(Constant.AssetPathKey) ?? ""
205
+
206
+ if (complex) {
207
+ volume = call.getFloat("volume") ?? 1.0
208
+ channels = NSNumber(value: call.getInt("channels") ?? 1)
209
+ delay = NSNumber(value: call.getInt("delay") ?? 1)
210
+ isUrl = call.getBool("isUrl") ?? false
211
+ } else {
212
+ channels = 0
213
+ volume = 0
214
+ delay = 0
215
+ isUrl = false
216
+ }
217
+
218
+ if audioList.isEmpty {
219
+ audioList = [:]
220
+ }
221
+
222
+ let asset = audioList[audioId]
223
+ let queue = DispatchQueue(label: "ee.forgr.audio.simple.queue", qos: .userInitiated)
224
+
225
+ queue.async {
226
+ if asset == nil {
227
+ var basePath: String?
228
+ if isUrl == false {
229
+ let assetPathSplit = assetPath.components(separatedBy: ".")
230
+ basePath = Bundle.main.path(forResource: assetPathSplit[0], ofType: assetPathSplit[1])
231
+ } else {
232
+ let url = URL(string: assetPath)
233
+ basePath = url!.path
234
+ }
235
+
236
+ if FileManager.default.fileExists(atPath: basePath ?? "") {
237
+ if !complex {
238
+ let pathUrl = URL(fileURLWithPath: basePath ?? "")
239
+ let soundFileUrl: CFURL = CFBridgingRetain(pathUrl) as! CFURL
240
+ var soundId = SystemSoundID()
241
+ AudioServicesCreateSystemSoundID(soundFileUrl, &soundId)
242
+ self.audioList[audioId] = NSNumber(value: Int32(soundId))
243
+ call.resolve()
244
+ } else {
245
+ let audioAsset: AudioAsset = AudioAsset(owner: self, withAssetId: audioId, withPath: basePath, withChannels: channels, withVolume: volume as NSNumber?, withFadeDelay: delay)
246
+ self.audioList[audioId] = audioAsset
247
+ call.resolve()
248
+ }
249
+ } else {
250
+ call.reject(Constant.ErrorAssetPath + " - " + assetPath)
251
+ }
252
+ }
253
+ }
254
+ }
255
+ }
256
+
257
+ private func stopAudio(audioId: String) throws {
258
+ if self.audioList.count > 0 {
259
+ let asset = self.audioList[audioId]
260
+
261
+ if asset != nil {
262
+ if asset is AudioAsset {
263
+ let audioAsset = asset as? AudioAsset
264
+
265
+ if self.fadeMusic {
266
+ audioAsset?.playWithFade(time: audioAsset?.getCurrentTime() ?? 0)
267
+ } else {
268
+ audioAsset?.stop()
269
+ }
270
+ }
271
+ } else {
272
+ throw MyError.runtimeError(Constant.ErrorAssetNotFound)
273
+ }
274
+ }
275
+ }
276
+ }
package/package.json ADDED
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "@capgo/native-audio",
3
+ "version": "4.0.0",
4
+ "description": "A native plugin for native audio engine",
5
+ "main": "dist/plugin.js",
6
+ "module": "dist/esm/index.js",
7
+ "types": "dist/esm/index.d.ts",
8
+ "unpkg": "dist/plugin.js",
9
+ "files": [
10
+ "android/src/main/",
11
+ "android/build.gradle",
12
+ "dist/",
13
+ "ios/Plugin/",
14
+ "CapgoNativeAudio.podspec"
15
+ ],
16
+ "keywords": [
17
+ "capacitor",
18
+ "plugin",
19
+ "audio",
20
+ "media",
21
+ "native"
22
+ ],
23
+ "scripts": {
24
+ "verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
25
+ "verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin && cd ..",
26
+ "verify:android": "cd android && ./gradlew clean build test && cd ..",
27
+ "verify:web": "npm run build",
28
+ "lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
29
+ "fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- autocorrect --format",
30
+ "eslint": "eslint . --ext ts",
31
+ "prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
32
+ "swiftlint": "node-swiftlint",
33
+ "docgen": "docgen --api NativeAudio --output-readme README.md --output-json dist/docs.json",
34
+ "build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js",
35
+ "clean": "rimraf ./dist",
36
+ "watch": "tsc --watch",
37
+ "prepublishOnly": "npm run build",
38
+ "prepare": "husky install"
39
+ },
40
+ "author": "Martin Donadieu <martindonadieu@gmail.com>",
41
+ "license": "MIT",
42
+ "devDependencies": {
43
+ "@capacitor/android": "^4.4.0",
44
+ "@capacitor/cli": "^4.4.0",
45
+ "@capacitor/core": "^4.4.0",
46
+ "@capacitor/docgen": "^0.2.0",
47
+ "@capacitor/ios": "^4.4.0",
48
+ "@ionic/eslint-config": "^0.3.0",
49
+ "@ionic/prettier-config": "^2.0.0",
50
+ "@ionic/swiftlint-config": "^1.1.2",
51
+ "eslint": "^7.32.0",
52
+ "husky": "^8.0.1",
53
+ "prettier": "^2.7.1",
54
+ "prettier-plugin-java": "^1.6.2",
55
+ "rimraf": "^3.0.2",
56
+ "rollup": "^2.79.1",
57
+ "swiftlint": "^1.0.1",
58
+ "typescript": "^4.8.4"
59
+ },
60
+ "peerDependencies": {
61
+ "@capacitor/core": "^3.0.0 || ^4.0.0"
62
+ },
63
+ "husky": {
64
+ "hooks": {
65
+ "pre-commit": "pretty-quick --staged"
66
+ }
67
+ },
68
+ "capacitor": {
69
+ "ios": {
70
+ "src": "ios"
71
+ },
72
+ "android": {
73
+ "src": "android"
74
+ }
75
+ },
76
+ "prettier": "@ionic/prettier-config",
77
+ "swiftlint": "@ionic/swiftlint-config",
78
+ "eslintConfig": {
79
+ "extends": "@ionic/eslint-config/recommended"
80
+ },
81
+ "repository": {
82
+ "type": "git",
83
+ "url": "https://github.com/capacitor-community/native-audio"
84
+ },
85
+ "bugs": {
86
+ "url": "https://github.com/capacitor-community/native-audio/issues"
87
+ },
88
+ "publishConfig": {
89
+ "access": "public"
90
+ }
91
+ }