Skip to content

Instantly share code, notes, and snippets.

@kwindla
Created July 22, 2021 03:18
Show Gist options
  • Save kwindla/fb79aa8f426d51eac13e7d03f8b1997a to your computer and use it in GitHub Desktop.
Save kwindla/fb79aa8f426d51eac13e7d03f8b1997a to your computer and use it in GitHub Desktop.
Daily video API -- custom audio and video tracks
<html>
<head>
<title>custom video and audio tracks</title>
<script src="https://unpkg.com/@daily-co/daily-js"></script>
</head>
<body>
<div id="local-controls" style="width: 50%; float: left">
<button onclick="createAndJoinCall()">create call object and join</button>
<button onclick="publishCanvasTrack()">
start/use custom video track
</button>
<button onclick="publishOscillatorTrack()">
start/use custom audio track
</button>
<hr />
local view of canvas
<canvas id="can" width="640" height="320" style="width: 100%"></canvas>
</div>
<div id="videos" style="margin-left: 50%"></div>
<script>
const ROOM_URL = 'https:// YOU ROOM URL HERE';
async function createAndJoinCall() {
if (window.call) {
return;
}
window.call = DailyIframe.createCallObject({
dailyConfig: {
experimentalChromeVideoMuteLightOff: true,
},
videoSource: false,
audioSource: false,
});
call.on('track-started', displayVideo);
await call.join({ url: ROOM_URL });
}
// ----
function startCanvasTrack() {
window.canvas = document.getElementById('can');
window.context = canvas.getContext('2d');
videoAnimationFrame(context);
window.canvasStream = canvas.captureStream(20);
window.angle = 0;
}
function videoAnimationFrame() {
window.angle += 0.01;
context.save();
context.resetTransform();
context.fillStyle = '#F8C471';
context.fillRect(0, 0, canvas.width, canvas.height);
context.restore();
context.save();
context.transform(1, 0, 0, 1, canvas.width / 2, canvas.height / 2);
context.rotate(window.angle);
context.transform(1, 0, 0, 1, canvas.width / -2, canvas.height / -2);
context.beginPath();
context.moveTo(canvas.width / 2, canvas.height / 2);
context.lineTo(canvas.width, canvas.height / 2);
context.strokeStyle = '#2C3E50';
context.stroke();
context.restore();
requestAnimationFrame(videoAnimationFrame);
}
function startOscillatorTrack() {
window.ac = new AudioContext();
window.osc = window.ac.createOscillator();
window.oscillatorDestination = window.ac.createMediaStreamDestination();
window.osc.connect(window.oscillatorDestination);
window.osc.start(0);
}
// ----
async function publishCanvasTrack() {
if (!window.canvas) {
startCanvasTrack();
}
if (window.call) {
await call.setInputDevicesAsync({
videoSource: window.canvasStream.getVideoTracks()[0],
});
}
}
async function publishOscillatorTrack() {
if (!window.ac) {
startOscillatorTrack();
}
if (window.call) {
await call.setInputDevicesAsync({
audioSource: oscillatorDestination.stream.getAudioTracks()[0],
});
}
}
// ----
function displayVideo(evt) {
console.log(evt);
if (!(evt.track.kind === 'video')) {
return;
}
let videosDiv = document.getElementById('videos');
let videoEl = document.createElement('video');
videosDiv.appendChild(videoEl);
videoEl.style.width = '100%';
videoEl.srcObject = new MediaStream([evt.track]);
videoEl.play();
}
function destroyVideo(evt) {
let vids = document.getElementsByTagName('video');
for (let vid of vids) {
if (vid.srcObject.getVideoTracks()[0] === evt.track) {
vid.remove();
}
}
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment