Pular para conteúdo

Download de Gravações

O endpoint /recordings/files/{fileId}/download-url permite obter uma URL assinada (presigned URL) para fazer download de arquivos de gravação armazenados no S3.

Estrutura de Gravações

As gravações seguem uma estrutura hierárquica:

Chamada (Call)
  └── Gravação (Recording)
      └── Arquivos de Gravação (RecordingFiles)

Uma única gravação pode conter múltiplos arquivos quando a gravação individual está habilitada (um arquivo por participante).

Requisição

Gera uma URL de download temporária para um arquivo de gravação específico.

Info

Nota importante: Este endpoint não requer autenticação. A segurança é garantida pelo próprio ID do arquivo que funciona como token único.

Exemplos de Implementação

1. Listar Gravações de uma Chamada

Primeiro, obtenha os arquivos de gravação disponíveis:

curl -X GET "https://api.videochamada.com.br/api/calls/{callId}/recordings" \
  -H "Authorization: Bearer {API_TOKEN}"
import requests

# Listar gravações
response = requests.get(
    "https://api.videochamada.com.br/api/calls/{callId}/recordings",
    headers={"Authorization": "Bearer {API_TOKEN}"}
)

recordings = response.json()
print(recordings)
// Listar gravações
const response = await fetch('https://api.videochamada.com.br/api/calls/{callId}/recordings', {
  headers: {
    'Authorization': 'Bearer {API_TOKEN}'
  }
});

const recordings = await response.json();
console.log(recordings);

Exemplo de Resposta:

{
  "data": [
    {
      "id": "rec_123",
      "callId": "call_456",
      "status": "completed",
      "files": [
        {
          "id": "file_abc",
          "fileType": "video",
          "sessionId": "session_xyz",
          "duration": 1800,
          "url": "https://s3.amazonaws.com/...",
          "transcription": "Conteúdo da transcrição...",
          "created": "2025-10-16T10:35:00Z"
        },
        {
          "id": "file_def",
          "fileType": "video",
          "sessionId": "session_uvw",
          "duration": 1750,
          "url": "https://s3.amazonaws.com/...",
          "transcription": null,
          "created": "2025-10-16T10:35:00Z"
        }
      ],
      "created": "2025-10-16T10:35:00Z"
    }
  ]
}

2. Obter URL de Download

Use o id do arquivo para gerar a URL de download:

curl -X GET "https://api.videochamada.com.br/recordings/files/{fileId}/download-url"
import requests

# Obter URL de download
response = requests.get(
    f"https://api.videochamada.com.br/recordings/files/{file_id}/download-url"
)

download_data = response.json()
print(f"URL de download: {download_data['url']}")
print(f"Expira em: {download_data['expiresAt']}")
// Obter URL de download
const response = await fetch(`https://api.videochamada.com.br/recordings/files/${fileId}/download-url`);
const downloadData = await response.json();

console.log('URL de download:', downloadData.url);
console.log('Expira em:', downloadData.expiresAt);
var client = new HttpClient();
var response = await client.GetAsync($"https://api.videochamada.com.br/recordings/files/{fileId}/download-url");
var content = await response.Content.ReadAsStringAsync();

Console.WriteLine(content);

Resposta

Exemplo de Resposta:

{
  "url": "https://s3.amazonaws.com/bucket/recording.webm?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=...",
  "expiresAt": "2025-10-16T15:00:00Z",
  "fileInfo": {
    "id": "file_abc",
    "fileType": "video",
    "duration": 1800,
    "sessionId": "session_xyz"
  }
}
{
  "message": "Recording file not found",
  "error": "Not Found",
  "statusCode": 404
}

Explicação dos Campos:

  • url: URL assinada do S3 para download direto do arquivo
  • expiresAt: Data e hora de expiração da URL (tipicamente 1 hora)
  • fileInfo: Informações sobre o arquivo
  • id: ID único do arquivo
  • fileType: Tipo do arquivo (video ou audio)
  • duration: Duração em segundos
  • sessionId: ID da sessão WebRTC associada ao arquivo

Exemplo Completo: Download Programático

Python

import requests
import os

