Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e2ea32c
Switch to event handler's and implement a common join
golgetahir Aug 12, 2025
da731cc
Implement SDK v2 first commit
golgetahir Aug 18, 2025
7be53ea
Imporve docs and rename webrtc client
golgetahir Aug 18, 2025
1844be9
Remove docs from git
golgetahir Aug 18, 2025
810e1e5
Add features to v2 sdk
golgetahir Aug 25, 2025
a5f7117
Extend examples and add docs
golgetahir Aug 25, 2025
05def1d
Improve docs
golgetahir Aug 25, 2025
807b5f0
Remove ready() from end user and use it internally
golgetahir Aug 25, 2025
5e5b7ef
Update docs
golgetahir Aug 25, 2025
f8eee58
Add lint to docs
golgetahir Aug 25, 2025
549c44c
Remove unnecessary function
golgetahir Aug 25, 2025
dd1ce3e
Update docs
golgetahir Aug 25, 2025
864d105
Update readme
golgetahir Aug 25, 2025
e0871af
Update readme
golgetahir Aug 25, 2025
435e91f
Update typeDocs
golgetahir Aug 25, 2025
7000d9e
Add mute/unmute audio to manual test plan
golgetahir Sep 15, 2025
7d1b5e5
Fix typo
golgetahir Sep 15, 2025
c53c460
Separate clients
golgetahir Sep 29, 2025
f159948
Add typedocs
golgetahir Sep 29, 2025
5ea2905
Merge branch 'master' into improve-sdk
golgetahir Nov 6, 2025
3584b1d
Revert changes on the src folder
golgetahir Nov 6, 2025
39ebb06
Add v2 into WAR file and refactor for readability
golgetahir Nov 6, 2025
8090c7f
Merge branch 'master' into improve-sdk
golgetahir Nov 10, 2025
c55d647
Fix publish-v2 cosmetics
golgetahir Dec 19, 2025
05bb92a
Refactor data-only-v2 to look good
golgetahir Dec 19, 2025
58bcd64
handle all new packages in v2
burak-58 Dec 26, 2025
d32cbec
edit rollup rules for a warning
burak-58 Dec 26, 2025
1bd4bc5
fix ci issues
burak-58 Dec 26, 2025
f0a1c30
change dependency version
burak-58 Dec 26, 2025
7ce4aae
revert the changes for ci
burak-58 Dec 26, 2025
56f3370
Merge branch 'master' into improve-sdk
golgetahir Dec 29, 2025
018226d
Fix rollup config for mediapipe
golgetahir Dec 29, 2025
0821d78
Fix rollup warning errors
golgetahir Dec 29, 2025
d33f5f1
Fix npm run compile for rollup
golgetahir Dec 29, 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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ node_modules
/coverage/
/tsbuild
/types
/.vscode
/packages/webrtc-sdk/docs/*
/packages/webrtc-sdk/dist
/packages/webrtc-sdk/docs
35 changes: 34 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,10 @@
"doc": "doc"
},
"scripts": {
"compile": "npm run cleanup:tsbuild && npm run compile:js && npm run compile:ts && copy-files-from-to && npm run cleanup:tsbuild",
"compile": "npm run cleanup:tsbuild && npm run compile:js && npm run compile:ts && npm run compile:webrtc-sdk && copy-files-from-to && npm run cleanup:tsbuild",
"compile:js": "rollup -c rollup.config.module.cjs && rollup -c rollup.config.browser.cjs ",
"compile:ts": "tsc -p ./tsconfig.json && api-extractor run",
"compile:webrtc-sdk": "npm install --prefix packages/webrtc-sdk && npm run build --prefix packages/webrtc-sdk",
"cleanup:tsbuild": "rimraf ./tsbuild",
"test": "karma start karma.conf.cjs",
"codecov": "codecov"
Expand All @@ -28,6 +29,38 @@
{
"from": "./dist/es/*",
"to": "./src/main/webapp/js/"
},
{
"from": "./packages/webrtc-sdk/dist/**/*",
"to": "./src/main/webapp/v2/js/"
},
{
"from": "./packages/webrtc-sdk/examples/*",
"to": "./src/main/webapp/v2/"
},
{
"from": "./src/main/webapp/js/external/**/*",
"to": "./src/main/webapp/v2/js/external/"
},
{
"from": "./src/main/webapp/js/external/**/*",
"to": "./src/main/webapp/v2/js/external/"
},
{
"from": "./src/main/webapp/js/fetch.stream.js",
"to": "./src/main/webapp/v2/js/"
},
{
"from": "./src/main/webapp/js/utility.js",
"to": "./src/main/webapp/v2/js/"
},
{
"from": "./src/main/webapp/js/external/**/*",
"to": "./src/main/webapp/v2/js/external/"
},
{
"from": "./src/main/webapp/css/**/*",
"to": "./src/main/webapp/v2/css/"
}
],
"copyFilesSettings": {
Expand Down
11 changes: 11 additions & 0 deletions packages/webrtc-sdk/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": false,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "lf"
}
229 changes: 229 additions & 0 deletions packages/webrtc-sdk/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
# WebRTC SDK v2 (TypeScript)

