Skip to content

dolit/WebGLAppInteractionSample

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 

Repository files navigation

简体中文 | English

Cloud Streaming Web App ↔ Client Communication Demo

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

Demo preview — connection status, mic stats, waveform, and playback


What This Demo Shows

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.


Architecture at a Glance

Text messages

Client  <————————————————>  Cloud streaming service  <————————————————>  Web app
         Data channel                                              dlcaReg / dlcaSend
  • Client → app: on_message callback
  • App → client: dlcaSend(text)

Shared microphone

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.).


Quick Start

1. Integrate the bridge

Add dlcaReg handlers to your page (see the integration section in index.html or the minimal template below).

2. Deploy and configure the admin console

  1. Host your Web content at a reachable URL
  2. Set the app entry URL in the cloud streaming admin console
  3. Under Advanced settings, enable Communication plugin and Microphone component

3. Connect from the client

  • Use HTTPS — default port 8086
  • URLs copied from the admin console are often http; change them to https://host:8086/...
  • When the page opens, allow microphone access

4. Verify the demo

  1. Start a cloud streaming session — the demo page should show Cloud streaming bridge ready
  2. Allow the microphone and speak — packet count increases, waveform and volume bar react
  3. Click Send test message to client — the client should receive the text
  4. 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 with typeof dlcaReg === 'function'.


API Reference

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.

dlcaReg(type, callback)

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.


dlcaSend(text)

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: booleantrue 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

Callback Details

on_message

dlcaReg('on_message', (text) => {
  // text: string
});
Parameter Type Description
text string Text from the client

on_mic_pcm

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();
}

Minimal Integration Template

<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>

Notes

  1. Register early — call dlcaReg as soon as possible, ideally at the top of your page script.
  2. Local preview — bridge APIs are unavailable when opening HTML locally; this is expected.
  3. Structured datadlcaSend is text-only; use JSON.stringify / JSON.parse for objects.
  4. Visualization vs. playback — the demo uses meters and waveforms; playback or ASR is up to your app.
  5. Streaming callbackson_mic_pcm fires per audio packet; buffer, schedule, or resample as needed.
  6. HTTPS + mic — configure the entry URL in the admin console; clients should use HTTPS (port 8086) and grant mic permission.

Files

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 简体中文文档

About

A demo for demonstrating the microphone voice and data channels of WebGL content

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages