Librería WebRTC profesional optimizada para transmisión en **alta resolución (720p a 4K 60fps)**, soporte nativo de codecs (VP9, H264, AV1), servidores STUN/TURN/TURNS SSL y compatibilidad completa con **OBS Studio** y **vMix**.
Incorpóralo directamente en cualquier aplicación web desde la CDN oficial cifrada por SSL:
<!-- Importar versión minificada de producción -->
<script src="https://369peerjs.net.ar/369peer.min.js"></script>
<script>
// Inicializar Peer con servidor propio y preset 1080p por defecto
const peer = new Peer369('mi-usuario-id', {
preset: '1080p',
videoFormat: 'VP9'
});
peer.on('open', (id) => {
console.log('✅ Conectado exitosamente con ID:', id);
});
</script>
La librería cuenta con presets integrados que aplican restricciones ideales de resolución, FPS, ancho de banda doble SDP (`b=AS:` y `b=TIAS:`) y preferencias de no-pixelado:
| Preset | Resolución | FPS | Bitrate Asignado | Uso Recomendado |
|---|---|---|---|---|
| 720p | 1280 x 720 | 30 fps | 4,000 kbps (4 Mbps) | Conexiones móviles estables |
| 1080p | 1920 x 1080 | 60 fps | 10,000 kbps (10 Mbps) | Videollamadas Full HD estándar |
| 2k | 2560 x 1440 | 60 fps | 18,000 kbps (18 Mbps) | Gaming Quad HD y monitores anchos |
| 4k | 3840 x 2160 | 60 fps | 35,000 kbps (35 Mbps) | Streaming profesional 4K Ultra HD |
const peer = new Peer369({
preset: '4k', // Asigna 3840x2160@60fps y 35 Mbps de ancho de banda
videoFormat: 'VP9', // VP9 o H264/AV1
degradationPreference: 'maintain-resolution' // Mantiene nitidez 4K
});
// Ajustar dinámicamente el ancho de banda durante una llamada
peer.setBitrate(25000); // Cambiar a 25 Mbps en vivo
// O cambiar preset dinámicamente
peer.setQualityPreset('1080p');
Puedes recibir streams en **alta calidad (1080p / 4K)** directamente en **OBS Studio (Browser Source)** o **vMix (Web Input)** sin requerir interacción manual del usuario en el navegador receptor.
Crea o utiliza la siguiente plantilla HTML transparente para OBS / vMix:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<title>369peerjs OBS / vMix Receiver</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
html, body {
width: 100%;
height: 100%;
background: transparent; /* Permite croma o fondos transparentes en OBS */
overflow: hidden;
}
video {
width: 100%;
height: 100%;
object-fit: contain; /* Preserva la proporción exacta y nitidez 4K */
background: #000000;
}
</style>
<script src="https://369peerjs.net.ar/369peer.min.js"></script>
</head>
<body>
<video id="obsVideo" autoplay playsinline muted></video>
<script>
// Leer parámetros de URL: receptor-obs.html?peerId=CAM1&preset=4k
const urlParams = new URLSearchParams(window.location.search);
const peerId = urlParams.get('peerId') || 'OBS_RECEIVER';
const preset = urlParams.get('preset') || '4k';
// Inicializar Peer Receptor
const peer = new Peer369(peerId, {
preset: preset,
videoFormat: 'VP9',
degradationPreference: 'maintain-resolution'
});
peer.on('open', (id) => {
console.log('✅ Receptor OBS/vMix listo con ID:', id);
});
// Al recibir llamada entrante
peer.on('call', (call) => {
console.log('📞 Llamada recibida en OBS desde:', call.peer);
call.answer(); // Responde para recibir stream
call.on('stream', (remoteStream) => {
const videoElem = document.getElementById('obsVideo');
videoElem.srcObject = remoteStream;
videoElem.play().catch(e => console.log('Autoplay:', e));
});
});
</script>
</body>
</html>
1920x1080 o 3840x2160 según tu lienzo.La librería viene preconfigurada con servidores STUN/TURN de alta disponibilidad con soporte TLS cifrado:
| Tipo | Servidor / Dominio | Puerto | Transporte / Cifrado |
|---|---|---|---|
| STUN | stun:369app.net.ar / 13.140.43.187 |
3478 | UDP & TCP |
| TURN | turn:369app.net.ar / 13.140.43.187 |
3478 | UDP & TCP (HMAC Auth) |
| TURNS SSL | turns:369app.net.ar / 13.140.43.187 |
5349 | TLS Cifrado (Certificado SSL) |
const peer = new Peer369('mi-peer-id', {
// Servidor de señalización WebSocket
signalingServer: 'wss://369peerjs.net.ar',
// Preset de calidad multimedia: '720p', '1080p', '2k', '4k'
preset: '1080p',
// Ancho de banda personalizado en kbps (sobreescribe el preset)
bandwidth: 10000,
// Codec de video preferido: 'VP9', 'H264', 'VP8', 'AV1'
videoFormat: 'VP9',
// Preferencia de degradación: 'maintain-resolution', 'maintain-framerate', 'balanced'
degradationPreference: 'maintain-resolution',
// Restricciones de captura de cámara personalizadas
videoConstraints: {
width: { ideal: 1920 },
height: { ideal: 1080 },
frameRate: { ideal: 60 }
},
// Configuración de servidor TURN/STUN personalizado
turnServer: {
realm: '369app.net.ar',
ip: '13.140.43.187',
port: 3478,
turnsPort: 5349,
user: '369user',
password: '369turnpass2026',
secret: 'LAhienas123'
}
});
| Método | Parámetros | Descripción |
|---|---|---|
open() |
- | Conecta el cliente al servidor de señalización. |
call(peerId, stream, options) |
peerId: String, stream: MediaStream | Inicia una videollamada bidireccional en alta calidad. |
callReceiveOnly(peerId, options) |
peerId: String | Inicia una videollamada unidireccional (solo recibir video). |
connect(peerId, options) |
peerId: String, options: Object | Abre un canal de datos P2P (`binary`, `json`, `raw`). |
setQualityPreset(preset) |
preset: '720p'|'1080p'|'2k'|'4k' | Cambia la calidad y bitrate en llamadas activas. |
setBitrate(bitrateKbps) |
bitrateKbps: Number | Ajusta el ancho de banda en kbps en vivo. |
getDevices() |
- | Devuelve lista de cámaras y micrófonos disponibles. |
switchCamera(deviceId) |
deviceId: String | Alterna la cámara en transmisiones activas. |
disconnect() |
- | Desconecta del servidor de señalización limpiamente. |
destroy() |
- | Cierra todas las conexiones P2P y destruye la instancia. |
| Evento | Argumentos | Descripción |
|---|---|---|
open |
id: String | Se emite al conectarse exitosamente con su ID. |
call |
mediaConnection: MediaConnection | Se emite al recibir una videollamada entrante. |
connection |
dataConnection: DataConnection | Se emite al recibir una conexión de datos entrante. |
disconnected |
id: String | Se emite al perder la señalización temporalmente. |
reconnected |
id: String | Se emite tras reconectarse automáticamente al servidor. |
error |
err: Error | Se emite cuando ocurre un error en WebRTC o Red. |
Soporte para transferencia de archivos de gigabytes divididos en fragmentos de 16 KB con encabezado binario de 14 bytes y sin límite de tamaño:
const dataConn = peer.connect('receptor-id', {
serialization: 'binary',
reliable: true
});
dataConn.on('open', () => {
const file = document.getElementById('fileInput').files[0];
console.log('📦 Enviando archivo:', file.name, file.size, 'bytes');
dataConn.send(file);
});
// Receptor
peer.on('connection', (conn) => {
conn.on('data', (data) => {
if (data instanceof Blob || data instanceof ArrayBuffer) {
console.log('✅ Archivo completo recibido');
}
});
});
La librería incluye el método nativo attachStatsHUD(videoElement) para mostrar una insignia flotante sobre el reproductor de video con las métricas en tiempo real (Resolución exacta, FPS, Bitrate Mbps, Latencia RTT y Codec en uso):
const call = peer.call('receptor-id', stream);
call.on('stream', (remoteStream) => {
const videoElem = document.getElementById('remoteVideo');
videoElem.srcObject = remoteStream;
// Adjuntar insignia HUD sobre el video (Muestra: 3840x2160, 60 FPS, 34.8 Mbps, 12ms RTT, VP9)
const detachHUD = call.attachStatsHUD(videoElem);
// Para remover el HUD cuando finalice la llamada:
// detachHUD();
});
Analista en Sistemas | Cineasta | Periodista | Consultor Político | Especialista en Neurociencias
Desde el año 1990 en medios de comunicación. Desde el año 2005 dedicado al estudio de las conductas humanas, incursionando en las neurociencias, programación neurolingüística y comunicación no verbal, desarrollando técnicas y software propios para encuestas y mediciones.