简体中文 | English
A reference sample for cloud-streamed Web applications that communicate with the end-user client over a runtime-injected JavaScript bridge— including bidirectional text messaging and shared microphone PCM audio.
Live demo page: index.html
| Capability | Description |
|---|---|
| Bidirectional text | Register on_message to receive client messages; call dlcaSend() to push text back to the client |
| Shared microphone | Receive client mic audio as PCM via on_mic_pcm (s16le, interleaved) |
| Connection status | Shows when the cloud-streaming bridge is ready |
| Mic capture detection | Detects whether the client has started sharing the microphone (15s timeout) |
| Live stats | Format, sample rate, channels, packet count, bytes, volume level, rolling buffer duration |
| Visualization | Volume meter and waveform (no real-time playback by default) |
| Playback buffer | Play last 10 seconds — merges cached PCM and plays through Web Audio |
Use this sample as a starting point for voice interaction, in-app notifications, game chat, ASR pipelines, or any workflow that needs client ↔ cloud Web app data exchange.
Client <————————————————> Cloud streaming service <————————————————> Web app
Data channel dlcaReg / dlcaSend
- Client → app:
on_messagecallback - App → client:
dlcaSend(text)
Client microphone
|
v (client enables "share microphone")
Cloud streaming service
|
v
Web app on_mic_pcm callback
Audio is captured on the client. The streamed Web app only receives PCM and decides how to use it (playback, recognition, upload, etc.).
Add dlcaReg handlers to your page (see the integration section in index.html or the minimal template below).
- Host your Web content at a reachable URL
- Set the app entry URL in the cloud streaming admin console
- Under Advanced settings, enable Communication plugin and Microphone component
- Use HTTPS — default port 8086
- URLs copied from the admin console are often
http; change them tohttps://host:8086/... - When the page opens, allow microphone access
- Start a cloud streaming session — the demo page should show Cloud streaming bridge ready
- Allow the microphone and speak — packet count increases, waveform and volume bar react
- Click Send test message to client — the client should receive the text
- Click Play last 10 seconds — hear the cached PCM buffer
Opening the HTML file directly in a normal browser will not expose
dlcaReg/dlcaSend. Access the page through a cloud streaming session, or guard withtypeof dlcaReg === 'function'.
The platform injects two global functions into your streamed Web app:
| Function | Purpose |
|---|---|
dlcaReg(type, callback) |
Register callbacks for client → app data |
dlcaSend(text) |
Send text from the app to the client |
App entry URL and streaming parameters are configured in the admin console — do not hard-code them in the page.
Register a callback. Registering the same type again replaces the previous handler.
| Parameter | Type | Description |
|---|---|---|
type |
string |
Callback type (see table below) |
callback |
function |
Handler invoked when data arrives |
Supported type values
| type | Direction | Description |
|---|---|---|
"on_message" |
Client → app | Text messages |
"on_mic_pcm" |
Client mic → app | PCM audio frames |
Example
dlcaReg('on_message', (text) => {
console.log('Message from client:', text);
});
dlcaReg('on_mic_pcm', (pcmBuffer, sampleRate, channelCount, sampleCount) => {
const pcm = new Int16Array(pcmBuffer);
// Process PCM...
});Register early in page load. Messages that arrive before registration are dropped.
Send a text message from the Web app to the control client in the current session.
| Parameter | Type | Description |
|---|---|---|
text |
string |
Plain text or JSON string |
Returns: boolean — true if sent successfully.
Example
dlcaSend(JSON.stringify({ event: 'scene_ready', level: 1 }));Prerequisites
- Communication plugin and Microphone component enabled in admin advanced settings
- Client accessed via
https://host:8086/... - Microphone permission granted in the browser
dlcaReg('on_message', (text) => {
// text: string
});| Parameter | Type | Description |
|---|---|---|
text |
string |
Text from the client |
dlcaReg('on_mic_pcm', (pcmBuffer, sampleRate, channelCount, sampleCount) => {
// pcmBuffer: ArrayBuffer
// sampleRate: e.g. 48000
// channelCount: 1 or 2
// sampleCount: total samples (= frames × channels)
});| Parameter | Type | Description |
|---|---|---|
pcmBuffer |
ArrayBuffer |
Raw PCM bytes |
sampleRate |
number |
Sample rate (Hz) |
channelCount |
number |
Number of channels |
sampleCount |
number |
Total sample count |
PCM format
| Property | Value |
|---|---|
| Encoding | Signed 16-bit little-endian (s16le) |
| Layout | Interleaved — stereo is L0 R0 L1 R1 ... |
| Byte length | sampleCount × 2 |
| Frames per channel | sampleCount / channelCount |
Read channels
dlcaReg('on_mic_pcm', (pcmBuffer, sampleRate, channelCount, sampleCount) => {
const int16 = new Int16Array(pcmBuffer);
const frames = sampleCount / channelCount;
for (let i = 0; i < frames; i++) {
const left = int16[i * channelCount + 0];
const right = channelCount > 1 ? int16[i * channelCount + 1] : left;
// Your logic...
}
});Play with Web Audio
function playPcm(pcmBuffer, sampleRate, channelCount, sampleCount) {
if (sampleCount <= 0) sampleCount = pcmBuffer.byteLength / 2;
const int16 = new Int16Array(pcmBuffer);
const frames = sampleCount / channelCount;
const ctx = new AudioContext({ sampleRate });
const buffer = ctx.createBuffer(channelCount, frames, sampleRate);
for (let ch = 0; ch < channelCount; ch++) {
const data = buffer.getChannelData(ch);
for (let i = 0; i < frames; i++) {
data[i] = int16[i * channelCount + ch] / 32768;
}
}
const source = ctx.createBufferSource();
source.buffer = buffer;
source.connect(ctx.destination);
source.start();
}<script>
(function () {
function init() {
if (typeof dlcaReg !== 'function') return false;
dlcaReg('on_message', (text) => {
console.log('[message]', text);
});
dlcaReg('on_mic_pcm', (pcmBuffer, sampleRate, channelCount, sampleCount) => {
const pcm = new Int16Array(pcmBuffer);
// Feed your audio pipeline
});
return true;
}
if (!init()) {
const timer = setInterval(() => init() && clearInterval(timer), 500);
}
})();
</script>- Register early — call
dlcaRegas soon as possible, ideally at the top of your page script. - Local preview — bridge APIs are unavailable when opening HTML locally; this is expected.
- Structured data —
dlcaSendis text-only; useJSON.stringify/JSON.parsefor objects. - Visualization vs. playback — the demo uses meters and waveforms; playback or ASR is up to your app.
- Streaming callbacks —
on_mic_pcmfires per audio packet; buffer, schedule, or resample as needed. - HTTPS + mic — configure the entry URL in the admin console; clients should use HTTPS (port 8086) and grant mic permission.
| File | Description |
|---|---|
preview.png |
Screenshot of the running demo |
index.html |
Full demo: messaging, mic PCM, stats, volume bar, waveform, 10s playback |
README.md |
This document (English) |
README.zh-CN.md |
简体中文文档 |