Modern, strictly-typed client SDK for Ant Media Server.

## Install

This package is currently private for development. Build locally:

```bash
npm install
npm run build
```

## Quick start

```ts
import { WebRTCClient, getWebSocketURL } from 'webrtc-sdk';

// One-liner session helper (recommended for most apps)
const { client } = await WebRTCClient.createSession({
websocketURL: getWebSocketURL('wss://example.com:5443/LiveApp/websocket'),
role: 'publisher',
streamId: 'stream1',
localVideo: document.getElementById('local') as HTMLVideoElement,
remoteVideo: document.getElementById('remote') as HTMLVideoElement,
mediaConstraints: { audio: true, video: true },
autoPlay: true, // attempt autoplay on the remote element after join
});

client.on('play_started', ({ streamId }) => console.log('playing', streamId));
```



### Common operations

```ts
// Stop a session
await client.stop('stream1');

// Send text over data channel
await client.sendData('stream1', 'hello');

// One-off stats snapshot
const stats = await client.getStats('stream1');
```

## Events

### Events quick reference

Common events emitted by the SDK (see TypeDoc for full list):

- `initialized`: signaling is ready
- `publish_started` / `publish_finished`
- `play_started` / `play_finished`
- `newTrackAvailable` { stream, track, streamId }
- `ice_connection_state_changed` { state, streamId }
- `data_channel_opened` / `data_channel_closed`
- `data_received` { streamId, data: string | ArrayBuffer }
- `updated_stats` PeerStats
- `devices_updated` GroupedDevices
- `room_joined` / `room_left`
- `room_information`, `broadcast_object`, `subscriber_count`, `subscriber_list`
- `video_track_assignments`
- `reconnection_attempt_for_publisher` / `reconnection_attempt_for_player`
- `error` { error, message? }

### Listening to events (v2)

```ts
client.on('initialized', () => console.log('ready'));
client.on('publish_started', ({ streamId }) => console.log('publishing', streamId));
client.on('play_started', ({ streamId }) => console.log('playing', streamId));
client.on('data_received', ({ streamId, data }) => console.log('dc <-', streamId, data));
client.on('ice_connection_state_changed', ({ state, streamId }) => console.log('ice', state, streamId));
client.on('reconnected', ({ streamId }) => console.log('reconnected', streamId));

// AMS server notifications exposed as typed events and also under notification:<name>
client.on('broadcast_object', (obj) => console.log('broadcast_object', obj));
client.on('notification:subscriberCount', (payload) => console.log('subscriberCount', payload));
```

## Documentation

Generated API docs are available in the `docs/` folder. To regenerate:

```bash
npm run docs
```

Open `docs/index.html` in a browser.

### Architecture and usage guidance

`WebRTCClient` is the primary API surface. It composes:

- `WebSocketAdaptor`: handles signaling with Ant Media Server (WS commands, notifications).
- `MediaManager`: handles local media (getUserMedia, device switching, screen share).

For most applications, call methods on `WebRTCClient` only. It exposes the common
operations you need: `join()`, `publish()`, `play()`, `stop()`, `listDevices()`,
`selectVideoInput()`, `selectAudioInput()`, `startScreenShare()`, `stopScreenShare()`,
`sendData()`, `enableStats()/disableStats()`, room/multitrack helpers, and emits typed events.

Note: Methods internally wait for signaling readiness; you don't need to call `ready()` yourself.

Only use `WebSocketAdaptor` or `MediaManager` directly if you have advanced
customization needs (e.g., custom signaling transport or bespoke media capture).
Otherwise, prefer the higher-level `WebRTCClient` methods.

### Room / Multitrack quick start

```ts
// Join a room
await client.joinRoom({ roomId: 'my-room', streamId: 'publisher1' });

// Selectively play only some subtracks of a main stream
await client.playSelective({
streamId: 'mainStreamId',
enableTracks: ['camera_user1', 'screen_user2'],
disableTracksByDefault: true,
});

// Enable/disable a specific subtrack
client.enableTrack('mainStreamId', 'camera_user3', true);

// Force quality (ABR)
client.forceStreamQuality('mainStreamId', 720); // or 'auto'
```

### Device management and screen share

```ts
// Switch devices without renegotiation
await client.selectVideoInput('camera-device-id');
await client.selectAudioInput('mic-device-id');

// Camera on/off keeps sender alive (black dummy track)
await client.turnOffLocalCamera();
await client.turnOnLocalCamera();

// Screen share and overlay (PIP camera)
await client.startScreenShare();
await client.stopScreenShare();
await client.startScreenWithCameraOverlay();
await client.stopScreenWithCameraOverlay();
```

