View a markdown version of this page

Integrasikan aplikasi web Anda dengan pengalihan WebRTC - Amazon WorkSpaces

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

Integrasikan aplikasi web Anda dengan pengalihan WebRTC

Pengalihan WebRTC memungkinkan aplikasi web yang berjalan di dalam WorkSpaces sesi untuk menggunakan perangkat audio sisi klien asli. Topik ini menunjukkan kepada pengembang aplikasi web cara mendeteksi lingkungan pengalihan WebRTC dan mengintegrasikannya.

Saat pengalihan WebRTC diaktifkan pada a WorkSpace, ekstensi browser Pengalihan WebRTC Amazon DCV menyuntikkan SDK proxy ke halaman web. Aplikasi Anda dapat mendeteksi proxy ini dan menggunakannya untuk mengalihkan panggilan API WebRTC standar - termasuk get UserMedia and RTCPeerConnection - ke perangkat lokal pengguna daripada perangkat virtual remote WorkSpace. Ini memberikan kinerja yang jauh lebih baik dan latensi yang lebih rendah dibandingkan dengan media streaming melalui protokol tampilan DCV.

Aplikasi Anda harus menangani kedua kasus: saat berjalan di dalam WorkSpace dengan pengalihan WebRTC diaktifkan, dan saat berjalan di browser standar tanpa itu. Proxy bersifat opsional - jika tidak ada, aplikasi Anda dapat kembali ke WebRTC standar.

Prasyarat

Untuk pengguna akhir

Pengguna akhir membutuhkan yang berikut:

  • WorkSpace Menggunakan protokol DCV. Untuk informasi selengkapnya, lihat Protokol untuk Pri WorkSpaces badi.

    catatan

    Pengalihan WebRTC di sisi server saat ini hanya didukung di Windows. WorkSpaces

  • Klien yang didukung dari WorkSpaces clients. amazonworkspaces.com. Platform yang didukung: Windows, macOS, Linux (Ubuntu 22.04 dan Ubuntu 24.04, amd64), dan Web.

  • Pengalihan WebRTC diaktifkan melalui Kebijakan Grup. Saat diaktifkan, kebijakan secara otomatis menginstal ekstensi browser di Chrome dan Edge melalui registri. Untuk informasi selengkapnya, lihat Kelola Windows Anda WorkSpaces di WorkSpaces Personal. Jika diperlukan, pengguna dapat menginstal ekstensi secara manual: Chrome dan Edge.

Untuk pengembang

Aplikasi web Anda harus:

  • Gunakan API WebRTC standar (seperti get UserMedia dan) RTCPeerConnection

  • Sertakan kode deteksi dan inisialisasi seperti yang dijelaskan dalam topik ini

Bagaimana mengintegrasikan

Integrasi melibatkan empat langkah: mendeteksi lingkungan pengalihan, mengganti API WebRTC, memetakan elemen audio, dan menangani koneksi ulang.

Langkah 1: Mendeteksi lingkungan pengalihan

Tambahkan kode inisialisasi ini ke aplikasi Anda. Panggilan balik berjalan saat proxy siap, atau setelah batas waktu jika pengalihan tidak tersedia.

