@formant/data-sdk 0.0.102 → 0.0.103

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.
@@ -19914,6 +19914,140 @@ class KeyValue {
19914
19914
  }
19915
19915
  }
19916
19916
  }
19917
+ function stringToArrayBuffer(input) {
19918
+ return Uint8Array.from(atob(input), (_) => _.charCodeAt(0));
19919
+ }
19920
+ function fork(_) {
19921
+ return void 0;
19922
+ }
19923
+ function browser() {
19924
+ const { userAgent } = navigator;
19925
+ if (userAgent.includes("Firefox/")) {
19926
+ return "Firefox";
19927
+ } else if (userAgent.includes("Edg/")) {
19928
+ return "Edge";
19929
+ } else if (userAgent.includes("Chrome/")) {
19930
+ return "Chrome";
19931
+ } else if (userAgent.includes("Safari/")) {
19932
+ return "Safari";
19933
+ } else if (userAgent.includes("MSIE/") || userAgent.includes("Trident/")) {
19934
+ return "IE";
19935
+ } else {
19936
+ return "Other";
19937
+ }
19938
+ }
19939
+ const rtcAudioChunkStreamType = "audio-chunk";
19940
+ class AudioPlayer {
19941
+ constructor(device, stream) {
19942
+ __publicField(this, "muted", false);
19943
+ __publicField(this, "hasReceivedData", false);
19944
+ __publicField(this, "audioContext");
19945
+ __publicField(this, "chunks", []);
19946
+ __publicField(this, "isPlaying", false);
19947
+ __publicField(this, "startTime", 0);
19948
+ __publicField(this, "lastChunkOffset", 0);
19949
+ __publicField(this, "bufferSize", 3);
19950
+ __publicField(this, "receive", async (msg) => {
19951
+ var _a;
19952
+ const data = (_a = msg.payload.audioChunk) == null ? void 0 : _a.chunk_data;
19953
+ if (!data) {
19954
+ return;
19955
+ }
19956
+ if (!this.hasReceivedData) {
19957
+ this.hasReceivedData = true;
19958
+ }
19959
+ const { audioContext, muted } = this;
19960
+ if (!audioContext || msg.header.stream.streamType !== rtcAudioChunkStreamType || muted !== false) {
19961
+ return;
19962
+ }
19963
+ const arrayBuffer = stringToArrayBuffer(data);
19964
+ try {
19965
+ await audioContext.decodeAudioData(arrayBuffer.buffer, this.scheduleChunk);
19966
+ } catch (error) {
19967
+ console.warn("Error decoding audio buffer, changing audioWireFormat on agent", { error });
19968
+ this.changeAudioWireFormat("wav");
19969
+ }
19970
+ });
19971
+ __publicField(this, "scheduleChunk", (buffer) => {
19972
+ const { audioContext } = this;
19973
+ if (!audioContext) {
19974
+ return;
19975
+ }
19976
+ if (this.chunks.length > this.bufferSize || this.isPlaying === false) {
19977
+ this.chunks.forEach((c) => {
19978
+ c.stop();
19979
+ });
19980
+ this.isPlaying = false;
19981
+ this.chunks = [];
19982
+ }
19983
+ const chunk = this.createChunk(buffer);
19984
+ if (!chunk) {
19985
+ return;
19986
+ }
19987
+ if (!chunk.buffer) {
19988
+ return;
19989
+ }
19990
+ if (this.isPlaying === false) {
19991
+ this.startTime = audioContext.currentTime;
19992
+ this.lastChunkOffset = 0;
19993
+ this.isPlaying = true;
19994
+ }
19995
+ chunk.start(this.startTime + this.lastChunkOffset, 0, buffer.duration);
19996
+ this.lastChunkOffset += chunk.buffer.duration;
19997
+ this.chunks.push(chunk);
19998
+ });
19999
+ this.device = device;
20000
+ this.stream = stream;
20001
+ this.device.startListeningToRealtimeDataStream(stream);
20002
+ this.device.addRealtimeListener((_peerId, msg) => {
20003
+ this.receive(msg);
20004
+ });
20005
+ if (browser() === "Safari" || browser() === "IE") {
20006
+ this.changeAudioWireFormat("wav");
20007
+ } else {
20008
+ this.changeAudioWireFormat("opus");
20009
+ }
20010
+ const AudioContext = window.AudioContext || window.webkitAudioContext;
20011
+ this.audioContext = new AudioContext();
20012
+ }
20013
+ async play() {
20014
+ var _a, _b;
20015
+ if (((_a = this.audioContext) == null ? void 0 : _a.state) === "suspended") {
20016
+ await ((_b = this.audioContext) == null ? void 0 : _b.resume());
20017
+ }
20018
+ this.muted = false;
20019
+ }
20020
+ async pause() {
20021
+ await this.audioContext.suspend();
20022
+ this.muted = true;
20023
+ }
20024
+ destroy() {
20025
+ this.device.stopListeningToRealtimeDataStream(this.stream);
20026
+ }
20027
+ createChunk(buffer) {
20028
+ const { audioContext } = this;
20029
+ if (!audioContext) {
20030
+ return;
20031
+ }
20032
+ const source = audioContext.createBufferSource();
20033
+ source.buffer = buffer;
20034
+ source.connect(audioContext.destination);
20035
+ source.loop = false;
20036
+ source.onended = (_) => {
20037
+ this.chunks.splice(this.chunks.indexOf(source), 1);
20038
+ if (this.chunks.length === 0) {
20039
+ this.isPlaying = false;
20040
+ }
20041
+ };
20042
+ return source;
20043
+ }
20044
+ changeAudioWireFormat(newFormat) {
20045
+ const { stream } = this;
20046
+ fork((async () => {
20047
+ await this.device.changeStreamAudioType(stream.name, newFormat);
20048
+ })());
20049
+ }
20050
+ }
19917
20051
  const accessLevels = ["viewer", "operator", "administrator"];
19918
20052
  const viewer = "viewer";
19919
20053
  const operator = "operator";
@@ -19968,4 +20102,4 @@ if (moduleName) {
19968
20102
  var IRtcSendConfiguration = dist.exports.IRtcSendConfiguration;
19969
20103
  var IRtcStreamMessage = dist.exports.IRtcStreamMessage;
19970
20104
  var IRtcStreamPayload = dist.exports.IRtcStreamPayload;
19971
- export { App, Authentication, BinaryRequestDataChannel, CaptureStream, DataChannel, Device, Fleet, IRtcSendConfiguration, IRtcStreamMessage, IRtcStreamPayload, KeyValue, Manipulator, PeerDevice, SessionType, TextRequestDataChannel, accessLevels, administrator, aggregateLevels, annotationTypes, eventTypes, healthStatuses, interventionTypes, operator, severities, videoMimeTypes, viewer };
20105
+ export { App, AudioPlayer, Authentication, BinaryRequestDataChannel, CaptureStream, DataChannel, Device, Fleet, IRtcSendConfiguration, IRtcStreamMessage, IRtcStreamPayload, KeyValue, Manipulator, PeerDevice, SessionType, TextRequestDataChannel, accessLevels, administrator, aggregateLevels, annotationTypes, eventTypes, healthStatuses, interventionTypes, operator, severities, videoMimeTypes, viewer };