@react-native-ohos/audio-toolkit 2.0.4-rc.1 → 2.0.4-rc.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/CHANGELOG.md +2 -136
- package/LICENSE +22 -22
- package/{harmony/audio_toolkit/OAT.xml → OAT.xml} +47 -37
- package/README.md +11 -17
- package/ReactNativeAudioToolkit.podspec +18 -18
- package/harmony/audio_toolkit/build-profile.json5 +7 -7
- package/harmony/audio_toolkit/hvigorfile.ts +1 -1
- package/harmony/audio_toolkit/index.ets +26 -25
- package/harmony/audio_toolkit/oh-package.json5 +12 -12
- package/harmony/audio_toolkit/src/main/cpp/AudioToolkitPackage.h +15 -0
- package/harmony/audio_toolkit/src/main/cpp/CMakeLists.txt +10 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/RNOH/generated/BaseReactNativeAudioToolkitPackage.h +69 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/RNOH/generated/turbo_modules/RCTAudioPlayer.cpp +23 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/RNOH/generated/turbo_modules/RCTAudioPlayer.h +16 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/RNOH/generated/turbo_modules/RCTAudioRecorder.cpp +20 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/RNOH/generated/turbo_modules/RCTAudioRecorder.h +16 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/ComponentDescriptors.h +22 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/EventEmitters.cpp +18 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/EventEmitters.h +19 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/Props.cpp +21 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/Props.h +20 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/ShadowNodes.cpp +19 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/ShadowNodes.h +25 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/States.cpp +18 -0
- package/harmony/audio_toolkit/src/main/cpp/generated/react/renderer/components/react_native_audio_toolkit/States.h +23 -0
- package/harmony/audio_toolkit/src/main/ets/{AudioToolkitPackage.ts → AudioToolkitPackage.ets} +51 -50
- package/harmony/audio_toolkit/src/main/ets/Logger.ts +63 -63
- package/harmony/audio_toolkit/src/main/ets/RNCAudioPlayerTurboModule.ts +432 -432
- package/harmony/audio_toolkit/src/main/ets/RNCAudioRecorderTurboModule.ts +260 -260
- package/harmony/audio_toolkit/src/main/ets/generated/components/ts.ts +5 -0
- package/harmony/audio_toolkit/src/main/ets/generated/index.ets +5 -0
- package/harmony/audio_toolkit/src/main/ets/generated/ts.ts +6 -0
- package/harmony/audio_toolkit/src/main/ets/generated/turboModules/RCTAudioPlayer.ts +40 -0
- package/harmony/audio_toolkit/src/main/ets/generated/turboModules/RCTAudioRecorder.ts +24 -0
- package/harmony/audio_toolkit/src/main/ets/generated/turboModules/ts.ts +6 -0
- package/harmony/audio_toolkit/src/main/module.json5 +6 -6
- package/harmony/audio_toolkit/src/main/resources/base/element/string.json +7 -7
- package/harmony/audio_toolkit/src/main/resources/en_US/element/string.json +7 -7
- package/harmony/audio_toolkit/src/main/resources/zh_CN/element/string.json +7 -7
- package/harmony/audio_toolkit/{ts.ts → ts.ets} +25 -25
- package/harmony/audio_toolkit.har +0 -0
- package/package.json +48 -46
- package/src/Player.js +329 -329
- package/src/PlayerModule.ts +51 -51
- package/src/Recorder.js +183 -183
- package/src/RecorderModule.ts +83 -83
- package/src/index.ts +5 -5
- package/harmony/audio_toolkit/BuildProfile.ets +0 -17
- package/harmony/audio_toolkit/LICENSE +0 -21
- package/harmony/audio_toolkit/NOTICE +0 -33
- package/harmony/audio_toolkit/README.OpenSource +0 -11
- package/harmony/audio_toolkit/README.md +0 -230
package/src/Player.js
CHANGED
|
@@ -1,329 +1,329 @@
|
|
|
1
|
-
import { DeviceEventEmitter, NativeAppEventEmitter, Platform } from 'react-native';
|
|
2
|
-
import RCTAudioPlayer from './PlayerModule'
|
|
3
|
-
import async from 'async';
|
|
4
|
-
import EventEmitter from 'eventemitter3';
|
|
5
|
-
import MediaStates from '@react-native-community/audio-toolkit/src/MediaStates';
|
|
6
|
-
// Only import specific items from lodash to keep build size down
|
|
7
|
-
import filter from 'lodash/filter';
|
|
8
|
-
import identity from 'lodash/identity';
|
|
9
|
-
import last from 'lodash/last';
|
|
10
|
-
import noop from 'lodash/noop';
|
|
11
|
-
|
|
12
|
-
let playerId = 0;
|
|
13
|
-
|
|
14
|
-
export const PlaybackCategories = {
|
|
15
|
-
Playback: 1,
|
|
16
|
-
Ambient: 2,
|
|
17
|
-
SoloAmbient: 3,
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const defaultPlayerOptions = {
|
|
21
|
-
autoDestroy: true,
|
|
22
|
-
continuesToPlayInBackground: false,
|
|
23
|
-
category: PlaybackCategories.Playback,
|
|
24
|
-
mixWithOthers: false,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* Represents a media player
|
|
29
|
-
* @constructor
|
|
30
|
-
*/
|
|
31
|
-
class Player extends EventEmitter {
|
|
32
|
-
constructor(path, options = defaultPlayerOptions) {
|
|
33
|
-
super();
|
|
34
|
-
|
|
35
|
-
this._path = path;
|
|
36
|
-
|
|
37
|
-
if (options == null) {
|
|
38
|
-
this._options = defaultPlayerOptions;
|
|
39
|
-
} else {
|
|
40
|
-
// Make sure all required options have values
|
|
41
|
-
if (options.autoDestroy == null)
|
|
42
|
-
options.autoDestroy = defaultPlayerOptions.autoDestroy;
|
|
43
|
-
if (options.continuesToPlayInBackground == null)
|
|
44
|
-
options.continuesToPlayInBackground = defaultPlayerOptions.continuesToPlayInBackground;
|
|
45
|
-
if (options.category == null)
|
|
46
|
-
options.category = defaultPlayerOptions.category;
|
|
47
|
-
if (options.mixWithOthers == null)
|
|
48
|
-
options.mixWithOthers = defaultPlayerOptions.mixWithOthers;
|
|
49
|
-
|
|
50
|
-
this._options = options;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
this._playerId = playerId++;
|
|
54
|
-
this._reset();
|
|
55
|
-
|
|
56
|
-
const appEventEmitter = Platform.OS === 'ios' ? NativeAppEventEmitter : DeviceEventEmitter;
|
|
57
|
-
|
|
58
|
-
appEventEmitter.addListener(`RCTAudioPlayerEvent:${this._playerId}`, (payload: Event) => {
|
|
59
|
-
this._handleEvent(payload.event, payload.data);
|
|
60
|
-
});
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
_reset() {
|
|
64
|
-
this._state = MediaStates.IDLE;
|
|
65
|
-
this._volume = 1.0;
|
|
66
|
-
this._pan = 0.0;
|
|
67
|
-
this._speed = 1.0;
|
|
68
|
-
this._wakeLock = false;
|
|
69
|
-
this._duration = -1;
|
|
70
|
-
this._position = -1;
|
|
71
|
-
this._lastSync = -1;
|
|
72
|
-
this._looping = false;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
_storeInfo(info) {
|
|
76
|
-
if (!info) {
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
this._duration = info.duration;
|
|
81
|
-
this._position = info.position;
|
|
82
|
-
this._lastSync = Date.now();
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
_updateState(err, state, results) {
|
|
86
|
-
this._state = err ? MediaStates.ERROR : state;
|
|
87
|
-
|
|
88
|
-
if (err || !results) {
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Use last truthy value from results array as new media info
|
|
93
|
-
const info = last(filter(results, identity));
|
|
94
|
-
this._storeInfo(info);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
_handleEvent(event, data) {
|
|
98
|
-
switch (event) {
|
|
99
|
-
case 'progress':
|
|
100
|
-
// TODO
|
|
101
|
-
break;
|
|
102
|
-
case 'ended':
|
|
103
|
-
this._updateState(null, MediaStates.PREPARED);
|
|
104
|
-
this._position = -1;
|
|
105
|
-
break;
|
|
106
|
-
case 'info':
|
|
107
|
-
// TODO
|
|
108
|
-
break;
|
|
109
|
-
case 'error':
|
|
110
|
-
this._state = MediaStates.ERROR;
|
|
111
|
-
break;
|
|
112
|
-
case 'pause':
|
|
113
|
-
this._state = MediaStates.PAUSED;
|
|
114
|
-
this._storeInfo(data.info);
|
|
115
|
-
break;
|
|
116
|
-
case 'forcePause':
|
|
117
|
-
this.pause();
|
|
118
|
-
break;
|
|
119
|
-
case 'looped':
|
|
120
|
-
this._position = 0;
|
|
121
|
-
this._lastSync = Date.now();
|
|
122
|
-
break;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
this.emit(event, data);
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
prepare(callback = noop) {
|
|
129
|
-
this._updateState(null, MediaStates.PREPARING);
|
|
130
|
-
|
|
131
|
-
const tasks = [];
|
|
132
|
-
|
|
133
|
-
// Prepare player
|
|
134
|
-
tasks.push((next) => {
|
|
135
|
-
RCTAudioPlayer.prepare(this._playerId, this._path, this._options, next);
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
// Set initial values for player options
|
|
139
|
-
tasks.push((next) => {
|
|
140
|
-
RCTAudioPlayer.set(
|
|
141
|
-
this._playerId,
|
|
142
|
-
{
|
|
143
|
-
volume: this._volume,
|
|
144
|
-
pan: this._pan,
|
|
145
|
-
wakeLock: this._wakeLock,
|
|
146
|
-
looping: this._looping,
|
|
147
|
-
speed: this._speed,
|
|
148
|
-
},
|
|
149
|
-
next,
|
|
150
|
-
);
|
|
151
|
-
});
|
|
152
|
-
|
|
153
|
-
async.series(tasks, (err, results) => {
|
|
154
|
-
this._updateState(err, MediaStates.PREPARED, results);
|
|
155
|
-
callback(err);
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
return this;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
play(callback = noop) {
|
|
162
|
-
const tasks = [];
|
|
163
|
-
// Make sure player is prepared
|
|
164
|
-
if (this._state === MediaStates.IDLE) {
|
|
165
|
-
tasks.push((next) => {
|
|
166
|
-
this.prepare(next);
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
// Start playback
|
|
171
|
-
tasks.push((next) => {
|
|
172
|
-
RCTAudioPlayer.play(this._playerId, next);
|
|
173
|
-
});
|
|
174
|
-
async.series(tasks, (err, results) => {
|
|
175
|
-
this._updateState(err, MediaStates.PLAYING, results);
|
|
176
|
-
callback(err);
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
return this;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
pause(callback = noop) {
|
|
183
|
-
RCTAudioPlayer.pause(this._playerId, (err, results) => {
|
|
184
|
-
// Android emits a pause event on the native side
|
|
185
|
-
if (Platform.OS === 'ios' || Platform.OS === 'harmony') {
|
|
186
|
-
this._updateState(err, MediaStates.PAUSED, [results]);
|
|
187
|
-
}
|
|
188
|
-
callback(err);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
return this;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
playPause(callback = noop) {
|
|
195
|
-
if (this._state === MediaStates.PLAYING) {
|
|
196
|
-
this.pause((err) => {
|
|
197
|
-
callback(err, true);
|
|
198
|
-
});
|
|
199
|
-
} else {
|
|
200
|
-
this.play((err) => {
|
|
201
|
-
callback(err, false);
|
|
202
|
-
});
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
return this;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
stop(callback = noop) {
|
|
209
|
-
RCTAudioPlayer.stop(this._playerId, (err, results) => {
|
|
210
|
-
this._updateState(err, MediaStates.PREPARED);
|
|
211
|
-
this._position = -1;
|
|
212
|
-
callback(err);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
return this;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
destroy(callback = noop) {
|
|
219
|
-
this._reset();
|
|
220
|
-
RCTAudioPlayer.destroy(this._playerId, callback);
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
seek(position = 0, callback = noop) {
|
|
224
|
-
// Store old state, but not if it was already SEEKING
|
|
225
|
-
if (this._state != MediaStates.SEEKING) {
|
|
226
|
-
this._preSeekState = this._state;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
this._updateState(null, MediaStates.SEEKING);
|
|
230
|
-
RCTAudioPlayer.seek(this._playerId, position, (err, results) => {
|
|
231
|
-
if (err && err.err === 'seekfail') {
|
|
232
|
-
// Seek operation was cancelled; ignore
|
|
233
|
-
return;
|
|
234
|
-
}
|
|
235
|
-
this._updateState(err, this._preSeekState, [results]);
|
|
236
|
-
callback(err);
|
|
237
|
-
});
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
_setIfInitialized(options, callback = noop) {
|
|
241
|
-
if (this._state >= MediaStates.PREPARED) {
|
|
242
|
-
RCTAudioPlayer.set(this._playerId, options, callback);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
set volume(value) {
|
|
247
|
-
this._volume = value;
|
|
248
|
-
this._setIfInitialized({ volume: value });
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
set currentTime(value) {
|
|
252
|
-
this.seek(value);
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
set wakeLock(value) {
|
|
256
|
-
this._wakeLock = value;
|
|
257
|
-
this._setIfInitialized({ wakeLock: value });
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
set looping(value) {
|
|
261
|
-
this._looping = value;
|
|
262
|
-
this._setIfInitialized({ looping: value });
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
set speed(value) {
|
|
266
|
-
this._speed = value;
|
|
267
|
-
this._setIfInitialized({ speed: value });
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
get currentTime() {
|
|
271
|
-
// Queue up an async call to get an accurate current time
|
|
272
|
-
RCTAudioPlayer.getCurrentTime(this._playerId, (err, results) => {
|
|
273
|
-
this._storeInfo(results);
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
if (this._position < 0) {
|
|
277
|
-
return -1;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
if (this._state === MediaStates.PLAYING) {
|
|
281
|
-
// Estimate the current time based on the latest info we received
|
|
282
|
-
let pos = this._position + (Date.now() - this._lastSync) * this._speed;
|
|
283
|
-
pos = Math.min(pos, this._duration);
|
|
284
|
-
return pos;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
return this._position;
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
get volume() {
|
|
291
|
-
return this._volume;
|
|
292
|
-
}
|
|
293
|
-
get looping() {
|
|
294
|
-
return this._looping;
|
|
295
|
-
}
|
|
296
|
-
get duration() {
|
|
297
|
-
return this._duration;
|
|
298
|
-
}
|
|
299
|
-
get speed() {
|
|
300
|
-
return this._speed;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
get state() {
|
|
304
|
-
return this._state;
|
|
305
|
-
}
|
|
306
|
-
get canPlay() {
|
|
307
|
-
return this._state >= MediaStates.PREPARED;
|
|
308
|
-
}
|
|
309
|
-
get canStop() {
|
|
310
|
-
return this._state >= MediaStates.PLAYING;
|
|
311
|
-
}
|
|
312
|
-
get canPrepare() {
|
|
313
|
-
return this._state == MediaStates.IDLE;
|
|
314
|
-
}
|
|
315
|
-
get isPlaying() {
|
|
316
|
-
return this._state == MediaStates.PLAYING;
|
|
317
|
-
}
|
|
318
|
-
get isStopped() {
|
|
319
|
-
return this._state <= MediaStates.PREPARED;
|
|
320
|
-
}
|
|
321
|
-
get isPaused() {
|
|
322
|
-
return this._state == MediaStates.PAUSED;
|
|
323
|
-
}
|
|
324
|
-
get isPrepared() {
|
|
325
|
-
return this._state == MediaStates.PREPARED;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
export default Player;
|
|
1
|
+
import { DeviceEventEmitter, NativeAppEventEmitter, Platform } from 'react-native';
|
|
2
|
+
import RCTAudioPlayer from './PlayerModule'
|
|
3
|
+
import async from 'async';
|
|
4
|
+
import EventEmitter from 'eventemitter3';
|
|
5
|
+
import MediaStates from '@react-native-community/audio-toolkit/src/MediaStates';
|
|
6
|
+
// Only import specific items from lodash to keep build size down
|
|
7
|
+
import filter from 'lodash/filter';
|
|
8
|
+
import identity from 'lodash/identity';
|
|
9
|
+
import last from 'lodash/last';
|
|
10
|
+
import noop from 'lodash/noop';
|
|
11
|
+
|
|
12
|
+
let playerId = 0;
|
|
13
|
+
|
|
14
|
+
export const PlaybackCategories = {
|
|
15
|
+
Playback: 1,
|
|
16
|
+
Ambient: 2,
|
|
17
|
+
SoloAmbient: 3,
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const defaultPlayerOptions = {
|
|
21
|
+
autoDestroy: true,
|
|
22
|
+
continuesToPlayInBackground: false,
|
|
23
|
+
category: PlaybackCategories.Playback,
|
|
24
|
+
mixWithOthers: false,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Represents a media player
|
|
29
|
+
* @constructor
|
|
30
|
+
*/
|
|
31
|
+
class Player extends EventEmitter {
|
|
32
|
+
constructor(path, options = defaultPlayerOptions) {
|
|
33
|
+
super();
|
|
34
|
+
|
|
35
|
+
this._path = path;
|
|
36
|
+
|
|
37
|
+
if (options == null) {
|
|
38
|
+
this._options = defaultPlayerOptions;
|
|
39
|
+
} else {
|
|
40
|
+
// Make sure all required options have values
|
|
41
|
+
if (options.autoDestroy == null)
|
|
42
|
+
options.autoDestroy = defaultPlayerOptions.autoDestroy;
|
|
43
|
+
if (options.continuesToPlayInBackground == null)
|
|
44
|
+
options.continuesToPlayInBackground = defaultPlayerOptions.continuesToPlayInBackground;
|
|
45
|
+
if (options.category == null)
|
|
46
|
+
options.category = defaultPlayerOptions.category;
|
|
47
|
+
if (options.mixWithOthers == null)
|
|
48
|
+
options.mixWithOthers = defaultPlayerOptions.mixWithOthers;
|
|
49
|
+
|
|
50
|
+
this._options = options;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this._playerId = playerId++;
|
|
54
|
+
this._reset();
|
|
55
|
+
|
|
56
|
+
const appEventEmitter = Platform.OS === 'ios' ? NativeAppEventEmitter : DeviceEventEmitter;
|
|
57
|
+
|
|
58
|
+
appEventEmitter.addListener(`RCTAudioPlayerEvent:${this._playerId}`, (payload: Event) => {
|
|
59
|
+
this._handleEvent(payload.event, payload.data);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
_reset() {
|
|
64
|
+
this._state = MediaStates.IDLE;
|
|
65
|
+
this._volume = 1.0;
|
|
66
|
+
this._pan = 0.0;
|
|
67
|
+
this._speed = 1.0;
|
|
68
|
+
this._wakeLock = false;
|
|
69
|
+
this._duration = -1;
|
|
70
|
+
this._position = -1;
|
|
71
|
+
this._lastSync = -1;
|
|
72
|
+
this._looping = false;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
_storeInfo(info) {
|
|
76
|
+
if (!info) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
this._duration = info.duration;
|
|
81
|
+
this._position = info.position;
|
|
82
|
+
this._lastSync = Date.now();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
_updateState(err, state, results) {
|
|
86
|
+
this._state = err ? MediaStates.ERROR : state;
|
|
87
|
+
|
|
88
|
+
if (err || !results) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Use last truthy value from results array as new media info
|
|
93
|
+
const info = last(filter(results, identity));
|
|
94
|
+
this._storeInfo(info);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
_handleEvent(event, data) {
|
|
98
|
+
switch (event) {
|
|
99
|
+
case 'progress':
|
|
100
|
+
// TODO
|
|
101
|
+
break;
|
|
102
|
+
case 'ended':
|
|
103
|
+
this._updateState(null, MediaStates.PREPARED);
|
|
104
|
+
this._position = -1;
|
|
105
|
+
break;
|
|
106
|
+
case 'info':
|
|
107
|
+
// TODO
|
|
108
|
+
break;
|
|
109
|
+
case 'error':
|
|
110
|
+
this._state = MediaStates.ERROR;
|
|
111
|
+
break;
|
|
112
|
+
case 'pause':
|
|
113
|
+
this._state = MediaStates.PAUSED;
|
|
114
|
+
this._storeInfo(data.info);
|
|
115
|
+
break;
|
|
116
|
+
case 'forcePause':
|
|
117
|
+
this.pause();
|
|
118
|
+
break;
|
|
119
|
+
case 'looped':
|
|
120
|
+
this._position = 0;
|
|
121
|
+
this._lastSync = Date.now();
|
|
122
|
+
break;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.emit(event, data);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
prepare(callback = noop) {
|
|
129
|
+
this._updateState(null, MediaStates.PREPARING);
|
|
130
|
+
|
|
131
|
+
const tasks = [];
|
|
132
|
+
|
|
133
|
+
// Prepare player
|
|
134
|
+
tasks.push((next) => {
|
|
135
|
+
RCTAudioPlayer.prepare(this._playerId, this._path, this._options, next);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
// Set initial values for player options
|
|
139
|
+
tasks.push((next) => {
|
|
140
|
+
RCTAudioPlayer.set(
|
|
141
|
+
this._playerId,
|
|
142
|
+
{
|
|
143
|
+
volume: this._volume,
|
|
144
|
+
pan: this._pan,
|
|
145
|
+
wakeLock: this._wakeLock,
|
|
146
|
+
looping: this._looping,
|
|
147
|
+
speed: this._speed,
|
|
148
|
+
},
|
|
149
|
+
next,
|
|
150
|
+
);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
async.series(tasks, (err, results) => {
|
|
154
|
+
this._updateState(err, MediaStates.PREPARED, results);
|
|
155
|
+
callback(err);
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
play(callback = noop) {
|
|
162
|
+
const tasks = [];
|
|
163
|
+
// Make sure player is prepared
|
|
164
|
+
if (this._state === MediaStates.IDLE) {
|
|
165
|
+
tasks.push((next) => {
|
|
166
|
+
this.prepare(next);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
// Start playback
|
|
171
|
+
tasks.push((next) => {
|
|
172
|
+
RCTAudioPlayer.play(this._playerId, next);
|
|
173
|
+
});
|
|
174
|
+
async.series(tasks, (err, results) => {
|
|
175
|
+
this._updateState(err, MediaStates.PLAYING, results);
|
|
176
|
+
callback(err);
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
return this;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
pause(callback = noop) {
|
|
183
|
+
RCTAudioPlayer.pause(this._playerId, (err, results) => {
|
|
184
|
+
// Android emits a pause event on the native side
|
|
185
|
+
if (Platform.OS === 'ios' || Platform.OS === 'harmony') {
|
|
186
|
+
this._updateState(err, MediaStates.PAUSED, [results]);
|
|
187
|
+
}
|
|
188
|
+
callback(err);
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return this;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
playPause(callback = noop) {
|
|
195
|
+
if (this._state === MediaStates.PLAYING) {
|
|
196
|
+
this.pause((err) => {
|
|
197
|
+
callback(err, true);
|
|
198
|
+
});
|
|
199
|
+
} else {
|
|
200
|
+
this.play((err) => {
|
|
201
|
+
callback(err, false);
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return this;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
stop(callback = noop) {
|
|
209
|
+
RCTAudioPlayer.stop(this._playerId, (err, results) => {
|
|
210
|
+
this._updateState(err, MediaStates.PREPARED);
|
|
211
|
+
this._position = -1;
|
|
212
|
+
callback(err);
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
return this;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
destroy(callback = noop) {
|
|
219
|
+
this._reset();
|
|
220
|
+
RCTAudioPlayer.destroy(this._playerId, callback);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
seek(position = 0, callback = noop) {
|
|
224
|
+
// Store old state, but not if it was already SEEKING
|
|
225
|
+
if (this._state != MediaStates.SEEKING) {
|
|
226
|
+
this._preSeekState = this._state;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
this._updateState(null, MediaStates.SEEKING);
|
|
230
|
+
RCTAudioPlayer.seek(this._playerId, position, (err, results) => {
|
|
231
|
+
if (err && err.err === 'seekfail') {
|
|
232
|
+
// Seek operation was cancelled; ignore
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
this._updateState(err, this._preSeekState, [results]);
|
|
236
|
+
callback(err);
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
_setIfInitialized(options, callback = noop) {
|
|
241
|
+
if (this._state >= MediaStates.PREPARED) {
|
|
242
|
+
RCTAudioPlayer.set(this._playerId, options, callback);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
set volume(value) {
|
|
247
|
+
this._volume = value;
|
|
248
|
+
this._setIfInitialized({ volume: value });
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
set currentTime(value) {
|
|
252
|
+
this.seek(value);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
set wakeLock(value) {
|
|
256
|
+
this._wakeLock = value;
|
|
257
|
+
this._setIfInitialized({ wakeLock: value });
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
set looping(value) {
|
|
261
|
+
this._looping = value;
|
|
262
|
+
this._setIfInitialized({ looping: value });
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
set speed(value) {
|
|
266
|
+
this._speed = value;
|
|
267
|
+
this._setIfInitialized({ speed: value });
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
get currentTime() {
|
|
271
|
+
// Queue up an async call to get an accurate current time
|
|
272
|
+
RCTAudioPlayer.getCurrentTime(this._playerId, (err, results) => {
|
|
273
|
+
this._storeInfo(results);
|
|
274
|
+
});
|
|
275
|
+
|
|
276
|
+
if (this._position < 0) {
|
|
277
|
+
return -1;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
if (this._state === MediaStates.PLAYING) {
|
|
281
|
+
// Estimate the current time based on the latest info we received
|
|
282
|
+
let pos = this._position + (Date.now() - this._lastSync) * this._speed;
|
|
283
|
+
pos = Math.min(pos, this._duration);
|
|
284
|
+
return pos;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return this._position;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
get volume() {
|
|
291
|
+
return this._volume;
|
|
292
|
+
}
|
|
293
|
+
get looping() {
|
|
294
|
+
return this._looping;
|
|
295
|
+
}
|
|
296
|
+
get duration() {
|
|
297
|
+
return this._duration;
|
|
298
|
+
}
|
|
299
|
+
get speed() {
|
|
300
|
+
return this._speed;
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
get state() {
|
|
304
|
+
return this._state;
|
|
305
|
+
}
|
|
306
|
+
get canPlay() {
|
|
307
|
+
return this._state >= MediaStates.PREPARED;
|
|
308
|
+
}
|
|
309
|
+
get canStop() {
|
|
310
|
+
return this._state >= MediaStates.PLAYING;
|
|
311
|
+
}
|
|
312
|
+
get canPrepare() {
|
|
313
|
+
return this._state == MediaStates.IDLE;
|
|
314
|
+
}
|
|
315
|
+
get isPlaying() {
|
|
316
|
+
return this._state == MediaStates.PLAYING;
|
|
317
|
+
}
|
|
318
|
+
get isStopped() {
|
|
319
|
+
return this._state <= MediaStates.PREPARED;
|
|
320
|
+
}
|
|
321
|
+
get isPaused() {
|
|
322
|
+
return this._state == MediaStates.PAUSED;
|
|
323
|
+
}
|
|
324
|
+
get isPrepared() {
|
|
325
|
+
return this._state == MediaStates.PREPARED;
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
export default Player;
|