Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
a817a45
added maxOpusPlaybackRate param
jpsantosbh Mar 8, 2025
1d8c330
Merge branch 'main' into joao/opus_config
jpsantosbh Mar 11, 2025
ff9f615
testing
jpsantosbh Mar 11, 2025
51ab08a
maxaveragebitrate
jpsantosbh Mar 11, 2025
0670610
add PlaybackRate enum
jpsantosbh Mar 12, 2025
950e8df
replace sdp with sdpTransform
jpsantosbh Mar 20, 2025
c65f62d
renaming parameters
jpsantosbh Mar 20, 2025
0941f1d
hardening
jpsantosbh Mar 20, 2025
94623fc
playground changes
jpsantosbh Mar 21, 2025
20bcb3e
Merge branch 'main' into joao/opus_config
jpsantosbh Mar 21, 2025
c7a4220
Merge branch 'main' into joao/opus_config
jpsantosbh Mar 21, 2025
07c55d2
Fix build
jpsantosbh Mar 25, 2025
db83282
cleanup
jpsantosbh Apr 8, 2025
93d1fb0
manual prettier
jpsantosbh Apr 15, 2025
78a1f78
Update internal/playground-js/src/fabric/index.js
jpsantosbh Apr 15, 2025
81a1b4c
Update packages/js/src/fabric/WSClient.ts
jpsantosbh Apr 15, 2025
8e924e0
flexible audio codec params
jpsantosbh May 6, 2025
8d0f26e
Merge remote-tracking branch 'origin/main' into joao/opus_config
jpsantosbh May 6, 2025
035d424
changeset
jpsantosbh May 6, 2025
dc0c11f
Atualizar o index.html
jpsantosbh May 7, 2025
51c5eea
Atualizar o index.html
jpsantosbh May 7, 2025
6e37d34
Atualizar o index.html
jpsantosbh May 7, 2025
00b65d9
Update internal/playground-js/src/fabric/index.html
jpsantosbh May 7, 2025
aad67a7
UI fixes
jpsantosbh May 7, 2025
41817e3
dependencies fix
jpsantosbh May 7, 2025
b8704ad
build fix
jpsantosbh May 7, 2025
255f0cf
formating
jpsantosbh May 7, 2025
37e545d
Update packages/webrtc/src/RTCPeer.ts
jpsantosbh May 7, 2025
a514e78
Update packages/js/src/fabric/interfaces/wsClient.ts
jpsantosbh May 7, 2025
5f99076
fixes
jpsantosbh May 7, 2025
5d5b474
fix
jpsantosbh May 7, 2025
43d5abe
fix test
jpsantosbh May 7, 2025
eb67f33
test fix
jpsantosbh May 7, 2025
b54aa5a
fix sdpMediaOrderHack
jpsantosbh May 7, 2025
4d49452
don't change the remote description
jpsantosbh May 8, 2025
9b38f4a
Merge branch 'main' into joao/opus_config
jpsantosbh May 26, 2025
7e5704c
cleanup
jpsantosbh May 26, 2025
9e7335b
Update audio codec selection and input handling in the demo
jpsantosbh May 26, 2025
a1ec706
Merge branch 'main' into joao/opus_config
jpsantosbh May 29, 2025
88534ea
testing
jpsantosbh Jun 4, 2025
eb4b374
testing
jpsantosbh Jun 4, 2025
aede240
Merge branch 'joao/opus_config' of github.com:signalwire/signalwire-j…
jpsantosbh Jun 4, 2025
97afc46
testing
jpsantosbh Jun 4, 2025
d9f1610
revert
jpsantosbh Jun 4, 2025
bd5996f
Merge main into joao/opus_config and resolve conflicts
jpsantosbh Jun 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/cute-zebras-grin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
'@signalwire/webrtc': minor
'@signalwire/js': minor
---

Added dial params:

- audioCodecs

