

As traduções são geradas por tradução automática. Em caso de conflito entre o conteúdo da tradução e da versão original em inglês, a versão em inglês prevalecerá.

# Integre seu aplicativo web com o redirecionamento WebRTC
<a name="webrtc-redirection-integration"></a>

O redirecionamento WebRTC permite que aplicativos web executados WorkSpaces dentro das sessões usem dispositivos de áudio nativos do lado do cliente. Este tópico mostra aos desenvolvedores de aplicativos Web como detectar o ambiente de redirecionamento WebRTC e integrá-lo a ele.

Quando o redirecionamento WebRTC está habilitado em um, WorkSpace a extensão de navegador Amazon DCV WebRTC Redirection injeta um SDK proxy na página da web. Seu aplicativo pode detectar esse proxy e usá-lo para redirecionar as chamadas padrão da API WebRTC, incluindo UserMedia get RTCPeerConnection and, para os dispositivos locais do usuário em vez dos dispositivos virtuais remotos. WorkSpace Isso fornece desempenho significativamente melhor e menor latência em comparação com streaming de mídia por meio do protocolo de exibição DCV.

Seu aplicativo deve lidar com os dois casos: quando executado dentro de um WorkSpace com o redirecionamento WebRTC ativado e quando executado em um navegador padrão sem ele. O proxy é opcional - se não estiver presente, seu aplicativo pode voltar para o WebRTC padrão.

## Pré-requisitos
<a name="webrtc-prereqs"></a>

### Para usuários finais
<a name="webrtc-prereqs-users"></a>

