@mcfarljw/capacitor-audio 1.0.0
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.
- package/CapacitorAudio.podspec +17 -0
- package/README.md +59 -0
- package/android/build.gradle +58 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/mcfarljw/capacitor/audio/CapacitorAudio.java +113 -0
- package/android/src/main/java/com/mcfarljw/capacitor/audio/CapacitorAudioPlugin.java +43 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +57 -0
- package/dist/esm/definitions.d.ts +10 -0
- package/dist/esm/definitions.js +2 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +12 -0
- package/dist/esm/web.js +13 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +29 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +32 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/CapacitorAudio.swift +99 -0
- package/ios/Plugin/CapacitorAudioPlugin.h +10 -0
- package/ios/Plugin/CapacitorAudioPlugin.m +10 -0
- package/ios/Plugin/CapacitorAudioPlugin.swift +38 -0
- package/ios/Plugin/Info.plist +24 -0
- package/package.json +79 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'CapacitorAudio'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '13.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.swift_version = '5.1'
|
|
17
|
+
end
|
package/README.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# @mcfarljw/capacitor-audio
|
|
2
|
+
|
|
3
|
+
A native audio plugin for Ionic Capacitor.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @mcfarljw/capacitor-audio
|
|
9
|
+
npx cap sync
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## API
|
|
13
|
+
|
|
14
|
+
<docgen-index>
|
|
15
|
+
|
|
16
|
+
* [`play(...)`](#play)
|
|
17
|
+
* [`stop(...)`](#stop)
|
|
18
|
+
* [`stopAll()`](#stopall)
|
|
19
|
+
|
|
20
|
+
</docgen-index>
|
|
21
|
+
|
|
22
|
+
<docgen-api>
|
|
23
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
24
|
+
|
|
25
|
+
### play(...)
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
play(options: { path: string; track: number; }) => Promise<void>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
| Param | Type |
|
|
32
|
+
| ------------- | --------------------------------------------- |
|
|
33
|
+
| **`options`** | <code>{ path: string; track: number; }</code> |
|
|
34
|
+
|
|
35
|
+
--------------------
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
### stop(...)
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
stop(options: { track: number; }) => Promise<void>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
| Param | Type |
|
|
45
|
+
| ------------- | ------------------------------- |
|
|
46
|
+
| **`options`** | <code>{ track: number; }</code> |
|
|
47
|
+
|
|
48
|
+
--------------------
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
### stopAll()
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
stopAll() => Promise<void>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
--------------------
|
|
58
|
+
|
|
59
|
+
</docgen-api>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.6.1'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.1.5'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.5.1'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
repositories {
|
|
10
|
+
google()
|
|
11
|
+
mavenCentral()
|
|
12
|
+
}
|
|
13
|
+
dependencies {
|
|
14
|
+
classpath 'com.android.tools.build:gradle:8.0.0'
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
apply plugin: 'com.android.library'
|
|
19
|
+
|
|
20
|
+
android {
|
|
21
|
+
namespace "com.mcfarljw.capacitor.audio"
|
|
22
|
+
compileSdkVersion project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 33
|
|
23
|
+
defaultConfig {
|
|
24
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 22
|
|
25
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 33
|
|
26
|
+
versionCode 1
|
|
27
|
+
versionName "1.0"
|
|
28
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
29
|
+
}
|
|
30
|
+
buildTypes {
|
|
31
|
+
release {
|
|
32
|
+
minifyEnabled false
|
|
33
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
lintOptions {
|
|
37
|
+
abortOnError false
|
|
38
|
+
}
|
|
39
|
+
compileOptions {
|
|
40
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
41
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
repositories {
|
|
46
|
+
google()
|
|
47
|
+
mavenCentral()
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
dependencies {
|
|
52
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
53
|
+
implementation project(':capacitor-android')
|
|
54
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
55
|
+
testImplementation "junit:junit:$junitVersion"
|
|
56
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
57
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
58
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
package com.mcfarljw.capacitor.audio;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.media.SoundPool;
|
|
5
|
+
import android.net.Uri;
|
|
6
|
+
import android.util.Log;
|
|
7
|
+
|
|
8
|
+
import java.io.File;
|
|
9
|
+
import java.io.IOException;
|
|
10
|
+
import java.util.HashMap;
|
|
11
|
+
import java.util.Map;
|
|
12
|
+
|
|
13
|
+
import com.getcapacitor.Bridge;
|
|
14
|
+
|
|
15
|
+
public class CapacitorAudio {
|
|
16
|
+
private static final String PLUGIN_NAME = "CapacitorAudioPlugin";
|
|
17
|
+
|
|
18
|
+
private SoundPool mSoundPool;
|
|
19
|
+
|
|
20
|
+
final private HashMap<Integer, HashMap<String, Integer>> audioTracks = new HashMap<>();
|
|
21
|
+
final private float mSoundRate = 1.0f;
|
|
22
|
+
final private float mSoundVolume = 1.0f;
|
|
23
|
+
final private Bridge bridge;
|
|
24
|
+
final private Context context;
|
|
25
|
+
|
|
26
|
+
public CapacitorAudio(Context context, Bridge bridge) {
|
|
27
|
+
this.bridge = bridge;
|
|
28
|
+
this.context = context;
|
|
29
|
+
|
|
30
|
+
this.load();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public void load () {
|
|
34
|
+
if (mSoundPool != null) {
|
|
35
|
+
mSoundPool.release();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
mSoundPool = new SoundPool.Builder().setMaxStreams(4).build();
|
|
39
|
+
|
|
40
|
+
mSoundPool.setOnLoadCompleteListener((SoundPool soundPool, int soundId, int status) -> {
|
|
41
|
+
soundPool.play(soundId, mSoundVolume, mSoundVolume, 1, 0, mSoundRate);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public void play(String path, int track) {
|
|
46
|
+
final Context context = this.context;
|
|
47
|
+
final String trimmedPath = path.replaceAll("^/+", "");
|
|
48
|
+
final String absolutePath = context.getFilesDir().getAbsolutePath() + "/files/" + trimmedPath;
|
|
49
|
+
final String parsedPath = Uri.parse(absolutePath).getPath();
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
if (!audioTracks.containsKey(track)) {
|
|
53
|
+
audioTracks.put(track, new HashMap<>());
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
this.bridge.getActivity().runOnUiThread(() -> {
|
|
57
|
+
if (audioTracks.get(track).containsKey(trimmedPath)) {
|
|
58
|
+
mSoundPool.play(audioTracks.get(track).get(trimmedPath), mSoundVolume, mSoundVolume, 1, 0, mSoundRate);
|
|
59
|
+
} else {
|
|
60
|
+
final File file = new File(parsedPath);
|
|
61
|
+
int soundId;
|
|
62
|
+
|
|
63
|
+
Log.d(PLUGIN_NAME, "playing file: " + file.getAbsolutePath());
|
|
64
|
+
|
|
65
|
+
if (file.exists()) {
|
|
66
|
+
soundId = mSoundPool.load(file.getPath(), 1);
|
|
67
|
+
audioTracks.get(track).put(trimmedPath, soundId);
|
|
68
|
+
} else {
|
|
69
|
+
try {
|
|
70
|
+
soundId = mSoundPool.load(context.getAssets().openFd("public/" + trimmedPath), 1);
|
|
71
|
+
audioTracks.get(track).put(trimmedPath, soundId);
|
|
72
|
+
} catch (IOException error) {
|
|
73
|
+
Log.i(PLUGIN_NAME, "public file not found: " + error.getMessage());
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
try {
|
|
77
|
+
soundId = mSoundPool.load(context.getAssets().openFd("www/" + trimmedPath), 1);
|
|
78
|
+
audioTracks.get(track).put(trimmedPath, soundId);
|
|
79
|
+
} catch (IOException error) {
|
|
80
|
+
Log.d(PLUGIN_NAME, "www file not found: " + error.getMessage());
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public void stop(int track) {
|
|
88
|
+
if (!audioTracks.containsKey(track)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
for (HashMap.Entry<String, Integer> entry : audioTracks.get(track).entrySet()) {
|
|
94
|
+
mSoundPool.stop(entry.getValue());
|
|
95
|
+
mSoundPool.unload(entry.getValue());
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
audioTracks.remove(track);
|
|
99
|
+
} catch (NullPointerException error) {
|
|
100
|
+
Log.i(PLUGIN_NAME, "Unable to stop audio track!");
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
public void stopAll() {
|
|
105
|
+
try {
|
|
106
|
+
for (Map.Entry<Integer, HashMap<String, Integer>> entry : audioTracks.entrySet()) {
|
|
107
|
+
stop(entry.getKey());
|
|
108
|
+
}
|
|
109
|
+
} catch (NullPointerException error) {
|
|
110
|
+
Log.i(PLUGIN_NAME, "Unable to stop audio tracks!");
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
package com.mcfarljw.capacitor.audio;
|
|
2
|
+
|
|
3
|
+
import com.getcapacitor.Plugin;
|
|
4
|
+
import com.getcapacitor.PluginCall;
|
|
5
|
+
import com.getcapacitor.PluginMethod;
|
|
6
|
+
import com.getcapacitor.annotation.CapacitorPlugin;
|
|
7
|
+
|
|
8
|
+
@CapacitorPlugin(name = "CapacitorAudio")
|
|
9
|
+
public class CapacitorAudioPlugin extends Plugin {
|
|
10
|
+
|
|
11
|
+
private CapacitorAudio implementation;
|
|
12
|
+
|
|
13
|
+
@Override
|
|
14
|
+
public void load() {
|
|
15
|
+
this.implementation = new CapacitorAudio(this.getContext(), this.getBridge());
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@PluginMethod
|
|
19
|
+
public void play(PluginCall call) {
|
|
20
|
+
String path = call.getString("path");
|
|
21
|
+
int track = call.getInt("track", 0);
|
|
22
|
+
|
|
23
|
+
implementation.play(path, track);
|
|
24
|
+
|
|
25
|
+
call.resolve();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@PluginMethod
|
|
29
|
+
public void stop(PluginCall call) {
|
|
30
|
+
int track = call.getInt("track", 0);
|
|
31
|
+
|
|
32
|
+
implementation.stop(track);
|
|
33
|
+
|
|
34
|
+
call.resolve();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@PluginMethod
|
|
38
|
+
public void stopAll(PluginCall call) {
|
|
39
|
+
implementation.stopAll();
|
|
40
|
+
|
|
41
|
+
call.resolve();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
File without changes
|
package/dist/docs.json
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
{
|
|
2
|
+
"api": {
|
|
3
|
+
"name": "CapacitorAudioPlugin",
|
|
4
|
+
"slug": "capacitoraudioplugin",
|
|
5
|
+
"docs": "",
|
|
6
|
+
"tags": [],
|
|
7
|
+
"methods": [
|
|
8
|
+
{
|
|
9
|
+
"name": "play",
|
|
10
|
+
"signature": "(options: { path: string; track: number; }) => Promise<void>",
|
|
11
|
+
"parameters": [
|
|
12
|
+
{
|
|
13
|
+
"name": "options",
|
|
14
|
+
"docs": "",
|
|
15
|
+
"type": "{ path: string; track: number; }"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"returns": "Promise<void>",
|
|
19
|
+
"tags": [],
|
|
20
|
+
"docs": "",
|
|
21
|
+
"complexTypes": [],
|
|
22
|
+
"slug": "play"
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"name": "stop",
|
|
26
|
+
"signature": "(options: { track: number; }) => Promise<void>",
|
|
27
|
+
"parameters": [
|
|
28
|
+
{
|
|
29
|
+
"name": "options",
|
|
30
|
+
"docs": "",
|
|
31
|
+
"type": "{ track: number; }"
|
|
32
|
+
}
|
|
33
|
+
],
|
|
34
|
+
"returns": "Promise<void>",
|
|
35
|
+
"tags": [],
|
|
36
|
+
"docs": "",
|
|
37
|
+
"complexTypes": [],
|
|
38
|
+
"slug": "stop"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"name": "stopAll",
|
|
42
|
+
"signature": "() => Promise<void>",
|
|
43
|
+
"parameters": [],
|
|
44
|
+
"returns": "Promise<void>",
|
|
45
|
+
"tags": [],
|
|
46
|
+
"docs": "",
|
|
47
|
+
"complexTypes": [],
|
|
48
|
+
"slug": "stopall"
|
|
49
|
+
}
|
|
50
|
+
],
|
|
51
|
+
"properties": []
|
|
52
|
+
},
|
|
53
|
+
"interfaces": [],
|
|
54
|
+
"enums": [],
|
|
55
|
+
"typeAliases": [],
|
|
56
|
+
"pluginConfigs": []
|
|
57
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface CapacitorAudioPlugin {\n play(options: { path: string, track: number }): Promise<void>;\n stop(options: { track: number }): Promise<void>;\n stopAll(): Promise<void>;\n}\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { registerPlugin } from '@capacitor/core';
|
|
2
|
+
const CapacitorAudio = registerPlugin('CapacitorAudio', {
|
|
3
|
+
web: () => import('./web').then(m => new m.CapacitorAudioWeb()),
|
|
4
|
+
});
|
|
5
|
+
export * from './definitions';
|
|
6
|
+
export { CapacitorAudio };
|
|
7
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,cAAc,GAAG,cAAc,CAAuB,gBAAgB,EAAE;IAC5E,GAAG,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;CAChE,CAAC,CAAC;AAEH,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,cAAc,EAAE,CAAC","sourcesContent":["import { registerPlugin } from '@capacitor/core';\n\nimport type { CapacitorAudioPlugin } from './definitions';\n\nconst CapacitorAudio = registerPlugin<CapacitorAudioPlugin>('CapacitorAudio', {\n web: () => import('./web').then(m => new m.CapacitorAudioWeb()),\n});\n\nexport * from './definitions';\nexport { CapacitorAudio };\n"]}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
import type { CapacitorAudioPlugin } from './definitions';
|
|
3
|
+
export declare class CapacitorAudioWeb extends WebPlugin implements CapacitorAudioPlugin {
|
|
4
|
+
play(options: {
|
|
5
|
+
path: string;
|
|
6
|
+
track: number;
|
|
7
|
+
}): Promise<void>;
|
|
8
|
+
stop(options: {
|
|
9
|
+
track: number;
|
|
10
|
+
}): Promise<void>;
|
|
11
|
+
stopAll(): Promise<void>;
|
|
12
|
+
}
|
package/dist/esm/web.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { WebPlugin } from '@capacitor/core';
|
|
2
|
+
export class CapacitorAudioWeb extends WebPlugin {
|
|
3
|
+
async play(options) {
|
|
4
|
+
console.log('play', options);
|
|
5
|
+
}
|
|
6
|
+
async stop(options) {
|
|
7
|
+
console.log('stop', options);
|
|
8
|
+
}
|
|
9
|
+
async stopAll() {
|
|
10
|
+
console.log('stopAll');
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=web.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,iBACX,SAAQ,SAAS;IAGjB,KAAK,CAAC,IAAI,CAAC,OAAwC;QACjD,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,OAA0B;QACnC,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,KAAK,CAAC,OAAO;QACX,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACzB,CAAC;CACF","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { CapacitorAudioPlugin } from './definitions';\n\nexport class CapacitorAudioWeb\n extends WebPlugin\n implements CapacitorAudioPlugin\n{\n async play(options: { path: string; track: number }): Promise<void> {\n console.log('play', options);\n }\n async stop(options: { track: number }): Promise<void> {\n console.log('stop', options);\n }\n async stopAll(): Promise<void> {\n console.log('stopAll');\n }\n}\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var core = require('@capacitor/core');
|
|
6
|
+
|
|
7
|
+
const CapacitorAudio = core.registerPlugin('CapacitorAudio', {
|
|
8
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.CapacitorAudioWeb()),
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
class CapacitorAudioWeb extends core.WebPlugin {
|
|
12
|
+
async play(options) {
|
|
13
|
+
console.log('play', options);
|
|
14
|
+
}
|
|
15
|
+
async stop(options) {
|
|
16
|
+
console.log('stop', options);
|
|
17
|
+
}
|
|
18
|
+
async stopAll() {
|
|
19
|
+
console.log('stopAll');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
24
|
+
__proto__: null,
|
|
25
|
+
CapacitorAudioWeb: CapacitorAudioWeb
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
exports.CapacitorAudio = CapacitorAudio;
|
|
29
|
+
//# sourceMappingURL=plugin.cjs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CapacitorAudio = registerPlugin('CapacitorAudio', {\n web: () => import('./web').then(m => new m.CapacitorAudioWeb()),\n});\nexport * from './definitions';\nexport { CapacitorAudio };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CapacitorAudioWeb extends WebPlugin {\n async play(options) {\n console.log('play', options);\n }\n async stop(options) {\n console.log('stop', options);\n }\n async stopAll() {\n console.log('stopAll');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;;;AACK,MAAC,cAAc,GAAGA,mBAAc,CAAC,gBAAgB,EAAE;AACxD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;AACnE,CAAC;;ACFM,MAAM,iBAAiB,SAASC,cAAS,CAAC;AACjD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,KAAK;AACL,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,KAAK;AACL,IAAI,MAAM,OAAO,GAAG;AACpB,QAAQ,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AAC/B,KAAK;AACL;;;;;;;;;"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
var capacitorCapacitorAudio = (function (exports, core) {
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
const CapacitorAudio = core.registerPlugin('CapacitorAudio', {
|
|
5
|
+
web: () => Promise.resolve().then(function () { return web; }).then(m => new m.CapacitorAudioWeb()),
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
class CapacitorAudioWeb extends core.WebPlugin {
|
|
9
|
+
async play(options) {
|
|
10
|
+
console.log('play', options);
|
|
11
|
+
}
|
|
12
|
+
async stop(options) {
|
|
13
|
+
console.log('stop', options);
|
|
14
|
+
}
|
|
15
|
+
async stopAll() {
|
|
16
|
+
console.log('stopAll');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
var web = /*#__PURE__*/Object.freeze({
|
|
21
|
+
__proto__: null,
|
|
22
|
+
CapacitorAudioWeb: CapacitorAudioWeb
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
exports.CapacitorAudio = CapacitorAudio;
|
|
26
|
+
|
|
27
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
28
|
+
|
|
29
|
+
return exports;
|
|
30
|
+
|
|
31
|
+
})({}, capacitorExports);
|
|
32
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst CapacitorAudio = registerPlugin('CapacitorAudio', {\n web: () => import('./web').then(m => new m.CapacitorAudioWeb()),\n});\nexport * from './definitions';\nexport { CapacitorAudio };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CapacitorAudioWeb extends WebPlugin {\n async play(options) {\n console.log('play', options);\n }\n async stop(options) {\n console.log('stop', options);\n }\n async stopAll() {\n console.log('stopAll');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,cAAc,GAAGA,mBAAc,CAAC,gBAAgB,EAAE;IACxD,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,iBAAiB,EAAE,CAAC;IACnE,CAAC;;ICFM,MAAM,iBAAiB,SAASC,cAAS,CAAC;IACjD,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK;IACL,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK;IACL,IAAI,MAAM,OAAO,GAAG;IACpB,QAAQ,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAC/B,KAAK;IACL;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import AVFoundation
|
|
2
|
+
import Foundation
|
|
3
|
+
|
|
4
|
+
@objc public class CapacitorAudio: NSObject, AVAudioPlayerDelegate {
|
|
5
|
+
var documentDirectory: String!
|
|
6
|
+
var wwwDirectory: String!
|
|
7
|
+
var publicDirectory: String!
|
|
8
|
+
var audioPlayer1: AVAudioPlayer!
|
|
9
|
+
var audioPlayer2: AVAudioPlayer!
|
|
10
|
+
var audioPlayer3: AVAudioPlayer!
|
|
11
|
+
|
|
12
|
+
@objc public func load() {
|
|
13
|
+
let searchPaths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
|
|
14
|
+
|
|
15
|
+
self.documentDirectory = searchPaths[0]
|
|
16
|
+
|
|
17
|
+
if let resourcePath = Bundle.main.resourcePath {
|
|
18
|
+
self.wwwDirectory = resourcePath + "/www"
|
|
19
|
+
self.publicDirectory = resourcePath + "/public"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
do {
|
|
23
|
+
try AVAudioSession.sharedInstance().setCategory(.playback, options: .mixWithOthers)
|
|
24
|
+
} catch {
|
|
25
|
+
print("Unable to set audio session category: \(error)")
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@objc public func play(_ path: String, _ track: Int) -> Void {
|
|
30
|
+
let trimmedPath = path.trimmingCharacters(in: .whitespaces)
|
|
31
|
+
let documentPath = "\(self.documentDirectory!)\(trimmedPath)"
|
|
32
|
+
let wwwPath = "\(self.wwwDirectory!)\(trimmedPath)"
|
|
33
|
+
let publicPath = "\(self.publicDirectory!)\(trimmedPath)"
|
|
34
|
+
|
|
35
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
36
|
+
var audioUrl: URL?
|
|
37
|
+
|
|
38
|
+
if FileManager.default.fileExists(atPath: publicPath) {
|
|
39
|
+
audioUrl = URL(fileURLWithPath: publicPath)
|
|
40
|
+
} else if FileManager.default.fileExists(atPath: wwwPath) {
|
|
41
|
+
audioUrl = URL(fileURLWithPath: wwwPath)
|
|
42
|
+
} else if FileManager.default.fileExists(atPath: documentPath) {
|
|
43
|
+
audioUrl = URL(fileURLWithPath: documentPath)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if let audioUrl = audioUrl {
|
|
47
|
+
if track == 0 {
|
|
48
|
+
self.audioPlayer1 = try? AVAudioPlayer(contentsOf: audioUrl)
|
|
49
|
+
self.audioPlayer1?.delegate = self
|
|
50
|
+
|
|
51
|
+
self.audioPlayer1?.play()
|
|
52
|
+
} else if track == 1 {
|
|
53
|
+
self.audioPlayer2 = try? AVAudioPlayer(contentsOf: audioUrl)
|
|
54
|
+
self.audioPlayer2?.delegate = self
|
|
55
|
+
|
|
56
|
+
self.audioPlayer2?.play()
|
|
57
|
+
} else if track == 2 {
|
|
58
|
+
self.audioPlayer3 = try? AVAudioPlayer(contentsOf: audioUrl)
|
|
59
|
+
self.audioPlayer3?.delegate = self
|
|
60
|
+
|
|
61
|
+
self.audioPlayer3?.play()
|
|
62
|
+
} else {
|
|
63
|
+
self.audioPlayer1 = try? AVAudioPlayer(contentsOf: audioUrl)
|
|
64
|
+
self.audioPlayer1?.delegate = self
|
|
65
|
+
|
|
66
|
+
self.audioPlayer1?.play()
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@objc public func stop(_ track: Int) -> Void {
|
|
75
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
76
|
+
if track == 0 {
|
|
77
|
+
self.audioPlayer1?.stop()
|
|
78
|
+
} else if track == 1 {
|
|
79
|
+
self.audioPlayer2?.stop()
|
|
80
|
+
} else if track == 2 {
|
|
81
|
+
self.audioPlayer3?.stop()
|
|
82
|
+
} else {
|
|
83
|
+
self.audioPlayer1?.stop()
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
@objc public func stopAll() -> Void {
|
|
91
|
+
DispatchQueue.global(qos: .userInitiated).async {
|
|
92
|
+
self.audioPlayer1?.stop()
|
|
93
|
+
self.audioPlayer2?.stop()
|
|
94
|
+
self.audioPlayer3?.stop()
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return
|
|
98
|
+
}
|
|
99
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
//! Project version number for Plugin.
|
|
4
|
+
FOUNDATION_EXPORT double PluginVersionNumber;
|
|
5
|
+
|
|
6
|
+
//! Project version string for Plugin.
|
|
7
|
+
FOUNDATION_EXPORT const unsigned char PluginVersionString[];
|
|
8
|
+
|
|
9
|
+
// In this header, you should import all the public headers of your framework using statements like #import <Plugin/PublicHeader.h>
|
|
10
|
+
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#import <Foundation/Foundation.h>
|
|
2
|
+
#import <Capacitor/Capacitor.h>
|
|
3
|
+
|
|
4
|
+
// Define the plugin using the CAP_PLUGIN Macro, and
|
|
5
|
+
// each method the plugin supports using the CAP_PLUGIN_METHOD macro.
|
|
6
|
+
CAP_PLUGIN(CapacitorAudioPlugin, "CapacitorAudio",
|
|
7
|
+
CAP_PLUGIN_METHOD(play, CAPPluginReturnPromise);
|
|
8
|
+
CAP_PLUGIN_METHOD(stop, CAPPluginReturnPromise);
|
|
9
|
+
CAP_PLUGIN_METHOD(stopAll, CAPPluginReturnPromise);
|
|
10
|
+
)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import Capacitor
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Please read the Capacitor iOS Plugin Development Guide
|
|
6
|
+
* here: https://capacitorjs.com/docs/plugins/ios
|
|
7
|
+
*/
|
|
8
|
+
@objc(CapacitorAudioPlugin)
|
|
9
|
+
public class CapacitorAudioPlugin: CAPPlugin {
|
|
10
|
+
private let implementation = CapacitorAudio()
|
|
11
|
+
|
|
12
|
+
override public func load() {
|
|
13
|
+
implementation.load()
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@objc func play(_ call: CAPPluginCall) {
|
|
17
|
+
let path = call.getString("path") ?? ""
|
|
18
|
+
let track = call.getInt("path", 0)
|
|
19
|
+
|
|
20
|
+
implementation.play(path, track)
|
|
21
|
+
|
|
22
|
+
call.resolve()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@objc func stop(_ call: CAPPluginCall) {
|
|
26
|
+
let track = call.getInt("path", 0)
|
|
27
|
+
|
|
28
|
+
implementation.stop(track)
|
|
29
|
+
|
|
30
|
+
call.resolve()
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@objc func stopAll(_ call: CAPPluginCall) {
|
|
34
|
+
implementation.stopAll()
|
|
35
|
+
|
|
36
|
+
call.resolve()
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
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>CFBundleDevelopmentRegion</key>
|
|
6
|
+
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
|
7
|
+
<key>CFBundleExecutable</key>
|
|
8
|
+
<string>$(EXECUTABLE_NAME)</string>
|
|
9
|
+
<key>CFBundleIdentifier</key>
|
|
10
|
+
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
|
11
|
+
<key>CFBundleInfoDictionaryVersion</key>
|
|
12
|
+
<string>6.0</string>
|
|
13
|
+
<key>CFBundleName</key>
|
|
14
|
+
<string>$(PRODUCT_NAME)</string>
|
|
15
|
+
<key>CFBundlePackageType</key>
|
|
16
|
+
<string>FMWK</string>
|
|
17
|
+
<key>CFBundleShortVersionString</key>
|
|
18
|
+
<string>1.0</string>
|
|
19
|
+
<key>CFBundleVersion</key>
|
|
20
|
+
<string>$(CURRENT_PROJECT_VERSION)</string>
|
|
21
|
+
<key>NSPrincipalClass</key>
|
|
22
|
+
<string></string>
|
|
23
|
+
</dict>
|
|
24
|
+
</plist>
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mcfarljw/capacitor-audio",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A native audio plugin for Ionic Capacitor.",
|
|
5
|
+
"main": "dist/plugin.cjs.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
|
+
"CapacitorAudio.podspec"
|
|
15
|
+
],
|
|
16
|
+
"author": "Joshua McFarland <mcfarljw@gmail.com>",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/mcfarljw/capacitor-audio.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/mcfarljw/capacitor-audio/issues"
|
|
24
|
+
},
|
|
25
|
+
"keywords": [
|
|
26
|
+
"capacitor",
|
|
27
|
+
"plugin",
|
|
28
|
+
"native"
|
|
29
|
+
],
|
|
30
|
+
"scripts": {
|
|
31
|
+
"verify": "npm run verify:ios && npm run verify:android && npm run verify:web",
|
|
32
|
+
"verify:ios": "cd ios && pod install && xcodebuild -workspace Plugin.xcworkspace -scheme Plugin -destination generic/platform=iOS && cd ..",
|
|
33
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
34
|
+
"verify:web": "npm run build",
|
|
35
|
+
"lint": "npm run eslint && npm run prettier -- --check && npm run swiftlint -- lint",
|
|
36
|
+
"fmt": "npm run eslint -- --fix && npm run prettier -- --write && npm run swiftlint -- --fix --format",
|
|
37
|
+
"eslint": "eslint . --ext ts",
|
|
38
|
+
"prettier": "prettier \"**/*.{css,html,ts,js,java}\"",
|
|
39
|
+
"swiftlint": "node-swiftlint",
|
|
40
|
+
"docgen": "docgen --api CapacitorAudioPlugin --output-readme README.md --output-json dist/docs.json",
|
|
41
|
+
"build": "npm run clean && npm run docgen && tsc && rollup -c rollup.config.js",
|
|
42
|
+
"clean": "rimraf ./dist",
|
|
43
|
+
"watch": "tsc --watch",
|
|
44
|
+
"prepublishOnly": "npm run build"
|
|
45
|
+
},
|
|
46
|
+
"devDependencies": {
|
|
47
|
+
"@capacitor/android": "^5.0.0",
|
|
48
|
+
"@capacitor/cli": "^5.4.0",
|
|
49
|
+
"@capacitor/core": "^5.0.0",
|
|
50
|
+
"@capacitor/docgen": "^0.0.18",
|
|
51
|
+
"@capacitor/ios": "^5.0.0",
|
|
52
|
+
"@ionic/eslint-config": "^0.3.0",
|
|
53
|
+
"@ionic/prettier-config": "^1.0.1",
|
|
54
|
+
"@ionic/swiftlint-config": "^1.1.2",
|
|
55
|
+
"eslint": "^7.11.0",
|
|
56
|
+
"prettier": "~2.3.0",
|
|
57
|
+
"prettier-plugin-java": "~1.0.2",
|
|
58
|
+
"rimraf": "^3.0.2",
|
|
59
|
+
"rollup": "^2.32.0",
|
|
60
|
+
"swiftlint": "^1.0.1",
|
|
61
|
+
"typescript": "~4.1.5"
|
|
62
|
+
},
|
|
63
|
+
"peerDependencies": {
|
|
64
|
+
"@capacitor/core": "^5.0.0"
|
|
65
|
+
},
|
|
66
|
+
"prettier": "@ionic/prettier-config",
|
|
67
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
68
|
+
"eslintConfig": {
|
|
69
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
70
|
+
},
|
|
71
|
+
"capacitor": {
|
|
72
|
+
"ios": {
|
|
73
|
+
"src": "ios"
|
|
74
|
+
},
|
|
75
|
+
"android": {
|
|
76
|
+
"src": "android"
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|