Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions demo/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@

// Development configuration (localhost)
const LOCALHOST_CONFIG = {
relay: "https://localhost:4443",
fingerprint: "https://localhost:4443/fingerprint",
environment: "development"
relay: "https://localhost:4443",
fingerprint: "https://localhost:4443/fingerprint",
environment: "development"
};

// Production configuration (Cloudflare)
const CLOUDFLARE_CONFIG = {
relay: "https://interop-relay.cloudflare.mediaoverquic.com",
fingerprint: null, // No fingerprint needed for trusted certificate
environment: "production"
relay: "https://draft-16-manish.cloudflare.mediaoverquic.com",
fingerprint: null, // No fingerprint needed for trusted certificate
environment: "production"
};

// Current active configuration
Expand All @@ -31,14 +31,14 @@ const isProduction = () => CONFIG.environment === "production";

// Export configuration and helpers
window.MoQConfig = {
CONFIG,
LOCALHOST_CONFIG,
CLOUDFLARE_CONFIG,
getRelayUrl,
getFingerprintUrl,
getEnvironment,
isLocalhost,
isProduction
CONFIG,
LOCALHOST_CONFIG,
CLOUDFLARE_CONFIG,
getRelayUrl,
getFingerprintUrl,
getEnvironment,
isLocalhost,
isProduction
};

// Log current configuration
Expand Down
14 changes: 10 additions & 4 deletions demo/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -77,31 +77,37 @@ <h3>How it works</h3>
<script>
// Simple configuration setup - let the component handle everything else
document.addEventListener("DOMContentLoaded", () => {
const urlParams = new URLSearchParams(window.location.search);
const relayUrl = urlParams.get("relay") || window.MoQConfig.getRelayUrl();
const publisherElement = document.getElementById("publisher");
const currentEnv = document.getElementById("currentEnv");
const currentRelay = document.getElementById("currentRelay");
const currentStatus = document.getElementById("currentStatus");

// Update config display
if (currentEnv) currentEnv.textContent = window.MoQConfig.getEnvironment();
if (currentRelay) currentRelay.textContent = window.MoQConfig.getRelayUrl();
if (currentRelay) currentRelay.textContent = relayUrl;

// Configure the publisher component
if (publisherElement) {
publisherElement.setAttribute("src", window.MoQConfig.getRelayUrl());
publisherElement.setAttribute("src", relayUrl);

if (window.MoQConfig.getFingerprintUrl()) {
publisherElement.setAttribute("fingerprint", window.MoQConfig.getFingerprintUrl());
}

// Set the playback base URL for the component's generated player links
const baseUrl = window.location.origin + window.location.pathname.replace("index.html", "");
publisherElement.setAttribute("playbackbaseurl", `${baseUrl}player.html?namespace=`);
const playerParams = new URLSearchParams();
if (urlParams.has("relay")) {
playerParams.set("relay", relayUrl);
}
const query = playerParams.toString();
publisherElement.setAttribute("playbackbaseurl", `${baseUrl}player.html${query ? `?${query}&` : "?"}namespace=`);
// Source - https://stackoverflow.com/a
// Posted by Artem Barger, modified by community. See post 'Timeline' for change history
// Retrieved 2025-11-13, License - CC BY-SA 4.0

const urlParams = new URLSearchParams(window.location.search);
const namespace = urlParams.get("namespace");
if (namespace) {
publisherElement.setAttribute("namespace", namespace);
Expand Down
6 changes: 4 additions & 2 deletions demo/player.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ <h4>Stream not loading?</h4>
constructor() {
console.log("MoQTPlayerDemo constructor");
this.namespace = null;
this.relayUrl = null;
this.isConnected = false;
this.videoPlayer = null;
this.startTime = Date.now();
Expand Down Expand Up @@ -200,6 +201,7 @@ <h4>Stream not loading?</h4>
parseUrlParameters() {
const urlParams = new URLSearchParams(window.location.search);
this.namespace = urlParams.get("namespace");
this.relayUrl = urlParams.get("relay") || window.MoQConfig.getRelayUrl();

if (!this.namespace) {
this.showError("No stream namespace provided in URL. Please use a valid player link.");
Expand All @@ -211,7 +213,7 @@ <h4>Stream not loading?</h4>

updateConfigDisplay() {
this.streamNamespace.textContent = this.namespace || "Not specified";
this.streamRelay.textContent = window.MoQConfig.getRelayUrl();
this.streamRelay.textContent = this.relayUrl;
}

async initializePlayer() {
Expand All @@ -233,7 +235,7 @@ <h4>Stream not loading?</h4>
this.videoPlayer.setAttribute("muted", "");

// Configure the video player element with full URL
const srcUrl = `${window.MoQConfig.getRelayUrl()}?namespace=${this.namespace}`;
const srcUrl = `${this.relayUrl}?namespace=${this.namespace}`;
this.videoPlayer.setAttribute("src", srcUrl);
console.log("MoQTPlayerDemo initializePlayer srcUrl", srcUrl);

Expand Down
41 changes: 33 additions & 8 deletions demo/server.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const path = require('path');
const url = require('url');

const PORT = process.env.PORT || 8080;
const DEMO_ROOT = __dirname;
const LIB_DIST_ROOT = path.resolve(__dirname, '..', 'lib', 'dist');

// MIME types for common files
const mimeTypes = {
Expand All @@ -31,13 +33,37 @@ function getContentType(filePath) {
return mimeTypes[ext] || 'application/octet-stream';
}

function safeResolve(root, relativePath) {
const resolved = path.resolve(root, relativePath);
if (resolved === root || resolved.startsWith(root + path.sep)) {
return resolved;
}

return null;
}

function resolvePath(requestPathname) {
const decoded = decodeURIComponent(requestPathname);

if (decoded === '/') {
return safeResolve(DEMO_ROOT, 'index.html');
}

if (decoded.startsWith('/lib/')) {
return safeResolve(LIB_DIST_ROOT, decoded.slice('/lib/'.length));
}

return safeResolve(DEMO_ROOT, decoded.replace(/^\//, ''));
}

const server = http.createServer((req, res) => {
const parsedUrl = url.parse(req.url);
let pathname = `.${parsedUrl.pathname}`;
const pathname = resolvePath(parsedUrl.pathname || '/');

// Default to index.html for root path
if (pathname === './') {
pathname = './index.html';
if (!pathname) {
res.writeHead(403, { 'Content-Type': 'text/plain' });
res.end('403 - Forbidden');
return;
}

// Set required headers for WebTransport and MoQT (enables SharedArrayBuffer)
Expand Down Expand Up @@ -76,10 +102,9 @@ const server = http.createServer((req, res) => {
const contentType = getContentType(pathname);
res.setHeader('Content-Type', contentType);

// Cache control for static assets
if (pathname.endsWith('.js') || pathname.endsWith('.css')) {
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
}
// This server is only used for local development, so always disable
// caching to ensure demo pages pick up fresh rollup output.
res.setHeader('Cache-Control', 'no-store');

const fileStream = fs.createReadStream(pathname);
fileStream.pipe(res);
Expand Down
11 changes: 11 additions & 0 deletions lib/common/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
export { asError } from "./error"
export {
setGlobalLogger,
getGlobalLogger,
createConsoleLogger,
getLogger,
notifyLoggerLevelChanged,
onLoggerLevelChange,
installWorkerLogReceiver,
installWorkletLogReceiver,
} from "./logger"
export type { Logger, LogLevel, LogLevelName, ScopedLogger, WorkerLogRecord } from "./logger"
Loading
Loading