@absolutejs/voice 0.0.22-beta.322 → 0.0.22-beta.323
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/dist/angular/index.js +164 -0
- package/dist/client/index.js +164 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +730 -437
- package/dist/react/index.js +164 -0
- package/dist/svelte/index.js +164 -0
- package/dist/telephonyMediaRoutes.d.ts +63 -0
- package/dist/testing/index.js +177 -13
- package/dist/vue/index.js +164 -0
- package/package.json +2 -2
package/dist/vue/index.js
CHANGED
|
@@ -4768,6 +4768,63 @@ var stringStat = (stat, key) => {
|
|
|
4768
4768
|
};
|
|
4769
4769
|
var statKey = (stat) => String(stat.id ?? stringStat(stat, "ssrc") ?? numericStat(stat, "ssrc") ?? stringStat(stat, "trackIdentifier") ?? stringStat(stat, "mid") ?? "unknown");
|
|
4770
4770
|
var secondsToMs = (value) => value === undefined ? undefined : value * 1000;
|
|
4771
|
+
var DEFAULT_TELEPHONY_FORMAT = {
|
|
4772
|
+
channels: 1,
|
|
4773
|
+
container: "raw",
|
|
4774
|
+
encoding: "mulaw",
|
|
4775
|
+
sampleRateHz: 8000
|
|
4776
|
+
};
|
|
4777
|
+
var bytesToBase64 = (audio) => {
|
|
4778
|
+
const bytes = audio instanceof ArrayBuffer ? new Uint8Array(audio) : new Uint8Array(audio.buffer, audio.byteOffset, audio.byteLength);
|
|
4779
|
+
return Buffer.from(bytes).toString("base64");
|
|
4780
|
+
};
|
|
4781
|
+
var base64ToBytes = (value) => new Uint8Array(Buffer.from(value, "base64"));
|
|
4782
|
+
var unknownRecord = (value) => value && typeof value === "object" ? value : {};
|
|
4783
|
+
var firstString = (records, keys) => {
|
|
4784
|
+
for (const record of records) {
|
|
4785
|
+
for (const key of keys) {
|
|
4786
|
+
const value = record[key];
|
|
4787
|
+
if (typeof value === "string" && value.length > 0) {
|
|
4788
|
+
return value;
|
|
4789
|
+
}
|
|
4790
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
4791
|
+
return String(value);
|
|
4792
|
+
}
|
|
4793
|
+
}
|
|
4794
|
+
}
|
|
4795
|
+
return;
|
|
4796
|
+
};
|
|
4797
|
+
var firstNumber = (records, keys) => {
|
|
4798
|
+
for (const record of records) {
|
|
4799
|
+
for (const key of keys) {
|
|
4800
|
+
const value = record[key];
|
|
4801
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
4802
|
+
return value;
|
|
4803
|
+
}
|
|
4804
|
+
if (typeof value === "string") {
|
|
4805
|
+
const parsed = Number(value);
|
|
4806
|
+
if (Number.isFinite(parsed)) {
|
|
4807
|
+
return parsed;
|
|
4808
|
+
}
|
|
4809
|
+
}
|
|
4810
|
+
}
|
|
4811
|
+
}
|
|
4812
|
+
return;
|
|
4813
|
+
};
|
|
4814
|
+
var telephonyDirection = (track) => {
|
|
4815
|
+
const normalized = track?.toLowerCase();
|
|
4816
|
+
if (!normalized) {
|
|
4817
|
+
return "unknown";
|
|
4818
|
+
}
|
|
4819
|
+
if (normalized.includes("inbound") || normalized.includes("caller") || normalized.includes("in")) {
|
|
4820
|
+
return "inbound";
|
|
4821
|
+
}
|
|
4822
|
+
if (normalized.includes("outbound") || normalized.includes("assistant") || normalized.includes("out")) {
|
|
4823
|
+
return "outbound";
|
|
4824
|
+
}
|
|
4825
|
+
return "unknown";
|
|
4826
|
+
};
|
|
4827
|
+
var telephonyFrameKind = (direction) => direction === "outbound" ? "assistant-audio" : "input-audio";
|
|
4771
4828
|
var normalizeWebRTCStat = (stat) => {
|
|
4772
4829
|
const sample = {};
|
|
4773
4830
|
for (const [key, value] of Object.entries(stat)) {
|
|
@@ -4777,6 +4834,113 @@ var normalizeWebRTCStat = (stat) => {
|
|
|
4777
4834
|
}
|
|
4778
4835
|
return sample;
|
|
4779
4836
|
};
|
|
4837
|
+
var parseTelephonyMediaFrame = (input) => {
|
|
4838
|
+
const envelope = input.envelope;
|
|
4839
|
+
const media = unknownRecord(envelope.media);
|
|
4840
|
+
const payload = firstString([media, envelope], ["payload", "audio", "data"]) ?? firstString([unknownRecord(envelope.message)], ["payload"]);
|
|
4841
|
+
if (!payload) {
|
|
4842
|
+
return;
|
|
4843
|
+
}
|
|
4844
|
+
const carrier = input.carrier ?? firstString([envelope], ["provider"]) ?? "telephony";
|
|
4845
|
+
const streamId = firstString([media, envelope], ["streamSid", "stream_id", "streamId", "streamId", "callSid", "call_id"]);
|
|
4846
|
+
const sequenceNumber = firstString([media, envelope], ["sequenceNumber", "sequence_number", "chunk"]);
|
|
4847
|
+
const track = firstString([media, envelope], ["track", "direction"]);
|
|
4848
|
+
const direction = telephonyDirection(track);
|
|
4849
|
+
const timestamp = firstNumber([media, envelope], ["timestamp", "time", "startedAt"]);
|
|
4850
|
+
return {
|
|
4851
|
+
at: timestamp,
|
|
4852
|
+
audio: base64ToBytes(payload),
|
|
4853
|
+
format: input.format ?? DEFAULT_TELEPHONY_FORMAT,
|
|
4854
|
+
id: [
|
|
4855
|
+
carrier,
|
|
4856
|
+
streamId ?? input.sessionId ?? "stream",
|
|
4857
|
+
sequenceNumber ?? timestamp ?? Date.now()
|
|
4858
|
+
].join(":"),
|
|
4859
|
+
kind: telephonyFrameKind(direction),
|
|
4860
|
+
metadata: {
|
|
4861
|
+
carrier,
|
|
4862
|
+
direction,
|
|
4863
|
+
event: firstString([envelope], ["event", "type"]),
|
|
4864
|
+
sequenceNumber,
|
|
4865
|
+
streamId,
|
|
4866
|
+
track
|
|
4867
|
+
},
|
|
4868
|
+
sessionId: input.sessionId ?? streamId,
|
|
4869
|
+
source: "telephony"
|
|
4870
|
+
};
|
|
4871
|
+
};
|
|
4872
|
+
var serializeTelephonyMediaFrame = (input) => {
|
|
4873
|
+
const carrier = input.carrier ?? input.frame.metadata?.carrier ?? "telephony";
|
|
4874
|
+
const streamId = input.streamId ?? (typeof input.frame.metadata?.streamId === "string" ? input.frame.metadata.streamId : input.frame.sessionId);
|
|
4875
|
+
const sequenceNumber = input.sequenceNumber ?? (typeof input.frame.metadata?.sequenceNumber === "string" || typeof input.frame.metadata?.sequenceNumber === "number" ? input.frame.metadata.sequenceNumber : undefined);
|
|
4876
|
+
const direction = input.frame.kind === "assistant-audio" ? "outbound" : "inbound";
|
|
4877
|
+
const payload = input.frame.audio ? bytesToBase64(input.frame.audio) : "";
|
|
4878
|
+
if (carrier === "twilio") {
|
|
4879
|
+
return {
|
|
4880
|
+
event: "media",
|
|
4881
|
+
sequenceNumber,
|
|
4882
|
+
streamSid: streamId,
|
|
4883
|
+
media: {
|
|
4884
|
+
payload,
|
|
4885
|
+
timestamp: input.frame.at,
|
|
4886
|
+
track: direction
|
|
4887
|
+
}
|
|
4888
|
+
};
|
|
4889
|
+
}
|
|
4890
|
+
if (carrier === "telnyx") {
|
|
4891
|
+
return {
|
|
4892
|
+
event: "media",
|
|
4893
|
+
stream_id: streamId,
|
|
4894
|
+
sequence_number: sequenceNumber,
|
|
4895
|
+
media: {
|
|
4896
|
+
payload,
|
|
4897
|
+
timestamp: input.frame.at,
|
|
4898
|
+
track: direction
|
|
4899
|
+
}
|
|
4900
|
+
};
|
|
4901
|
+
}
|
|
4902
|
+
if (carrier === "plivo") {
|
|
4903
|
+
return {
|
|
4904
|
+
event: "media",
|
|
4905
|
+
streamId,
|
|
4906
|
+
sequenceNumber,
|
|
4907
|
+
media: {
|
|
4908
|
+
payload,
|
|
4909
|
+
timestamp: input.frame.at,
|
|
4910
|
+
track: direction
|
|
4911
|
+
}
|
|
4912
|
+
};
|
|
4913
|
+
}
|
|
4914
|
+
return {
|
|
4915
|
+
event: "media",
|
|
4916
|
+
provider: carrier,
|
|
4917
|
+
sequenceNumber,
|
|
4918
|
+
streamId,
|
|
4919
|
+
media: {
|
|
4920
|
+
payload,
|
|
4921
|
+
timestamp: input.frame.at,
|
|
4922
|
+
track: direction
|
|
4923
|
+
}
|
|
4924
|
+
};
|
|
4925
|
+
};
|
|
4926
|
+
var createTelephonyMediaSerializer = (input) => {
|
|
4927
|
+
const format = input.format ?? DEFAULT_TELEPHONY_FORMAT;
|
|
4928
|
+
return {
|
|
4929
|
+
carrier: input.carrier,
|
|
4930
|
+
format,
|
|
4931
|
+
parse: (envelope) => parseTelephonyMediaFrame({
|
|
4932
|
+
carrier: input.carrier,
|
|
4933
|
+
envelope,
|
|
4934
|
+
format,
|
|
4935
|
+
sessionId: input.sessionId ?? input.streamId
|
|
4936
|
+
}),
|
|
4937
|
+
serialize: (frame) => serializeTelephonyMediaFrame({
|
|
4938
|
+
carrier: input.carrier,
|
|
4939
|
+
frame,
|
|
4940
|
+
streamId: input.streamId
|
|
4941
|
+
})
|
|
4942
|
+
};
|
|
4943
|
+
};
|
|
4780
4944
|
var buildMediaResamplingPlan = (input) => {
|
|
4781
4945
|
const required = !formatMatches(input.inputFormat, input.outputFormat);
|
|
4782
4946
|
return {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@absolutejs/voice",
|
|
3
|
-
"version": "0.0.22-beta.
|
|
3
|
+
"version": "0.0.22-beta.323",
|
|
4
4
|
"description": "Voice primitives and Elysia plugin for AbsoluteJS",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -246,7 +246,7 @@
|
|
|
246
246
|
}
|
|
247
247
|
},
|
|
248
248
|
"dependencies": {
|
|
249
|
-
"@absolutejs/media": "0.0.1-beta.
|
|
249
|
+
"@absolutejs/media": "0.0.1-beta.6"
|
|
250
250
|
},
|
|
251
251
|
"devDependencies": {
|
|
252
252
|
"@absolutejs/absolute": "0.19.0-beta.646",
|