@jambonz/mrf 0.1.2 → 0.1.4
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/lib/endpoint.js +30 -8
- package/package.json +1 -1
- package/test/support/mock-server.js +1 -1
package/lib/endpoint.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
const { EventEmitter } = require('events');
|
|
2
|
+
const { randomUUID } = require('crypto');
|
|
2
3
|
const { parseSdp, translatePlayUrl } = require('./utils');
|
|
3
4
|
|
|
4
5
|
// mediajam normalized wire events -> legacy ESL event names the
|
|
@@ -46,13 +47,29 @@ class Endpoint extends EventEmitter {
|
|
|
46
47
|
seekOffset = file.seekOffset;
|
|
47
48
|
file = file.file;
|
|
48
49
|
}
|
|
49
|
-
const
|
|
50
|
-
const
|
|
50
|
+
const files = Array.isArray(file) ? file : [file];
|
|
51
|
+
const urls = files.map(translatePlayUrl);
|
|
52
|
+
/* the client supplies the playId so _pendingPlays is populated BEFORE
|
|
53
|
+
* anything hits the wire — the server's play.start event can arrive in
|
|
54
|
+
* the same tcp chunk as the command response, which processes ahead of
|
|
55
|
+
* the awaiter's microtask; a lookup keyed on the response's playId
|
|
56
|
+
* misses that window (seen live: playback-start without file). */
|
|
57
|
+
const playId = randomUUID();
|
|
58
|
+
const data = { urls, playId };
|
|
51
59
|
if (seekOffset > 0) data.seekOffset = parseInt(seekOffset, 10);
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
60
|
+
const result = new Promise((resolve, reject) => {
|
|
61
|
+
// file (the caller's original, untranslated path) rides on the
|
|
62
|
+
// playback-start/stop events: FS parity — the say/play tasks match
|
|
63
|
+
// events to plays by evt.file when there is no tts playback id
|
|
64
|
+
this._pendingPlays.set(playId, { resolve, reject, file: files[0] });
|
|
55
65
|
});
|
|
66
|
+
try {
|
|
67
|
+
await this._request('play.start', data);
|
|
68
|
+
} catch (err) {
|
|
69
|
+
this._pendingPlays.delete(playId);
|
|
70
|
+
throw err;
|
|
71
|
+
}
|
|
72
|
+
return result;
|
|
56
73
|
}
|
|
57
74
|
|
|
58
75
|
/** fsmrf api() passthrough: translate the FS api commands in use. */
|
|
@@ -457,9 +474,12 @@ class Endpoint extends EventEmitter {
|
|
|
457
474
|
case 'dtmf':
|
|
458
475
|
this.emit('dtmf', { dtmf: data.digit, duration: data.durationMs, source: data.source });
|
|
459
476
|
break;
|
|
460
|
-
case 'play.start':
|
|
461
|
-
|
|
477
|
+
case 'play.start': {
|
|
478
|
+
const file = this._pendingPlays.get(data.playId)?.file;
|
|
479
|
+
this.emit('playback-start',
|
|
480
|
+
{ playId: data.playId, ...(file && {file}), ...ttsVars(data.tts) });
|
|
462
481
|
break;
|
|
482
|
+
}
|
|
463
483
|
case 'play.done': {
|
|
464
484
|
const p = this._pendingPlays.get(data.playId);
|
|
465
485
|
if (p) {
|
|
@@ -475,7 +495,9 @@ class Endpoint extends EventEmitter {
|
|
|
475
495
|
playbackLastOffsetPos: data.lastOffsetPos ?? 0
|
|
476
496
|
});
|
|
477
497
|
}
|
|
478
|
-
this.emit('playback-stop',
|
|
498
|
+
this.emit('playback-stop',
|
|
499
|
+
{ playId: data.playId, reason: data.reason, ...(p?.file && {file: p.file}),
|
|
500
|
+
...ttsVars(data.tts) });
|
|
479
501
|
break;
|
|
480
502
|
}
|
|
481
503
|
default: {
|
package/package.json
CHANGED
|
@@ -97,7 +97,7 @@ class MockMediajam {
|
|
|
97
97
|
case 'play.start': {
|
|
98
98
|
const ep = this.endpoints.get(frame.ep);
|
|
99
99
|
if (!ep) return fail('unknown_endpoint', frame.ep);
|
|
100
|
-
const playId = randomUUID().slice(0, 8);
|
|
100
|
+
const playId = frame.data?.playId || randomUUID().slice(0, 8);
|
|
101
101
|
res({ playId });
|
|
102
102
|
this.send(socket, { t: 'evt', ep: frame.ep, evt: 'play.start', data: { playId } });
|
|
103
103
|
const t = setTimeout(() => {
|