The new parameter allows developers to select the audio codec to use with the desired configuration
1 change: 0 additions & 1 deletion internal/e2e-js/tests/roomSessionStreamingAPI.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@ test.describe('Room Streaming from REST API', () => {
const STREAM_CHECK_URL = process.env.STREAM_CHECK_URL!
await pageTwo.goto(STREAM_CHECK_URL, { waitUntil: 'domcontentloaded' })
await pageTwo.waitForSelector(`text=${streamName}`, { timeout: 10_000 })

await deleteRoom(roomData.id)
})
})
19 changes: 18 additions & 1 deletion internal/playground-js/src/fabric/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
href="https://signalwire.com/assets/images/favicon.ico"
/>
</head>

<body class="bg-light">
<div class="container">
<div class="row pt-5">
Expand Down Expand Up @@ -104,7 +105,23 @@ <h5>Connect</h5>
</label>
</div>
</div>
<div class="d-grid gap-2">
<div class="card">
<div class="card-body">
<div class="form-group">
<label for="targetCodec">Audio Codec Override</label>
<textarea
type="text"
rows="3"
class="form-control"
id=""
placeholder="opus:maxplaybackrate=8000;maxaveragebitrate=4000\nPCMU:"
onchange="saveInLocalStorage(event)"
></textarea>
</div>
</div>
</div>

