@pipecat-ai/daily-transport 1.0.0 → 1.1.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.
@@ -1 +1 @@
1
- {"mappings":";;ASiCA;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iDAAkD,SAAQ,mBAAmB;IAC3E,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;IACE,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;CACpD;AAED,kCAAkC,kBAAkB,GAClD,OAAO,CAAC;IACN,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CACrC,CAAC,CAAC;AAoDL,2BAA4B,SAAQ,SAAS;IAE3C,UAAkB,UAAU,EAAE,mBAAmB,CAAC;gBAkBtC,IAAI,GAAE,gCAAqC;IAuBvD,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IA2B9C,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,IAAI;IAoBxC,UAAU,CACf,OAAO,EAAE,oBAAoB,EAC7B,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,GACxC,IAAI;IA8BP,IAAI,eAAe,IAAI,SAAS,CAE/B;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,OAAO,KAAK,KAAK,QAKhB;IAED,cAAc;IAIR,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,cAAc;IAKpB,aAAa,CAAC,SAAS,EAAE,MAAM;IAQ/B,IAAI,eAAe,4CAElB;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAEM,iBAAiB,CAAC,MAAM,EAAE,OAAO;IAQxC,IAAW,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM;IAuCA,OAAO,CAAC,gBAAgB,EAAE,gBAAgB;IAK1C,WAAW;IAgCjB,yBAAyB,CACvB,aAAa,CAAC,EAAE,OAAO,GACtB,gBAAgB,GAAG,SAAS;IAsBzB,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB;IA6BzC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA6FjC,WAAW;IAYV,WAAW,CAAC,OAAO,EAAE,WAAW;CAiLxC","sources":["transports/lib/wavtools/lib/wav_packer.js","transports/lib/wavtools/lib/analysis/constants.js","transports/lib/wavtools/lib/analysis/audio_analysis.js","transports/lib/wavtools/lib/worklets/stream_processor.js","transports/lib/wavtools/lib/wav_stream_player.js","transports/lib/wavtools/lib/worklets/audio_processor.js","transports/lib/wavtools/lib/wav_recorder.js","transports/lib/wavtools/lib/mediastream_recorder.js","transports/lib/wavtools/index.js","transports/daily/src/src/transport.ts","transports/daily/src/src/index.ts","transports/daily/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,"export * from \"./transport\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
1
+ {"mappings":";;ASsCA;IACE,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,iDAAkD,SAAQ,mBAAmB;IAC3E,6BAA6B,CAAC,EAAE,OAAO,CAAC;CACzC;AAED;IACE,uBAAuB,4BAA4B;IACnD,uBAAuB,4BAA4B;CACpD;AAED,kCAAkC,kBAAkB,GAClD,OAAO,CAAC;IACN,uBAAuB,EAAE,MAAM,IAAI,CAAC;IACpC,uBAAuB,EAAE,MAAM,IAAI,CAAC;CACrC,CAAC,CAAC;AAoDL,2BAA4B,SAAQ,SAAS;IAE3C,UAAkB,UAAU,EAAE,mBAAmB,CAAC;gBAkBtC,IAAI,GAAE,gCAAqC;IAuBvD,qBAAqB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI;IA2B9C,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,IAAI;IAoBxC,UAAU,CACf,OAAO,EAAE,oBAAoB,EAC7B,cAAc,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,GACxC,IAAI;IA8BP,IAAI,eAAe,IAAI,SAAS,CAE/B;IAED,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,OAAO,KAAK,KAAK,QAKhB;IAED,cAAc;IAIR,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,UAAU;IAKhB,SAAS,CAAC,KAAK,EAAE,MAAM;IAUvB,IAAI,WAAW,4CAEd;IAEK,cAAc;IAKpB,aAAa,CAAC,SAAS,EAAE,MAAM;IAa/B,IAAI,eAAe,4CAElB;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAED,SAAS,CAAC,MAAM,EAAE,OAAO;IAIzB,IAAI,YAAY,YAEf;IAEM,iBAAiB,CAAC,MAAM,EAAE,OAAO;IAQxC,IAAW,eAAe,IAAI,OAAO,CAEpC;IAED,MAAM;IAuCA,OAAO,CAAC,gBAAgB,EAAE,gBAAgB;IAK1C,WAAW;IAgCjB,yBAAyB,CACvB,aAAa,CAAC,EAAE,OAAO,GACtB,gBAAgB,GAAG,SAAS;IAsBzB,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB;IA6BzC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IA8FjC,WAAW;IAYV,WAAW,CAAC,OAAO,EAAE,WAAW;CA8OxC","sources":["transports/lib/wavtools/lib/wav_packer.js","transports/lib/wavtools/lib/analysis/constants.js","transports/lib/wavtools/lib/analysis/audio_analysis.js","transports/lib/wavtools/lib/worklets/stream_processor.js","transports/lib/wavtools/lib/wav_stream_player.js","transports/lib/wavtools/lib/worklets/audio_processor.js","transports/lib/wavtools/lib/wav_recorder.js","transports/lib/wavtools/lib/mediastream_recorder.js","transports/lib/wavtools/index.js","transports/daily/src/src/transport.ts","transports/daily/src/src/index.ts","transports/daily/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,"export * from \"./transport\";\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/dist/index.js CHANGED
@@ -801,6 +801,7 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
801
801
  this.outputToSpeakers = outputToSpeakers;
802
802
  this.debug = !!debug;
803
803
  this._deviceChangeCallback = null;
804
+ this._deviceErrorCallback = null;
804
805
  this._devices = [];
805
806
  this.deviceSelection = null;
806
807
  // State variables
@@ -959,21 +960,42 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
959
960
  return true;
960
961
  }
961
962
  /**
963
+ * Provide a callback for if/when device errors occur
964
+ * @param {(({devices: Array<"cam" | "mic">, type: string, error?: Error}) => void) | null} callback
965
+ * @returns {true}
966
+ */ listenForDeviceErrors(callback) {
967
+ this._deviceErrorCallback = callback;
968
+ }
969
+ /**
962
970
  * Manually request permission to use the microphone
963
971
  * @returns {Promise<true>}
964
972
  */ async requestPermission() {
965
973
  const permissionStatus = await navigator.permissions.query({
966
974
  name: 'microphone'
967
975
  });
968
- if (permissionStatus.state === 'denied') window.alert('You must grant microphone access to use this feature.');
969
- else if (permissionStatus.state === 'prompt') try {
976
+ if (permissionStatus.state === 'denied') {
977
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
978
+ devices: [
979
+ "mic"
980
+ ],
981
+ type: "unknown",
982
+ error: new Error("Microphone access denied")
983
+ });
984
+ } else if (permissionStatus.state === 'prompt') try {
970
985
  const stream = await navigator.mediaDevices.getUserMedia({
971
986
  audio: true
972
987
  });
973
988
  const tracks = stream.getTracks();
974
989
  tracks.forEach((track)=>track.stop());
975
990
  } catch (e) {
976
- window.alert('You must grant microphone access to use this feature.');
991
+ console.error("Error accessing microphone.");
992
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
993
+ devices: [
994
+ "mic"
995
+ ],
996
+ type: "unknown",
997
+ error: e
998
+ });
977
999
  }
978
1000
  return true;
979
1001
  }
