@capgo/capacitor-native-audio 8.4.3
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/CapgoCapacitorNativeAudio.podspec +16 -0
- package/LICENSE +373 -0
- package/Package.swift +31 -0
- package/README.md +1229 -0
- package/android/build.gradle +89 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/java/ee/forgr/audio/AudioAsset.java +611 -0
- package/android/src/main/java/ee/forgr/audio/AudioCompletionListener.java +5 -0
- package/android/src/main/java/ee/forgr/audio/AudioDispatcher.java +208 -0
- package/android/src/main/java/ee/forgr/audio/Constant.java +36 -0
- package/android/src/main/java/ee/forgr/audio/HlsAvailabilityChecker.java +84 -0
- package/android/src/main/java/ee/forgr/audio/Logger.java +55 -0
- package/android/src/main/java/ee/forgr/audio/NativeAudio.java +2022 -0
- package/android/src/main/java/ee/forgr/audio/RemoteAudioAsset.java +886 -0
- package/android/src/main/java/ee/forgr/audio/StreamAudioAsset.java +708 -0
- package/android/src/main/res/values/colors.xml +3 -0
- package/android/src/main/res/values/strings.xml +3 -0
- package/android/src/main/res/values/styles.xml +3 -0
- package/dist/docs.json +1470 -0
- package/dist/esm/audio-asset.d.ts +4 -0
- package/dist/esm/audio-asset.js +6 -0
- package/dist/esm/audio-asset.js.map +1 -0
- package/dist/esm/definitions.d.ts +597 -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 +82 -0
- package/dist/esm/web.js +553 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +571 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +574 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Sources/NativeAudioPlugin/AudioAsset+Fade.swift +157 -0
- package/ios/Sources/NativeAudioPlugin/AudioAsset.swift +403 -0
- package/ios/Sources/NativeAudioPlugin/Constant.swift +52 -0
- package/ios/Sources/NativeAudioPlugin/Logger.swift +43 -0
- package/ios/Sources/NativeAudioPlugin/Plugin.swift +1786 -0
- package/ios/Sources/NativeAudioPlugin/RemoteAudioAsset+Fade.swift +152 -0
- package/ios/Sources/NativeAudioPlugin/RemoteAudioAsset.swift +405 -0
- package/ios/Tests/NativeAudioPluginTests/PluginTests.swift +648 -0
- package/ios/Tests/README.md +39 -0
- package/package.json +101 -0
- package/scripts/configure-dependencies.js +251 -0
package/package.json
ADDED
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@capgo/capacitor-native-audio",
|
|
3
|
+
"version": "8.4.3",
|
|
4
|
+
"description": "A native plugin for native audio engine",
|
|
5
|
+
"license": "MPL-2.0",
|
|
6
|
+
"main": "dist/plugin.cjs.js",
|
|
7
|
+
"module": "dist/esm/index.js",
|
|
8
|
+
"types": "dist/esm/index.d.ts",
|
|
9
|
+
"unpkg": "dist/plugin.js",
|
|
10
|
+
"files": [
|
|
11
|
+
"android/src/main/",
|
|
12
|
+
"android/build.gradle",
|
|
13
|
+
"dist/",
|
|
14
|
+
"ios/Sources",
|
|
15
|
+
"ios/Tests",
|
|
16
|
+
"Package.swift",
|
|
17
|
+
"CapgoCapacitorNativeAudio.podspec",
|
|
18
|
+
"scripts/configure-dependencies.js"
|
|
19
|
+
],
|
|
20
|
+
"author": "Martin Donadieu",
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/Cap-go/capacitor-native-audio.git"
|
|
24
|
+
},
|
|
25
|
+
"bugs": {
|
|
26
|
+
"url": "https://github.com/Cap-go/capacitor-native-audio/native-audio/issues"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://capgo.app/docs/plugins/native-audio/",
|
|
29
|
+
"keywords": [
|
|
30
|
+
"capacitor",
|
|
31
|
+
"plugin",
|
|
32
|
+
"audio",
|
|
33
|
+
"media",
|
|
34
|
+
"capgo",
|
|
35
|
+
"native"
|
|
36
|
+
],
|
|
37
|
+
"scripts": {
|
|
38
|
+
"capacitor:sync:after": "node scripts/configure-dependencies.js",
|
|
39
|
+
"verify": "bun run verify:ios && bun run verify:android && bun run verify:web",
|
|
40
|
+
"verify:ios": "xcodebuild -scheme CapgoCapacitorNativeAudio -destination generic/platform=iOS",
|
|
41
|
+
"verify:android": "cd android && ./gradlew clean build test && cd ..",
|
|
42
|
+
"verify:web": "bun run build",
|
|
43
|
+
"test": "bun run test:ios",
|
|
44
|
+
"test:ios": "cd ios && xcodebuild test -workspace Plugin.xcworkspace -scheme Plugin -destination 'platform=iOS Simulator,name=iPhone 16' && cd ..",
|
|
45
|
+
"lint": "bun run eslint && bun run prettier -- --check && bun run swiftlint -- lint",
|
|
46
|
+
"fmt": "bun run eslint -- --fix && bun run prettier -- --write && bun run swiftlint -- --fix --format",
|
|
47
|
+
"eslint": "eslint . --ext .ts",
|
|
48
|
+
"prettier": "prettier-pretty-check \"**/*.{css,html,ts,js,java}\" --plugin=prettier-plugin-java",
|
|
49
|
+
"swiftlint": "node-swiftlint",
|
|
50
|
+
"docgen": "docgen --api NativeAudio --output-readme README.md --output-json dist/docs.json",
|
|
51
|
+
"build": "bun run clean && bun run docgen && bun run build:scripts && tsc && rollup -c rollup.config.mjs",
|
|
52
|
+
"build:scripts": "tsc -p scripts/tsconfig.json",
|
|
53
|
+
"clean": "rimraf ./dist",
|
|
54
|
+
"watch": "tsc --watch",
|
|
55
|
+
"example:install": "cd example-app && bun install",
|
|
56
|
+
"example:build": "cd example-app && bun run build",
|
|
57
|
+
"example:sync:android": "cd example-app && bun run sync:android",
|
|
58
|
+
"example:sync:ios": "cd example-app && bun run sync:ios",
|
|
59
|
+
"test:e2e:android": "maestro test .maestro/android/basic-features.yaml",
|
|
60
|
+
"test:e2e:ios": "maestro test .maestro/ios/basic-features.yaml",
|
|
61
|
+
"prepublishOnly": "bun run build",
|
|
62
|
+
"check:wiring": "node scripts/check-capacitor-plugin-wiring.mjs"
|
|
63
|
+
},
|
|
64
|
+
"devDependencies": {
|
|
65
|
+
"@capacitor/android": "^8.0.0",
|
|
66
|
+
"@capacitor/cli": "^8.0.0",
|
|
67
|
+
"@capacitor/core": "^8.0.0",
|
|
68
|
+
"@capacitor/docgen": "^0.3.1",
|
|
69
|
+
"@capacitor/ios": "^8.0.0",
|
|
70
|
+
"@ionic/eslint-config": "^0.4.0",
|
|
71
|
+
"@ionic/prettier-config": "^4.0.0",
|
|
72
|
+
"@ionic/swiftlint-config": "^2.0.0",
|
|
73
|
+
"@types/node": "^24.10.1",
|
|
74
|
+
"eslint": "^8.57.1",
|
|
75
|
+
"eslint-plugin-import": "^2.31.0",
|
|
76
|
+
"husky": "^9.1.7",
|
|
77
|
+
"prettier": "^3.6.2",
|
|
78
|
+
"prettier-plugin-java": "^2.7.7",
|
|
79
|
+
"rimraf": "^6.1.0",
|
|
80
|
+
"rollup": "^4.53.2",
|
|
81
|
+
"swiftlint": "^2.0.0",
|
|
82
|
+
"typescript": "^5.9.3",
|
|
83
|
+
"prettier-pretty-check": "^0.2.0"
|
|
84
|
+
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"@capacitor/core": ">=8.0.0"
|
|
87
|
+
},
|
|
88
|
+
"prettier": "@ionic/prettier-config",
|
|
89
|
+
"swiftlint": "@ionic/swiftlint-config",
|
|
90
|
+
"eslintConfig": {
|
|
91
|
+
"extends": "@ionic/eslint-config/recommended"
|
|
92
|
+
},
|
|
93
|
+
"capacitor": {
|
|
94
|
+
"ios": {
|
|
95
|
+
"src": "ios"
|
|
96
|
+
},
|
|
97
|
+
"android": {
|
|
98
|
+
"src": "android"
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* Capacitor Hook Script: Configure Optional HLS Dependency
|
|
5
|
+
*
|
|
6
|
+
* This script runs during `npx cap sync` and configures whether to include
|
|
7
|
+
* the HLS (m3u8) streaming dependency based on capacitor.config.ts settings.
|
|
8
|
+
*
|
|
9
|
+
* By default, HLS is enabled for backward compatibility.
|
|
10
|
+
* To disable HLS and reduce APK size by ~4MB, set:
|
|
11
|
+
*
|
|
12
|
+
* plugins: {
|
|
13
|
+
* NativeAudio: {
|
|
14
|
+
* hls: false
|
|
15
|
+
* }
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* Environment variables provided by Capacitor:
|
|
19
|
+
* - CAPACITOR_ROOT_DIR: Root directory of the consuming app
|
|
20
|
+
* - CAPACITOR_CONFIG: JSON stringified config object
|
|
21
|
+
* - CAPACITOR_PLATFORM_NAME: Platform name (android, ios, web)
|
|
22
|
+
* - process.cwd(): Plugin root directory
|
|
23
|
+
*/
|
|
24
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
27
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
28
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
29
|
+
}
|
|
30
|
+
Object.defineProperty(o, k2, desc);
|
|
31
|
+
}) : (function(o, m, k, k2) {
|
|
32
|
+
if (k2 === undefined) k2 = k;
|
|
33
|
+
o[k2] = m[k];
|
|
34
|
+
}));
|
|
35
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
36
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
37
|
+
}) : function(o, v) {
|
|
38
|
+
o["default"] = v;
|
|
39
|
+
});
|
|
40
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
41
|
+
var ownKeys = function(o) {
|
|
42
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
43
|
+
var ar = [];
|
|
44
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
45
|
+
return ar;
|
|
46
|
+
};
|
|
47
|
+
return ownKeys(o);
|
|
48
|
+
};
|
|
49
|
+
return function (mod) {
|
|
50
|
+
if (mod && mod.__esModule) return mod;
|
|
51
|
+
var result = {};
|
|
52
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
53
|
+
__setModuleDefault(result, mod);
|
|
54
|
+
return result;
|
|
55
|
+
};
|
|
56
|
+
})();
|
|
57
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
58
|
+
exports.getConfig = getConfig;
|
|
59
|
+
exports.configureAndroid = configureAndroid;
|
|
60
|
+
exports.configureIOS = configureIOS;
|
|
61
|
+
exports.configureWeb = configureWeb;
|
|
62
|
+
const fs = __importStar(require("fs"));
|
|
63
|
+
const path = __importStar(require("path"));
|
|
64
|
+
// Get environment variables
|
|
65
|
+
const PLUGIN_ROOT = process.cwd();
|
|
66
|
+
const CONFIG_JSON = process.env.CAPACITOR_CONFIG;
|
|
67
|
+
const PLATFORM = process.env.CAPACITOR_PLATFORM_NAME;
|
|
68
|
+
// File paths
|
|
69
|
+
const gradlePropertiesPath = path.join(PLUGIN_ROOT, 'android', 'gradle.properties');
|
|
70
|
+
// ============================================================================
|
|
71
|
+
// Logging Utilities
|
|
72
|
+
// ============================================================================
|
|
73
|
+
const colors = {
|
|
74
|
+
reset: '\x1b[0m',
|
|
75
|
+
bright: '\x1b[1m',
|
|
76
|
+
green: '\x1b[32m',
|
|
77
|
+
red: '\x1b[31m',
|
|
78
|
+
yellow: '\x1b[33m',
|
|
79
|
+
blue: '\x1b[34m',
|
|
80
|
+
cyan: '\x1b[36m',
|
|
81
|
+
gray: '\x1b[90m',
|
|
82
|
+
};
|
|
83
|
+
function log(message, emoji = '', color = '') {
|
|
84
|
+
const emojiPart = emoji ? `${emoji} ` : '';
|
|
85
|
+
const colorCode = color || colors.reset;
|
|
86
|
+
const resetCode = color ? colors.reset : '';
|
|
87
|
+
console.log(`${colorCode}${emojiPart}${message}${resetCode}`);
|
|
88
|
+
}
|
|
89
|
+
function logSuccess(message) {
|
|
90
|
+
log(message, '✔', colors.green);
|
|
91
|
+
}
|
|
92
|
+
function logError(message) {
|
|
93
|
+
log(message, '✖', colors.red);
|
|
94
|
+
}
|
|
95
|
+
function logInfo(message) {
|
|
96
|
+
log(message, 'ℹ', colors.blue);
|
|
97
|
+
}
|
|
98
|
+
function logWarning(message) {
|
|
99
|
+
log(message, '⚠', colors.yellow);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Parse NativeAudio configuration from Capacitor config
|
|
103
|
+
* Default: hls = true (for backward compatibility)
|
|
104
|
+
*/
|
|
105
|
+
function getConfig() {
|
|
106
|
+
const defaultConfig = {
|
|
107
|
+
hls: true, // Enabled by default for backward compatibility
|
|
108
|
+
};
|
|
109
|
+
try {
|
|
110
|
+
if (!CONFIG_JSON) {
|
|
111
|
+
logInfo('No CAPACITOR_CONFIG found, using defaults (HLS enabled)');
|
|
112
|
+
return defaultConfig;
|
|
113
|
+
}
|
|
114
|
+
const config = JSON.parse(CONFIG_JSON);
|
|
115
|
+
const nativeAudioConfig = config.plugins?.NativeAudio || {};
|
|
116
|
+
return {
|
|
117
|
+
hls: nativeAudioConfig.hls !== false, // Default to true unless explicitly set to false
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
logError(`Error parsing config: ${error.message}`);
|
|
122
|
+
return defaultConfig;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Log the current configuration status
|
|
127
|
+
*/
|
|
128
|
+
function logConfig(config) {
|
|
129
|
+
log('\nNativeAudio configuration:', '', colors.bright);
|
|
130
|
+
if (config.hls) {
|
|
131
|
+
console.log(` ${colors.green}✔${colors.reset} ${colors.bright}HLS (m3u8)${colors.reset}: ${colors.green}enabled${colors.reset} (includes media3-exoplayer-hls, adds ~4MB to APK)`);
|
|
132
|
+
}
|
|
133
|
+
else {
|
|
134
|
+
console.log(` ${colors.yellow}○${colors.reset} ${colors.bright}HLS (m3u8)${colors.reset}: ${colors.yellow}disabled${colors.reset} (reduces APK size by ~4MB)`);
|
|
135
|
+
}
|
|
136
|
+
console.log('');
|
|
137
|
+
}
|
|
138
|
+
// ============================================================================
|
|
139
|
+
// Android: Gradle Configuration
|
|
140
|
+
// ============================================================================
|
|
141
|
+
/**
|
|
142
|
+
* Write gradle.properties file for Android
|
|
143
|
+
* Injects NativeAudio properties while preserving existing content
|
|
144
|
+
*/
|
|
145
|
+
function configureAndroid(config) {
|
|
146
|
+
logInfo('Configuring Android dependencies...');
|
|
147
|
+
try {
|
|
148
|
+
// Read existing gradle.properties if it exists
|
|
149
|
+
let existingContent = '';
|
|
150
|
+
if (fs.existsSync(gradlePropertiesPath)) {
|
|
151
|
+
existingContent = fs.readFileSync(gradlePropertiesPath, 'utf8');
|
|
152
|
+
}
|
|
153
|
+
// Remove existing NativeAudio properties (if any)
|
|
154
|
+
const lines = existingContent.split('\n');
|
|
155
|
+
const filteredLines = [];
|
|
156
|
+
let inNativeAudioSection = false;
|
|
157
|
+
let lastWasEmpty = false;
|
|
158
|
+
for (const line of lines) {
|
|
159
|
+
// Check if this is a NativeAudio property or comment
|
|
160
|
+
if (line.trim().startsWith('# NativeAudio') ||
|
|
161
|
+
line.trim().startsWith('nativeAudio.') ||
|
|
162
|
+
line.trim() === '# Generated by NativeAudio hook script') {
|
|
163
|
+
inNativeAudioSection = true;
|
|
164
|
+
continue; // Skip this line
|
|
165
|
+
}
|
|
166
|
+
// If we were in NativeAudio section and hit a non-empty line, we're done
|
|
167
|
+
if (inNativeAudioSection && line.trim() !== '') {
|
|
168
|
+
inNativeAudioSection = false;
|
|
169
|
+
}
|
|
170
|
+
// Add non-NativeAudio lines, but avoid multiple consecutive empty lines
|
|
171
|
+
if (!inNativeAudioSection) {
|
|
172
|
+
if (line.trim() === '') {
|
|
173
|
+
if (!lastWasEmpty) {
|
|
174
|
+
filteredLines.push(line);
|
|
175
|
+
lastWasEmpty = true;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
else {
|
|
179
|
+
filteredLines.push(line);
|
|
180
|
+
lastWasEmpty = false;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
// Build new NativeAudio properties section
|
|
185
|
+
const nativeAudioProperties = [];
|
|
186
|
+
nativeAudioProperties.push('');
|
|
187
|
+
nativeAudioProperties.push('# NativeAudio Optional Dependencies (auto-generated)');
|
|
188
|
+
nativeAudioProperties.push('# Generated by NativeAudio hook script');
|
|
189
|
+
nativeAudioProperties.push(`nativeAudio.hls.include=${config.hls ? 'true' : 'false'}`);
|
|
190
|
+
// Combine: existing content + new NativeAudio properties
|
|
191
|
+
const newContent = filteredLines.join('\n') + '\n' + nativeAudioProperties.join('\n') + '\n';
|
|
192
|
+
fs.writeFileSync(gradlePropertiesPath, newContent, 'utf8');
|
|
193
|
+
logSuccess('Updated gradle.properties');
|
|
194
|
+
}
|
|
195
|
+
catch (error) {
|
|
196
|
+
logError(`Error updating gradle.properties: ${error.message}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// ============================================================================
|
|
200
|
+
// iOS: No Configuration Needed (yet)
|
|
201
|
+
// ============================================================================
|
|
202
|
+
/**
|
|
203
|
+
* iOS platform - HLS is handled natively by AVPlayer
|
|
204
|
+
*/
|
|
205
|
+
function configureIOS() {
|
|
206
|
+
logInfo('iOS uses native AVPlayer for HLS - no additional configuration needed');
|
|
207
|
+
}
|
|
208
|
+
// ============================================================================
|
|
209
|
+
// Web: No Configuration Needed
|
|
210
|
+
// ============================================================================
|
|
211
|
+
/**
|
|
212
|
+
* Web platform doesn't need native dependency configuration
|
|
213
|
+
*/
|
|
214
|
+
function configureWeb() {
|
|
215
|
+
logInfo('Web platform - no native dependency configuration needed');
|
|
216
|
+
}
|
|
217
|
+
// ============================================================================
|
|
218
|
+
// Main Execution
|
|
219
|
+
// ============================================================================
|
|
220
|
+
function main() {
|
|
221
|
+
const config = getConfig();
|
|
222
|
+
switch (PLATFORM) {
|
|
223
|
+
case 'android':
|
|
224
|
+
log('Configuring optional dependencies for NativeAudio', '🔧', colors.cyan);
|
|
225
|
+
logConfig(config);
|
|
226
|
+
configureAndroid(config);
|
|
227
|
+
logSuccess('Configuration complete\n');
|
|
228
|
+
break;
|
|
229
|
+
case 'ios':
|
|
230
|
+
log('Configuring NativeAudio for iOS', '🔧', colors.cyan);
|
|
231
|
+
logConfig(config);
|
|
232
|
+
configureIOS();
|
|
233
|
+
logSuccess('Configuration complete\n');
|
|
234
|
+
break;
|
|
235
|
+
case 'web':
|
|
236
|
+
configureWeb();
|
|
237
|
+
break;
|
|
238
|
+
default:
|
|
239
|
+
// If platform is not specified, configure all platforms (backward compatibility)
|
|
240
|
+
log('Configuring optional dependencies for NativeAudio', '🔧', colors.blue);
|
|
241
|
+
logConfig(config);
|
|
242
|
+
logWarning(`Unknown platform: ${PLATFORM || 'undefined'}, configuring Android`);
|
|
243
|
+
configureAndroid(config);
|
|
244
|
+
logSuccess('Configuration complete\n');
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Run if executed directly
|
|
249
|
+
if (require.main === module) {
|
|
250
|
+
main();
|
|
251
|
+
}
|