<div class="d-grid gap-2 mt-3">
<button
id="btnConnect"
class="btn btn-primary"
Expand Down
16 changes: 14 additions & 2 deletions internal/playground-js/src/fabric/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,20 @@ window.dial = async ({ reattach = false } = {}) => {

const dialer = reattach ? client.reattach : client.dial

const call = await dialer({
const dialOptions = {
nodeId: steeringId,
to: document.getElementById('destination').value,
rootElement: document.getElementById('rootElement'),
fromFabricAddressId: document.getElementById('fromFabricAddressId').value,
video: document.getElementById('video').checked,
audio: document.getElementById('audio').checked,
})
}

if (document.getElementById('audioCodec').value.trim().length) {
const userInput = document.getElementById('audioCodec').value.trim()
dialOptions.audioCodecs = userInput.split('\n').map((codec) => codec.trim())
}
const call = await dialer(dialOptions)

window.__call = call
roomObj = call
Expand Down Expand Up @@ -910,6 +916,12 @@ window.ready(async function () {
document.getElementById('audio').checked = true
document.getElementById('video').checked =
localStorage.getItem('fabric.ws.video') === 'true'
document.getElementById('targetCodec').value =
localStorage.getItem('fabric.ws.targetCodec') || ''
document.getElementById('maxPlaybackRate').value =
localStorage.getItem('fabric.ws.maxPlaybackRate') || ''
document.getElementById('maxAverageBitrate').value =
localStorage.getItem('fabric.ws.maxAverageBitrate') || ''

const urlParams = new URLSearchParams(window.location.search)
const room = urlParams.get('room')
Expand Down
53 changes: 33 additions & 20 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions packages/core/src/types/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,3 +147,11 @@ export type Promisify<T> = {
export type Prettify<T> = NonNullable<unknown> & {
[K in keyof T]: Prettify<T[K]>
} & {}

export type AudioCodecOptions =
| `opus:${string}`
| `red:${string}`
| `G722:${string}`
| `PCMU:${string}`
| `PCMA:${string}`
| `telephone-event:${string}`
2 changes: 2 additions & 0 deletions packages/js/src/fabric/WSClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export class WSClient extends BaseClient<{}> implements WSClientContract {
disableUdpIceServers: params.disableUdpIceServers || false,
userVariables: params.userVariables || this.wsClientOptions.userVariables,
fromFabricAddressId: params.fromFabricAddressId,
audioCodecs: params.audioCodecs,
})

// WebRTC connection left the room.
Expand Down Expand Up @@ -232,6 +233,7 @@ export class WSClient extends BaseClient<{}> implements WSClientContract {
prevCallId: payload.callID,
disableUdpIceServers: params.disableUdpIceServers || false,
userVariables: params.userVariables || this.wsClientOptions.userVariables,
audioCodecs: params.audioCodecs
})

// WebRTC connection left the room.
Expand Down
8 changes: 7 additions & 1 deletion packages/js/src/fabric/interfaces/wsClient.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import { SessionOptions, UserOptions } from '@signalwire/core'
import {
AudioCodecOptions,
SessionOptions,
UserOptions,
} from '@signalwire/core'
import {
IncomingCallHandler,
IncomingCallHandlers,
Expand Down Expand Up @@ -117,6 +121,8 @@ export interface CallParams extends DefaultCallParams {
stopMicrophoneWhileMuted?: boolean
/** Fabric address ID matching one of the subscriber’s addresses to attribute conversation API events in the INVITE. */
fromFabricAddressId?: string
/** Audio codec with fmtp params */
audioCodecs?: AudioCodecOptions[]
}

export interface DialParams extends CallParams {
Expand Down
7 changes: 5 additions & 2 deletions packages/webrtc/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,10 @@
},
"dependencies": {
"@signalwire/core": "4.3.0-dev.202506111650.ad2f5be.0",
"sdp": "^3.2.0"
"sdp-transform": "2.15.0"
},
"types": "dist/cjs/webrtc/src/index.d.ts"
"types": "dist/cjs/webrtc/src/index.d.ts",
"devDependencies": {
"@types/sdp-transform": "^2.4.9"
}
}
28 changes: 20 additions & 8 deletions packages/webrtc/src/RTCPeer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ import {
filterIceServers,
} from './utils/helpers'
import {
sdpStereoHack,
sdpBitrateHack,
sdpMediaOrderHack,
sdpHasValidCandidates,
useAudioCodecs,
sdpStereoHack,
} from './utils/sdpHelpers'
import { BaseConnection } from './BaseConnection'
import {
Expand Down Expand Up @@ -71,6 +72,8 @@ export default class RTCPeer<EventTypes extends EventEmitter.ValidEventTypes> {
this.options
)

this._validateOptions()

this._onIce = this._onIce.bind(this)
this._onEndedTrackHandler = this._onEndedTrackHandler.bind(this)

Expand All @@ -86,6 +89,16 @@ export default class RTCPeer<EventTypes extends EventEmitter.ValidEventTypes> {
this.rtcConfigPolyfill = this.config
}

private _validateOptions() {
if (
this.options.useStereo === true &&
typeof this.options.audio === 'object' &&
(this.options.audio.channelCount ?? 2) !== 2
) {
throw new Error('Mismatch params: useStereo, audio.channelCount')
}
}

get options() {
return this.call.options
}
Expand Down Expand Up @@ -820,6 +833,7 @@ export default class RTCPeer<EventTypes extends EventEmitter.ValidEventTypes> {
googleMaxBitrate,
googleMinBitrate,
googleStartBitrate,
audioCodecs,
} = this.options
if (localDescription.sdp && useStereo) {
localDescription.sdp = sdpStereoHack(localDescription.sdp)
Expand All @@ -837,17 +851,15 @@ export default class RTCPeer<EventTypes extends EventEmitter.ValidEventTypes> {
googleStartBitrate
)
}
// this.logger.debug(
// 'LOCAL SDP \n',
// `Type: ${localDescription.type}`,
// '\n\n',
// localDescription.sdp
// )
if (localDescription.sdp && audioCodecs) {
localDescription.sdp = useAudioCodecs(localDescription.sdp, audioCodecs)
}
return this.instance.setLocalDescription(localDescription)
}

private _setRemoteDescription(remoteDescription: RTCSessionDescriptionInit) {
if (remoteDescription.sdp && this.options.useStereo) {
const { useStereo } = this.options
if (remoteDescription.sdp && useStereo) {
remoteDescription.sdp = sdpStereoHack(remoteDescription.sdp)
}
if (remoteDescription.sdp && this.instance.localDescription) {
Expand Down
Loading
Loading