let proxy = null; function handleInitCallback(result) { if (result.success) { // Redirection is available proxy = result.proxy; console.log('WebRTC redirection enabled, version:', proxy.getVersion()); console.log('Client info:', proxy.clientInfo); // Override WebRTC APIs to use redirection proxy.overrideWebRTC(); // Set up reconnection handling setupReconnectionHandling(); } else { // Not in a redirection environment - use standard WebRTC console.log('WebRTC redirection not available:', result.error); } } // Register the initialization callback if (globalThis.DCVWebRTCPeerConnectionProxyV2) { globalThis.DCVWebRTCPeerConnectionProxyV2.setInitCallback(handleInitCallback, 5000); }

Poin kunci:

  • Periksa globalThis.DCVWebRTCPeerConnectionProxyV2 untuk mendeteksi ekstensi

  • Panggil setInitCallback() dengan handler Anda dan batas waktu - 5000 ms disarankan

  • Panggilan balik menerima objek hasil dengan success boolean dan salah satu atau proxy error

  • Panggilan proxy.overrideWebRTC() untuk mengalihkan API WebRTC standar

Langkah 2: Gunakan API WebRTC standar

Setelah meneleponoverrideWebRTC(), gunakan API WebRTC secara normal. Proxy secara transparan mengarahkan mereka ke klien lokal.

catatan

Pengalihan video saat ini tidak didukung. Tet video: false apkan getUserMedia permintaan.

// Get user media - automatically redirected const stream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false // Video redirection not yet supported }); // Create peer connection - automatically redirected const pc = new RTCPeerConnection(configuration); // Everything else works as standard WebRTC pc.addTrack(stream.getAudioTracks()[0], stream); const offer = await pc.createOffer(); await pc.setLocalDescription(offer);

Jika Anda perlu mengakses API browser asli (misalnya, untuk menangkap video dari browser jarak jauh daripada klien lokal), mereka disimpan diproxy.overridenApis:

// Get the original getUserMedia (runs in remote browser, not redirected) const originalGetUserMedia = proxy.overridenApis.get('navigator.mediaDevices.getUserMedia'); // Available original APIs: // 'navigator.mediaDevices.getUserMedia' // 'navigator.mediaDevices.addEventListener' // 'navigator.mediaDevices.removeEventListener' // 'navigator.mediaDevices.enumerateDevices' // 'navigator.mediaDevices.getDisplayMedia' // 'window.RTCPeerConnection' // 'window.RTCPeerConnection.generateCertificate' // 'window.AudioContext' // 'window.Worker' (experimental) const remoteStream = await originalGetUserMedia.call(navigator.mediaDevices, { audio: false, video: true });

Langkah 3: Memetakan elemen audio

Untuk pemutaran audio, hubungi mapAudioElement() sebelum mengatur srcObject elemen audio apa pun.

const audioElement = document.querySelector('audio#remote-audio'); // Map the audio element before setting srcObject proxy.mapAudioElement(audioElement); // Now use the audio element normally audioElement.srcObject = remoteStream; await audioElement.play(); // Control playback audioElement.pause(); audioElement.volume = 0.8; audioElement.muted = false; // Change output device await audioElement.setSinkId(deviceId);

Langkah 4: Tangani koneksi ulang

Layanan pengalihan dapat menjadi tidak tersedia sementara, misalnya karena masalah jaringan atau koneksi ulang klien.

penting

Setelah koneksi ulang, semua objek proxy yang dibuat sebelumnya menjadi tidak valid karena konteks browser klien dimuat ulang sepenuhnya. Anda harus menutup koneksi yang ada dan membuat objek WebRTC baru.

function setupReconnectionHandling() { proxy.addStatusChangeEventListener((event) => { switch (event.status) { case 'unavailable': console.error('Redirection lost'); handleRedirectionLost(); break; case 'available': console.info('Redirection restored'); handleRedirectionRestored(); break; } }); } function handleRedirectionLost() { // Try to close cleanly - proxies may throw exceptions after reconnection try { if (peerConnection) { peerConnection.close(); } } catch (error) { console.warn('Error closing peer connection (proxy may be invalid):', error); } showReconnectingMessage(); } function handleRedirectionRestored() { // IMPORTANT: All existing proxy objects are invalid after reconnection. // Create new RTCPeerConnection, MediaStream, and other WebRTC objects. hideReconnectingMessage(); restartCall(); // Must create fresh WebRTC objects }

Anda dapat menyesuaikan waktu detak jantung:

proxy.resetHeartbeat({ heartbeatTimeoutMs: 5000, // Time before marking unavailable heartbeatIntervalPeriodMs: 500 // How often to check });

Pencacatan perangkat

Perubahan perangkat - misalnya, pengguna yang mencolokkan headset - terdeteksi secara otomatis. Gunakan makeMediaDevicesProxy() untuk mendengarkan perubahan perangkat pada klien lokal:

const mediaDevices = proxy.makeMediaDevicesProxy(); mediaDevices.ondevicechange = async () => { const devices = await navigator.mediaDevices.enumerateDevices(); updateDeviceList(devices); };

Gunakan proxy.clientInfo untuk menentukan platform klien mana pengguna terhubung dari:

// clientInfo contains: // - platform: 'web' | 'windows' | 'macOS' | 'linux' // - version: SDK version string // - userAgent: browser user agent string // - browserDetails: { browser: string, version: string } switch (proxy.clientInfo.platform) { case 'web': console.log('Connecting from web client'); break; case 'windows': console.log('Connecting from Windows native client'); break; case 'macOS': console.log('Connecting from macOS native client'); break; case 'linux': console.log('Connecting from Linux native client'); break; }

Lanjutan: Pemrosesan audio dengan Web Audio API

Anda dapat menggunakan Web Audio API untuk memproses aliran audio sebelum mengirimnya melalui koneksi peer:

const audioContext = new AudioContext(); const source = audioContext.createMediaStreamSource(micStream); const gainNode = audioContext.createGain(); const destination = audioContext.createMediaStreamDestination(); source.connect(gainNode); gainNode.connect(destination); // Control microphone volume gainNode.gain.value = 0.5; // 50% volume // Use the processed stream pc.addTrack(destination.stream.getAudioTracks()[0], destination.stream);

Contoh lengkap

Contoh berikut menunjukkan integrasi lengkap dengan inisialisasi, penanganan rekoneksi, deteksi perubahan perangkat, dan pengaturan panggilan:

let proxy = null; let peerConnection = null; let localStream = null; function initializeRedirection() { if (globalThis.DCVWebRTCPeerConnectionProxyV2) { globalThis.DCVWebRTCPeerConnectionProxyV2.setInitCallback((result) => { if (result.success) { proxy = result.proxy; proxy.overrideWebRTC(); proxy.addStatusChangeEventListener(handleStatusChange); proxy.resetHeartbeat({ heartbeatTimeoutMs: 5000, heartbeatIntervalPeriodMs: 500 }); setupDeviceChangeListener(); } else { console.log('Redirection not available:', result.error); } }, 5000); } } function handleStatusChange(event) { if (event.status === 'unavailable') { try { if (peerConnection) { peerConnection.close(); peerConnection = null; } if (localStream) { localStream.getTracks().forEach(t => t.stop()); localStream = null; } } catch (error) { console.warn('Error cleaning up (proxies invalid):', error); peerConnection = null; localStream = null; } } else if (event.status === 'available') { startCall(); // Create fresh WebRTC objects } } function setupDeviceChangeListener() { const mediaDevices = proxy.makeMediaDevicesProxy(); mediaDevices.ondevicechange = async () => { const devices = await navigator.mediaDevices.enumerateDevices(); updateDeviceUI(devices); }; } async function startCall() { try { localStream = await navigator.mediaDevices.getUserMedia({ audio: true, video: false }); peerConnection = new RTCPeerConnection({ iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] }); localStream.getTracks().forEach(track => peerConnection.addTrack(track, localStream)); peerConnection.ontrack = (event) => { const remoteAudio = document.querySelector('audio#remote'); if (proxy) { proxy.mapAudioElement(remoteAudio); } remoteAudio.srcObject = event.streams[0]; remoteAudio.play(); }; peerConnection.onicecandidate = (event) => { if (event.candidate) { sendToSignalingServer({ type: 'ice-candidate', candidate: event.candidate }); } }; const offer = await peerConnection.createOffer(); await peerConnection.setLocalDescription(offer); sendToSignalingServer({ type: 'offer', sdp: offer }); } catch (error) { console.error('Failed to start call:', error); } } initializeRedirection();

Menguji integrasi Anda

Tanpa pengalihan

Aplikasi Anda bekerja secara normal ketika ekstensi tidak diinstal, saat berjalan di luar WorkSpace, atau ketika pengalihan WebRTC tidak diaktifkan melalui Kebijakan Grup. Uji dengan membuka aplikasi Anda di browser biasa.

Dengan pengalihan

Untuk menguji dengan pengalihan diaktifkan:

  1. Buat protokol WorkSpace menggunakan DCV dan aktifkan pengaturan Kebijakan Grup pengalihan WebRTC. Lihat Kelola Windows Anda WorkSpaces di WorkSpaces Personal.

  2. Unduh dan instal WorkSpaces klien dari clients.amazonworkspaces.com dan sambungkan ke. WorkSpace Verifikasi ekstensi Chrome atau Edge diinstal (otomatis saat GPO disetel).

  3. Buka aplikasi web Anda di WorkSpace browser. Periksa konsol untuk pesan “Pengalihan WebRTC diaktifkan”. Verifikasi fungsionalitas audio dengan perangkat lokal, uji enumerasi dan peralihan perangkat, dan verifikasi penanganan koneksi ulang.

Praktik terbaik

Ikuti rekomendasi ini saat mengintegrasikan dengan pengalihan WebRTC:

  • Selalu periksa ketersediaan pengalihan - jangan pernah menganggap proxy ada

  • Panggil overrideWebRTC() lebih awal - sebelum membuat objek WebRTC apa pun

  • Memetakan elemen audio sebelum digunakan - panggil mapAudioElement() sebelum pengaturan srcObject

  • Tangani koneksi ulang - setelah koneksi ulang, semua objek proxy tidak valid; selalu buat objek WebRTC baru

  • Uji kedua mode - pastikan aplikasi Anda berfungsi dengan benar dengan dan tanpa pengalihan

  • Gunakan API WebRTC standar - proxy mengalihkannya secara transparan; tidak ada API khusus yang diperlukan untuk penggunaan dasar

  • Bersihkan sumber daya - hapus pendengar acara dan tutup koneksi setelah selesai

Pemecahan masalah

Pengalihan tidak terdeteksi

  • Verifikasi ekstensi browser diinstal dan diaktifkan (periksachrome://extensions)

  • Konfirmasikan Kebijakan Grup pengalihan WebRTC diaktifkan pada WorkSpace

  • Verifikasi Anda menjalankan di dalam protokol DCV yang WorkSpace menggunakan

  • Periksa konsol browser untuk pesan inisialisasi

  • Verifikasi versi WorkSpaces klien mendukung pengalihan WebRTC (Windows 5.21.0 atau lebih baru, macOS 5.31.0 atau lebih baru, Linux 2026.0 atau lebih baru, atau klien Web)

Audio atau video tidak berfungsi

  • Verifikasi overrideWebRTC() dipanggil sebelum membuat objek WebRTC

  • Verifikasi elemen audio dipetakan mapAudioElement() sebelum pengaturan srcObject

  • Periksa konsol browser untuk kesalahan

  • Verifikasi izin perangkat diberikan

Masalah koneksi ulang

  • Menerapkan addStatusChangeEventListener() untuk mendeteksi perubahan ketersediaan

  • Setelah koneksi ulang, selalu buat objek baru RTCPeerConnection dan MediaStream objek - proxy lama tidak valid dan akan melempar

  • Tinjau konfigurasi detak jantung jika ketidaktersediaan terdeteksi terlalu lambat atau terlalu cepat

Referensi API

Berikut ini merangkum API proxy:

interface DCVWebRTCProxy { // Version and client info getVersion(): string; clientInfo: { platform: 'web' | 'windows' | 'macOS' | 'linux'; version: string; userAgent: string; browserDetails: { browser: string; version: string; }; }; // Core methods overrideWebRTC(): void; mapAudioElement(element: HTMLAudioElement): void; // Device management makeMediaDevicesProxy(): MediaDevices; // Status monitoring addStatusChangeEventListener(callback: (event: StatusChangeEvent) => void): void; resetHeartbeat(config: { heartbeatTimeoutMs: number, heartbeatIntervalPeriodMs: number }): void; // Access original (non-redirected) browser APIs overridenApis: Map<string, Function>; } interface StatusChangeEvent { status: 'available' | 'unavailable'; lastHeartbeat?: number; }