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 WorkSpaces dalam sesi untuk menggunakan perangkat audio sisi klien asli. Topik ini menunjukkan pengembang aplikasi web bagaimana mendeteksi lingkungan pengalihan WebRTC dan mengintegrasikannya.

Saat pengalihan WebRTC diaktifkan pada a, WorkSpace ekstensi browser Amazon DCV WebRTC Redirection menyuntikkan SDK proxy ke halaman web. Aplikasi Anda dapat mendeteksi proxy ini dan menggunakannya untuk mengarahkan panggilan API WebRTC standar - termasuk UserMedia get RTCPeerConnection dan - 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: ketika berjalan di dalam WorkSpace dengan pengalihan WebRTC diaktifkan, dan ketika 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 ini:

  • A WorkSpace menggunakan protokol DCV. Untuk informasi selengkapnya, lihat Protokol untuk Pribadi WorkSpaces.

    catatan

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

  • WorkSpaces Klien yang didukung dari 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 akan secara otomatis menginstal ekstensi browser di Chrome dan Edge melalui registri. Untuk informasi selengkapnya, lihat Kelola Windows Anda WorkSpaces secara WorkSpaces Pribadi. Jika diperlukan, pengguna dapat menginstal ekstensi secara manual: Chrome dan Edge.

Untuk pengembang

Aplikasi web Anda harus:

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

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

Bagaimana cara 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. Callback 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

  • Panggilan setInitCallback() dengan handler Anda dan batas waktu - 5000 ms direkomendasikan

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

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

Langkah 2: Gunakan API WebRTC standar

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

catatan

Pengalihan video saat ini tidak didukung. Ditetapkan video: false dalam 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 merekam video dari browser jarak jauh daripada klien lokal), mereka disimpan dalamproxy.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: Peta 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 untuk 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 });

Pencacahan 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 rekan:

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 penyiapan 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 berfungsi normal saat ekstensi tidak diinstal, saat berjalan di luar a WorkSpace, atau saat 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 secara WorkSpaces Pribadi.

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

  3. Buka aplikasi web Anda di WorkSpace browser. Periksa konsol untuk pesan “WebRTC redirection enabled”. Verifikasi fungsionalitas audio dengan perangkat lokal, uji pencacahan 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

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

  • Menangani rekoneksi - setelah rekoneksi, 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 mengarahkannya secara transparan; tidak diperlukan API khusus 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 bahwa Anda menjalankan di dalam WorkSpace protokol menggunakan DCV

  • Periksa konsol browser untuk pesan inisialisasi

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

Audio atau video tidak berfungsi

  • Verifikasi overrideWebRTC() dipanggil sebelum membuat objek WebRTC

  • Verifikasi elemen audio dipetakan dengan mapAudioElement() sebelum pengaturan srcObject

  • Periksa konsol browser untuk kesalahan

  • Verifikasi izin perangkat diberikan

Masalah koneksi ulang

  • Terapkan addStatusChangeEventListener() untuk mendeteksi perubahan ketersediaan

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

  • Tinjau konfigurasi detak jantung jika tidak tersedianya 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; }