// CanvasCompositor — gelen video track'lerini tek bir canvas'ta birleştirir. // // Kullanım: // const comp = new CanvasCompositor({ width: 1280, height: 720, fps: 30 }); // comp.addTrack('alice', videoTrack); // comp.addTrack('bob', videoTrack2); // comp.setLayout('grid'); // 'grid' | 'pip' | 'side-by-side' | 'focus' // const stream = comp.stream(); // MediaStream → StreamManager.addStream() ile gönder // comp.destroy(); // cleanup // // Ses için AudioContext mix bus: // const { ctx, dest, stream: audioStream } = MediaSources.createAudioMix(); // ctx.createMediaStreamSource(peerAudioStream).connect(dest); // // audioStream'ı da StreamManager.addStream('audio-mix', audioStream) ile gönder export default class CanvasCompositor { constructor({ width = 1280, height = 720, fps = 30, background = '#000' } = {}) { this._width = width; this._height = height; this._fps = fps; this._bg = background; // Use OffscreenCanvas when available (no DOM required, runs in workers too). if (typeof OffscreenCanvas !== 'undefined') { this._canvas = new OffscreenCanvas(width, height); } else { this._canvas = document.createElement('canvas'); this._canvas.width = width; this._canvas.height = height; } this._ctx = this._canvas.getContext('2d'); this._tracks = new Map(); // label → { track, video, active } this._layout = 'grid'; this._focus = null; // label of the focused track in 'focus' mode this._timer = null; this._stream = null; this._start(); } // ---- Track management ----------------------------------------------- // Add a VideoTrack to the compositor. A hidden