@@ -1010,7 +1032,16 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
1010
1032
  * @returns {Promise<true>}
1011
1033
  */ async begin(deviceId) {
1012
1034
  if (this.processor) throw new Error(`Already connected: please call .end() to start a new session`);
1013
- if (!navigator.mediaDevices || !('getUserMedia' in navigator.mediaDevices)) throw new Error('Could not request user media');
1035
+ if (!navigator.mediaDevices || !('getUserMedia' in navigator.mediaDevices)) {
1036
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
1037
+ devices: [
1038
+ "mic",
1039
+ "cam"
1040
+ ],
1041
+ type: "undefined-mediadevices"
1042
+ });
1043
+ throw new Error('Could not request user media');
1044
+ }
1014
1045
  deviceId = deviceId ?? this.deviceSelection?.deviceId;
1015
1046
  try {
1016
1047
  const config = {
@@ -1023,6 +1054,13 @@ class $0d471c38435bdab6$export$439b217ca659a877 {
1023
1054
  };
1024
1055
  this.stream = await navigator.mediaDevices.getUserMedia(config);
1025
1056
  } catch (err) {
1057
+ if (this._deviceErrorCallback) this._deviceErrorCallback({
1058
+ devices: [
1059
+ "mic"
1060
+ ],
1061
+ type: "unknown",
1062
+ error: err
1063
+ });
1026
1064
  throw new Error('Could not start media stream');
1027
1065
  }
1028
1066
  this.listDevices().then((devices)=>{
@@ -1444,7 +1482,7 @@ globalThis.WavRecorder = WavRecorder;
1444
1482
 
1445
1483
 
1446
1484
  var $c2e964a535c1120e$exports = {};
1447
- $c2e964a535c1120e$exports = JSON.parse("{\"name\":\"@pipecat-ai/daily-transport\",\"version\":\"1.0.0\",\"license\":\"BSD-2-Clause\",\"main\":\"dist/index.js\",\"module\":\"dist/index.module.js\",\"types\":\"dist/index.d.ts\",\"source\":\"src/index.ts\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/pipecat-ai/pipecat-client-web-transports.git\"},\"files\":[\"dist\",\"package.json\",\"README.md\"],\"scripts\":{\"build\":\"parcel build --no-cache\",\"dev\":\"parcel watch\",\"lint\":\"eslint . --ext ts --report-unused-disable-directives --max-warnings 0\"},\"devDependencies\":{\"@pipecat-ai/client-js\":\"^1.0.0\",\"eslint\":\"9.11.1\",\"eslint-config-prettier\":\"^9.1.0\",\"eslint-plugin-simple-import-sort\":\"^12.1.1\"},\"peerDependencies\":{\"@pipecat-ai/client-js\":\"~1.0.0\"},\"dependencies\":{\"@daily-co/daily-js\":\"^0.77.0\"},\"description\":\"Pipecat Daily Transport Package\",\"author\":\"Daily.co\",\"bugs\":{\"url\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/issues\"},\"homepage\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/blob/main/transports/daily-webrtc/README.md\"}");
1485
+ $c2e964a535c1120e$exports = JSON.parse("{\"name\":\"@pipecat-ai/daily-transport\",\"version\":\"1.1.0\",\"license\":\"BSD-2-Clause\",\"main\":\"dist/index.js\",\"module\":\"dist/index.module.js\",\"types\":\"dist/index.d.ts\",\"source\":\"src/index.ts\",\"repository\":{\"type\":\"git\",\"url\":\"git+https://github.com/pipecat-ai/pipecat-client-web-transports.git\"},\"files\":[\"dist\",\"package.json\",\"README.md\"],\"scripts\":{\"build\":\"parcel build --no-cache\",\"dev\":\"parcel watch\",\"lint\":\"eslint . --ext ts --report-unused-disable-directives --max-warnings 0\"},\"devDependencies\":{\"@pipecat-ai/client-js\":\"^1.1.0\",\"eslint\":\"9.11.1\",\"eslint-config-prettier\":\"^9.1.0\",\"eslint-plugin-simple-import-sort\":\"^12.1.1\"},\"peerDependencies\":{\"@pipecat-ai/client-js\":\"~1.1.0\"},\"dependencies\":{\"@daily-co/daily-js\":\"^0.77.0\"},\"description\":\"Pipecat Daily Transport Package\",\"author\":\"Daily.co\",\"bugs\":{\"url\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/issues\"},\"homepage\":\"https://github.com/pipecat-ai/pipecat-client-web-transports/blob/main/transports/daily-webrtc/README.md\"}");
1448
1486
 
1449
1487
 
1450
1488
  var $28bdeb35415d61e8$export$ef180de88fd317cc;
@@ -1616,6 +1654,10 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1616
1654
  outputDeviceId: speakerId
1617
1655
  }).then((infos)=>{
1618
1656
  this._selectedSpeaker = infos.speaker;
1657
+ }).catch((e)=>{
1658
+ this._callbacks.onDeviceError?.(new (0, $jrPAn$pipecataiclientjs.DeviceError)([
1659
+ "speaker"
1660
+ ], e.type ?? "unknown", e.message));
1619
1661
  });
1620
1662
  }