Os usuários finais precisam do seguinte:
+ A WorkSpace usando o protocolo DCV. Para obter mais informações, consulte [Protocolos para WorkSpaces uso pessoal](amazon-workspaces-networking.md#amazon-workspaces-protocols).
**nota**  
Atualmente, o redirecionamento WebRTC no lado do servidor é suportado somente no Windows. WorkSpaces
+ Um WorkSpaces cliente compatível de [clients.amazonworkspaces.com](https://clients.amazonworkspaces.com). Plataformas suportadas: Windows, macOS, Linux (Ubuntu 22.04 e Ubuntu 24.04, amd64) e Web.
+ Redirecionamento WebRTC habilitado por meio da Política de Grupo. Quando ativada, a política instala automaticamente a extensão do navegador no Chrome e no Edge por meio do registro. Para obter mais informações, consulte [Gerencie seu Windows WorkSpaces no WorkSpaces Personal](group_policy.md). Se necessário, os usuários podem instalar a extensão manualmente: [Chrome](https://chromewebstore.google.com/detail/amazon-dcv-webrtc-redirec/diilpfplcnhehakckkpmcmibmhbingnd) e [Edge](https://microsoftedge.microsoft.com/addons/detail/amazon-dcv-webrtc-redirec/kjbbkjjiecchbcdoollhgffghfjnbhef).

### Para desenvolvedores
<a name="webrtc-prereqs-devs"></a>

Seu aplicativo web deve:
+ Use APIs WebRTC padrão (como get and) UserMedia RTCPeerConnection
+ Inclua o código de detecção e inicialização conforme descrito neste tópico

## Como integrar
<a name="webrtc-how-to-integrate"></a>

A integração envolve quatro etapas: detectar o ambiente de redirecionamento, substituir as APIs do WebRTC, mapear elementos de áudio e lidar com a reconexão.

### Etapa 1: Detectar o ambiente de redirecionamento
<a name="webrtc-step1-detect"></a>

Adicione esse código de inicialização ao seu aplicativo. O retorno de chamada é executado quando o proxy está pronto ou após o tempo limite, se o redirecionamento não estiver disponível.

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

Principais pontos:
+ Verifique `globalThis.DCVWebRTCPeerConnectionProxyV2` para detectar a extensão
+ Faça uma chamada `setInitCallback()` com seu manipulador e um tempo limite de 5000 ms é recomendado
+ O retorno de chamada recebe um objeto de resultado com um `success` booleano e ou `proxy` `error`
+ Chamada `proxy.overrideWebRTC()` para redirecionar as APIs WebRTC padrão

### Etapa 2: usar APIs WebRTC padrão
<a name="webrtc-step2-apis"></a>

Depois de ligar`overrideWebRTC()`, use as APIs WebRTC normalmente. O proxy os redireciona de forma transparente para o cliente local.

**nota**  
Atualmente, o redirecionamento de vídeo não é suportado. `video: false`Definido nas `getUserMedia` solicitações.

```
// 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);
```

Se você precisar acessar as APIs originais do navegador (por exemplo, para capturar vídeo do navegador remoto em vez do cliente local), elas serão preservadas em`proxy.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
});
```

### Etapa 3: mapear elementos de áudio
<a name="webrtc-step3-audio"></a>

Para reprodução de áudio, ligue `mapAudioElement()` antes de configurar `srcObject` qualquer elemento de áudio.

```
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);
```

### Etapa 4: lidar com a reconexão
<a name="webrtc-step4-reconnection"></a>

O serviço de redirecionamento pode ficar temporariamente indisponível, por exemplo, devido a problemas de rede ou reconexão do cliente.

**Importante**  
Após a reconexão, todos os objetos proxy criados anteriormente se tornam inválidos porque o contexto do navegador do cliente é completamente recarregado. Você deve fechar as conexões existentes e criar novos objetos WebRTC.

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

Você pode personalizar o tempo de pulsação:

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

## Enumeração de dispositivos
<a name="webrtc-device-enumeration"></a>

Alterações no dispositivo — por exemplo, um usuário conectando um fone de ouvido — são detectadas automaticamente. Use `makeMediaDevicesProxy()` para ouvir as alterações do dispositivo no cliente local:

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

Use `proxy.clientInfo` para determinar de qual plataforma de cliente o usuário está se conectando:

```
// 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;
}
```

## Avançado: processamento de áudio com a API de áudio da Web
<a name="webrtc-advanced-audio"></a>

Você pode usar a API de áudio da Web para processar fluxos de áudio antes de enviá-los por meio de uma conexão de mesmo nível:

```
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);
```

## Exemplo completo
<a name="webrtc-complete-example"></a>

O exemplo a seguir demonstra uma integração completa com inicialização, tratamento de reconexão, detecção de alterações no dispositivo e configuração de chamadas:

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

## Testando sua integração
<a name="webrtc-testing"></a>

### Sem redirecionamento
<a name="webrtc-testing-without"></a>

Seu aplicativo funciona normalmente quando a extensão não está instalada, quando executada fora de uma WorkSpace ou quando o redirecionamento WebRTC não está habilitado por meio da Política de Grupo. Teste abrindo seu aplicativo em um navegador comum.

### Com redirecionamento
<a name="webrtc-testing-with"></a>

Para testar com o redirecionamento ativado:

1. Crie um protocolo DCV WorkSpace usando e habilite a configuração da Política de Grupo de redirecionamento WebRTC. Consulte [Gerencie seu Windows WorkSpaces no WorkSpaces Personal](group_policy.md).

1. Baixe e instale um WorkSpaces cliente em [clients.amazonworkspaces.com](https://clients.amazonworkspaces.com) e conecte-se ao. WorkSpace Verifique se a extensão Chrome ou Edge está instalada (automática quando o GPO está definido).

1. Abra seu aplicativo da web no WorkSpace navegador. Verifique se há a mensagem “Redirecionamento WebRTC ativado” no console. Verifique a funcionalidade de áudio com dispositivos locais, teste a enumeração e a comutação de dispositivos e verifique o tratamento da reconexão.

## Práticas recomendadas
<a name="webrtc-best-practices"></a>

Siga estas recomendações ao fazer a integração com o redirecionamento WebRTC:
+ Sempre verifique a disponibilidade do redirecionamento - nunca assuma que o proxy existe
+ Ligue `overrideWebRTC()` mais cedo - antes de criar qualquer objeto WebRTC
+ Mapeie elementos de áudio antes de usar - ligue `mapAudioElement()` antes de configurar `srcObject`
+ Manipule a reconexão - após a reconexão, todos os objetos proxy são inválidos; sempre crie novos objetos WebRTC
+ Teste os dois modos - certifique-se de que seu aplicativo funcione corretamente com e sem redirecionamento
+ Use APIs WebRTC padrão - o proxy as redireciona de forma transparente; nenhuma API personalizada é necessária para uso básico
+ Limpe os recursos - remova os ouvintes do evento e feche as conexões quando terminar

## Solução de problemas
<a name="webrtc-troubleshooting"></a>

### Redirecionamento não detectado
<a name="webrtc-troubleshooting-not-detected"></a>
+ Verifique se a extensão do navegador está instalada e ativada (verifique`chrome://extensions`)
+ Confirme se a Política de Grupo de redirecionamento WebRTC está habilitada no WorkSpace
+ Verifique se você está executando dentro de um protocolo DCV em WorkSpace uso
+ Verifique se há mensagens de inicialização no console do navegador
+ Verifique se a versão do WorkSpaces cliente oferece suporte ao redirecionamento WebRTC (Windows 5.21.0 ou posterior, macOS 5.31.0 ou posterior, Linux 2026.0 ou posterior ou cliente Web)

### Áudio ou vídeo não funcionam
<a name="webrtc-troubleshooting-audio-video"></a>
+ Verifique se `overrideWebRTC()` foi chamado antes de criar qualquer objeto WebRTC
+ Verifique se os elementos de áudio estão mapeados `mapAudioElement()` antes da configuração `srcObject`
+ Verifique se há erros no console do navegador
+ Verifique se as permissões do dispositivo foram concedidas

### Problemas de reconexão
<a name="webrtc-troubleshooting-reconnection"></a>
+ Implemente `addStatusChangeEventListener()` para detectar mudanças na disponibilidade
+ Após a reconexão, sempre crie novos MediaStream objetos RTCPeerConnection e objetos - os proxies antigos são inválidos e serão lançados
+ Revise a configuração do heartbeat se a indisponibilidade for detectada muito lentamente ou muito rapidamente

## Referência de API
<a name="webrtc-api-reference"></a>

O seguinte resume a API de 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;
}
```