def download_recording(call_id, api_token, output_dir="downloads"):
    # 1. Listar gravações da chamada
    headers = {"Authorization": f"Bearer {api_token}"}
    recordings_response = requests.get(
        f"https://api.videochamada.com.br/api/calls/{call_id}/recordings",
        headers=headers
    )
    recordings = recordings_response.json()["data"]

    if not recordings:
        print("Nenhuma gravação encontrada")
        return

    # 2. Para cada arquivo de gravação
    for recording in recordings:
        for file in recording["files"]:
            file_id = file["id"]
            session_id = file.get("sessionId", "unknown")

            # 3. Obter URL de download
            download_response = requests.get(
                f"https://api.videochamada.com.br/recordings/files/{file_id}/download-url"
            )
            download_url = download_response.json()["url"]

            # 4. Fazer download do arquivo
            file_response = requests.get(download_url, stream=True)

            # 5. Salvar no disco
            os.makedirs(output_dir, exist_ok=True)
            filename = f"{call_id}_{session_id}_{file_id}.webm"
            filepath = os.path.join(output_dir, filename)

            with open(filepath, 'wb') as f:
                for chunk in file_response.iter_content(chunk_size=8192):
                    f.write(chunk)

            print(f"Download concluído: {filepath}")

# Uso
download_recording("call_123", "your_api_token")

Node.js

const fs = require('fs');
const path = require('path');
const axios = require('axios');

async function downloadRecording(callId, apiToken, outputDir = 'downloads') {
    // 1. Listar gravações da chamada
    const recordingsResponse = await axios.get(
        `https://api.videochamada.com.br/api/calls/${callId}/recordings`,
        { headers: { 'Authorization': `Bearer ${apiToken}` } }
    );
    const recordings = recordingsResponse.data.data;

    if (recordings.length === 0) {
        console.log('Nenhuma gravação encontrada');
        return;
    }

    // 2. Para cada arquivo de gravação
    for (const recording of recordings) {
        for (const file of recording.files) {
            const fileId = file.id;
            const sessionId = file.sessionId || 'unknown';

            // 3. Obter URL de download
            const downloadResponse = await axios.get(
                `https://api.videochamada.com.br/recordings/files/${fileId}/download-url`
            );
            const downloadUrl = downloadResponse.data.url;

            // 4. Fazer download do arquivo
            const fileResponse = await axios.get(downloadUrl, {
                responseType: 'stream'
            });

            // 5. Salvar no disco
            if (!fs.existsSync(outputDir)) {
                fs.mkdirSync(outputDir, { recursive: true });
            }

            const filename = `${callId}_${sessionId}_${fileId}.webm`;
            const filepath = path.join(outputDir, filename);
            const writer = fs.createWriteStream(filepath);

            fileResponse.data.pipe(writer);

            await new Promise((resolve, reject) => {
                writer.on('finish', resolve);
                writer.on('error', reject);
            });

            console.log(`Download concluído: ${filepath}`);
        }
    }
}

// Uso
downloadRecording('call_123', 'your_api_token');

Informações Técnicas

Formato dos Arquivos

  • Container: WebM
  • Codec de Vídeo: VP8 ou VP9
  • Codec de Áudio: Opus
  • Extensão: .webm

Validade da URL

As URLs de download geradas são temporárias e tipicamente expiram em 1 hora. Após a expiração, você precisará gerar uma nova URL.

Política de Retenção

As gravações são mantidas de acordo com a configuração do projeto:

  • recordingRetentionDays: Número de dias que as gravações são mantidas
  • autoDeleteExpiredRecordings: Se habilitado, gravações expiradas são deletadas automaticamente

Warning

Importante: Faça backup das gravações importantes antes do período de retenção expirar!

Boas Práticas

  • Validade da URL: Sempre verifique o campo expiresAt antes de usar a URL
  • Download Assíncrono: Para múltiplos arquivos, use download em paralelo
  • Armazenamento Local: Se necessário acesso frequente, faça cache local dos arquivos
  • Monitoramento de Espaço: Gravações podem ser grandes, monitore espaço em disco
  • Tratamento de Erros: Implemente retry para falhas de rede durante download

Casos de Uso

  • Backup: Fazer backup automático de todas as gravações
  • Processamento: Download para análise ou processamento local (ex: edição)
  • Arquivo: Armazenar gravações em sistemas de arquivo de longo prazo
  • Distribuição: Download para redistribuição aos participantes
  • Compliance: Manter cópias para requisitos regulatórios

Troubleshooting

Erro 404: Recording file not found

Causa: O arquivo de gravação não existe ou foi deletado.

Solução: Verifique se o fileId está correto e se o arquivo não foi deletado pela política de retenção.

URL Expirada

Causa: Tentou usar a URL após o tempo de expiração.

Solução: Gere uma nova URL de download chamando o endpoint novamente.

Download Lento

Causa: Arquivo grande ou conexão lenta.

Solução: - Use download em streaming ao invés de carregar tudo na memória - Implemente retry com resume para downloads interrompidos - Considere fazer download em horários de menor tráfego