1621
1663
  get selectedSpeaker() {
@@ -1776,6 +1818,7 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1776
1818
  attachEventListeners() {
1777
1819
  this._daily.on("available-devices-updated", this.handleAvailableDevicesUpdated.bind(this));
1778
1820
  this._daily.on("selected-devices-updated", this.handleSelectedDevicesUpdated.bind(this));
1821
+ this._daily.on("camera-error", this.handleDeviceError.bind(this));
1779
1822
  this._daily.on("track-started", this.handleTrackStarted.bind(this));
1780
1823
  this._daily.on("track-stopped", this.handleTrackStopped.bind(this));
1781
1824
  this._daily.on("participant-joined", this.handleParticipantJoined.bind(this));
@@ -1826,24 +1869,74 @@ class $28bdeb35415d61e8$export$b1ca982aa1e488c1 extends (0, $jrPAn$pipecataiclie
1826
1869
  this._callbacks.onSpeakerUpdated?.(ev.devices.speaker);
1827
1870
  }
1828
1871
  }
1872
+ handleDeviceError(ev) {
1873
+ const generateDeviceError = (error)=>{
1874
+ const devices = [];
1875
+ switch(error.type){
1876
+ case "permissions":
1877
+ error.blockedMedia.forEach((d)=>{
1878
+ devices.push(d === "video" ? "cam" : "mic");
1879
+ });
1880
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg, {
1881
+ blockedBy: error.blockedBy
1882
+ });
1883
+ case "not-found":
1884
+ error.missingMedia.forEach((d)=>{
1885
+ devices.push(d === "video" ? "cam" : "mic");
1886
+ });
1887
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg);
1888
+ case "constraints":
1889
+ error.failedMedia.forEach((d)=>{
1890
+ devices.push(d === "video" ? "cam" : "mic");
1891
+ });
1892
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg, {
1893
+ reason: error.reason
1894
+ });
1895
+ case "cam-in-use":
1896
+ devices.push("cam");
1897
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, "in-use", error.msg);
1898
+ case "mic-in-use":
1899
+ devices.push("mic");
1900
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, "in-use", error.msg);
1901
+ case "cam-mic-in-use":
1902
+ devices.push("cam");
1903
+ devices.push("mic");
1904
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, "in-use", error.msg);
1905
+ case "undefined-mediadevices":
1906
+ case "unknown":
1907
+ default:
1908
+ devices.push("cam");
1909
+ devices.push("mic");
1910
+ return new (0, $jrPAn$pipecataiclientjs.DeviceError)(devices, error.type, error.msg);
1911
+ }
1912
+ };
1913
+ this._callbacks.onDeviceError?.(generateDeviceError(ev.error));
1914
+ }
1829
1915
  async handleLocalAudioTrack(track) {
1830
1916
  if (this.state == "ready" || !this._bufferLocalAudioUntilBotReady) return;
1831
1917
  const status = this._mediaStreamRecorder.getStatus();
1832
1918
  switch(status){
1833
1919
  case "ended":
1834
- await this._mediaStreamRecorder.begin(track);
1835
- await this.startRecording();
1920
+ try {
1921
+ await this._mediaStreamRecorder.begin(track);
1922
+ await this.startRecording();
1923
+ } catch (e) {
1924
+ // void. nothing to do.
1925
+ }
1836
1926
  break;
1837
1927
  case "paused":
1838
1928
  await this.startRecording();
1839
1929
  break;
1840
1930
  case "recording":
1841
1931
  default:
1842
- if (this._currentAudioTrack !== track) {
1932
+ if (this._currentAudioTrack !== track) try {
1843
1933
  await this._mediaStreamRecorder.end();
1844
1934
  await this._mediaStreamRecorder.begin(track);
1845
1935
  await this.startRecording();
1846
- } else (0, $jrPAn$pipecataiclientjs.logger).warn("track-started event received for current track and already recording");
1936
+ } catch (e) {
1937
+ // void. nothing to do.
1938
+ }
1939
+ else (0, $jrPAn$pipecataiclientjs.logger).warn("track-started event received for current track and already recording");
1847
1940
  break;
1848
1941
  }
1849
1942
  this._currentAudioTrack = track;