### Data channel

```ts
// Text
await client.sendData('s1', 'hello');
// Binary
await client.sendData('s1', new Uint8Array([1,2,3]).buffer);
// Optional sanitize received strings
client.setSanitizeDataChannelStrings(true);
client.on('data_received', ({ data }) => console.log('rx', data));
```

## Feature examples

### Reconnect configuration

```ts
client.configureReconnect({ backoff: "exp", baseMs: 500, maxMs: 10000, jitter: 0.3 });
client.on("reconnected", ({ streamId }) => console.log("reconnected", streamId));
```

### Device hot-swap and track controls

```ts
client.on("device_hotswapped", e => console.log("hotswapped", e));

// Pause/resume tracks without renegotiation
client.pauseTrack("audio");
client.resumeTrack("audio");
```

### Remote audio level (viewer)

```ts
await client.enableRemoteAudioLevel("s1", level => console.log(level), 200);
client.disableRemoteAudioLevel("s1");
```

### Data-only publish

```ts
const { client } = await WebRTCClient.createSession({
websocketURL: getWebSocketURL('wss://example.com:5443/LiveApp/websocket'),
role: 'publisher',
streamId: 'data-only',
onlyDataChannel: true,
});
await client.sendJSON('data-only', { hello: 'world' });
```

### Stats helpers

```ts
// One-off snapshot and event
const stats = await client.getStats('s1');
client.on('updated_stats', (ps) => console.log(ps));

// Poll every 2s
client.enableStats('s1', 2000);
```

## Troubleshooting

- Autoplay blocked: browsers may block autoplay with sound. Use `autoPlay: true` and call `videoEl.play()` on a user gesture if needed.
- HTTPS required: `getUserMedia` and `getDisplayMedia` need HTTPS (or localhost). Serve examples over HTTPS.
- TURN/ICE: if connections fail across networks, configure proper TURN servers on Ant Media Server and pass `peerConfig.iceServers` if needed.

## Examples

- `examples/publish.html`
- `examples/play.html`
- `examples/room.html` (rooms/multitrack, enable/disable subtracks, force quality, selective play)

## Development

- Lint: `npm run lint` (ESLint)
- Format: Prettier (integrated; run `npm run lint:fix` for quick fixes)
- Tests: `npm test`
- Docs: `npm run docs`

83 changes: 83 additions & 0 deletions packages/webrtc-sdk/documents/Cookbook.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
## WebRTC SDK v2 Cookbook

### 1) Publish/Play with one-liner
```ts
const { client } = await WebRTCClient.createSession({ websocketURL, role: 'publisher', streamId: 's1', localVideo, remoteVideo, mediaConstraints: { audio: true, video: true }, autoPlay: true });
```

### 1b) Event listeners
```ts
client.on('publish_started', ({ streamId }) => console.log('publishing', streamId));
client.on('data_received', ({ data }) => console.log('dc <-', data));

```

### 2) Device switching
```ts
await client.selectVideoInput(cameraId);
await client.selectAudioInput(micId);
```

### 3) Screen share and PIP overlay
```ts
await client.startScreenShare();
// later
await client.stopScreenShare();

await client.startScreenWithCameraOverlay();
await client.stopScreenWithCameraOverlay();
```

### 4) Data channel helpers
```ts
await client.sendData('s1', 'hello');
await client.sendJSON('s1', { type: 'chat', text: 'hi' });
```

### 5) Reconnect policy and events
```ts
client.configureReconnect({ backoff: 'exp', baseMs: 500, maxMs: 10000, jitter: 0.3 });
client.on('reconnected', ({ streamId }) => console.log('reconnected', streamId));
```

### 6) Room / multitrack helpers
```ts
await client.joinRoom({ roomId: 'room1', streamId: 'pub1' });
await client.playSelective({ streamId: 'main', enableTracks: ['camera_u1'], disableTracksByDefault: true });
client.enableTrack('main', 'camera_u1', true);
client.forceStreamQuality('main', 720); // or 'auto'
```

### 7) Bandwidth/quality
```ts
await client.changeBandwidth('s1', 600);
await client.changeBandwidth('s1', 'unlimited');
await client.setDegradationPreference('s1', 'maintain-framerate');
```

### 8) Stats
```ts
client.on('updated_stats', ps => console.log(ps));
client.enableStats('s1', 2000);
```

### 9) Audio output (sinkId) and meters
```ts
await client.setAudioOutput(deviceId, remoteVideo);
await client.enableRemoteAudioLevel('s1', level => console.log(level));
```

### 10) Track controls
```ts
client.pauseTrack('audio');
client.resumeTrack('audio');
```

### 11) Data-only publish
```ts
const { client } = await WebRTCClient.createSession({ websocketURL, role: 'publisher', streamId: 'data', onlyDataChannel: true });
await client.sendJSON('data', { ping: true });
```



Loading