Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decouple the Player from the Web Application #13

Merged
merged 12 commits into from
Jan 7, 2025
2 changes: 2 additions & 0 deletions lib/.eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ module.exports = {
plugins: ["@typescript-eslint", "prettier", "solid"],
root: true,
env: {
commonjs: true,
browser: true,
es2022: true,
worker: true,
Expand Down Expand Up @@ -44,6 +45,7 @@ module.exports = {
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-return": "off",
"@typescript-eslint/no-var-requires": "off",

// Make formatting errors into warnings
"prettier/prettier": 1,
Expand Down
48 changes: 40 additions & 8 deletions lib/package.json
Original file line number Diff line number Diff line change
@@ -1,29 +1,61 @@
{
"name": "@kixelated/moq",
"type": "module",
"version": "0.1.4",
"name": "moq-player",
"version": "0.0.1",
"description": "Media over QUIC library",
"license": "(MIT OR Apache-2.0)",
"repository": "github:kixelated/moq-js",
"entry": "playback/index.ts",
"main": "dist/moq-player.cjs.js",
"module": "dist/moq-player.esm.js",
"iife": "dist/moq-player.iife.js",
"types": "dist/types/moq-player.d.ts",
"scripts": {
"build": "tsc -b && cp ../LICENSE* ./dist && cp ./README.md ./dist && cp ./package.json ./dist",
"lint": "eslint .",
"build": "rollup -c",
"dev": "rollup -c -w",
"lint": "eslint . --ext .js,.ts,.jsx,.tsx",
"fmt": "prettier --write ."
},
"devDependencies": {
"@babel/core": "^7.26.0",
"@babel/preset-env": "^7.26.0",
"@babel/preset-typescript": "^7.26.0",
"@rollup/plugin-babel": "^6.0.4",
"@rollup/plugin-commonjs": "^28.0.1",
"@rollup/plugin-node-resolve": "^15.3.0",
"@rollup/plugin-terser": "^0.4.4",
"@rollup/plugin-typescript": "^12.1.1",
"@types/audioworklet": "^0.0.50",
"@types/dom-mediacapture-transform": "^0.1.6",
"@types/dom-webcodecs": "^0.1.8",
"@typescript/lib-dom": "npm:@types/web@^0.0.115",
"@typescript-eslint/eslint-plugin": "^6.4.0",
"@typescript-eslint/parser": "^6.4.0",
"@typescript/lib-dom": "npm:@types/web@^0.0.115",
"cross-env": "^7.0.2",
"eslint": "^8.47.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"npm-run-all": "^4.1.5",
"prettier": "^3.0.1",
"typescript": "^5.1.6"
"rollup": "^4.28.0",
"rollup-plugin-sourcemaps": "^0.6.2",
"rollup-plugin-web-worker-loader": "github:montevideo-tech/rollup-plugin-web-worker-loader",
"tslib": "^2.8.1",
"typescript": "^5.7.2"
},
"dependencies": {
"mp4box": "^0.5.2"
},
"browserslist": {
"production": [
"chrome >= 97",
"edge >= 98",
"firefox >= 130",
"opera >= 83",
"safari >= 18"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
9 changes: 2 additions & 7 deletions lib/playback/audio.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
/// <reference types="vite/client" />

import * as Message from "./worker/message"

// This is a non-standard way of importing worklet/workers.
// Unfortunately, it's the only option because of a Vite bug: https://github.com/vitejs/vite/issues/11823
import workletURL from "./worklet/index.ts?worker&url"
import registerMyAudioWorklet from "audio-worklet:./worklet/index.ts"

// NOTE: This must be on the main thread
export class Audio {
Expand All @@ -25,8 +21,7 @@ export class Audio {

private async load(config: Message.ConfigAudio): Promise<AudioWorkletNode> {
// Load the worklet source code.
await this.context.audioWorklet.addModule(workletURL)

await registerMyAudioWorklet(this.context)
const volume = this.context.createGain()
volume.gain.value = 2.0

Expand Down
9 changes: 4 additions & 5 deletions lib/playback/backend.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/// <reference types="vite/client" />

import * as Message from "./worker/message"
import { Audio } from "./audio"

import MediaWorker from "./worker?worker"
// import WebWorker from 'web-worker:./Worker.ts';
import MediaWorker from "web-worker:./worker/index.ts"

import { RingShared } from "../common/ring"
import { Root, isAudioTrack } from "../media/catalog"
import { GroupHeader } from "../transport/objects"
Expand All @@ -26,8 +26,7 @@ export default class Backend {

constructor(config: PlayerConfig) {
// TODO does this block the main thread? If so, make this async
// @ts-expect-error: The Vite typing is wrong https://github.com/vitejs/vite/blob/22bd67d70a1390daae19ca33d7de162140d533d6/packages/vite/client.d.ts#L182
this.#worker = new MediaWorker({ format: "es" })
this.#worker = new MediaWorker()
this.#worker.addEventListener("message", this.on.bind(this))

let sampleRate: number | undefined
Expand Down
2 changes: 1 addition & 1 deletion lib/playback/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export interface PlayerConfig {
}

// This class must be created on the main thread due to AudioContext.
export class Player {
export default class Player {
#backend: Backend

// A periodically updated timeline
Expand Down
66 changes: 66 additions & 0 deletions lib/rollup.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
"use strict"
const resolve = require("@rollup/plugin-node-resolve")
const commonjs = require("@rollup/plugin-commonjs")
const typescript = require("@rollup/plugin-typescript")
const workerLoader = require("rollup-plugin-web-worker-loader")
const babel = require("@rollup/plugin-babel")
const terser = require("@rollup/plugin-terser")
const sourceMaps = require("rollup-plugin-sourcemaps")
const pkg = require("./package.json")

const config = []

config.push({
input: pkg.entry,
output: {
file: pkg.iife,
format: "iife",
name: "moqplayer",
sourcemap: true,
},
plugins: [
resolve(),
commonjs({
include: [/node_modules/, /src/],
transformMixedEsModules: true,
}),
workerLoader({ preserveSource: true }),
typescript({
typescript: require("typescript"),
}),
sourceMaps(),
babel({
babelHelpers: "bundled",
presets: ["@babel/preset-env", "@babel/preset-typescript"],
exclude: "./node_modules/*",
}),
terser(),
],
})

config.push({
input: pkg.entry,
output: {
file: pkg.module,
format: "esm",
sourcemap: true,
},
external: [],
plugins: [
resolve(),
commonjs(),
workerLoader({ preserveSource: true }),
typescript({
typescript: require("typescript"),
}),
sourceMaps(),
babel({
babelHelpers: "bundled",
presets: ["@babel/preset-env", "@babel/preset-typescript"],
exclude: "./node_modules/*",
}),
terser(),
],
})

module.exports = config
46 changes: 11 additions & 35 deletions lib/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,42 +1,18 @@
{
"files": [], // don't build anything with these settings.
"compilerOptions": {
"target": "es2022",
"module": "es2022",
"sourceMap": true,
"moduleResolution": "node",
"rootDir": ".",
"module": "es2022",
"target": "es2022",
"lib": ["es2022", "dom"],
JoaquinBCh marked this conversation as resolved.
Show resolved Hide resolved
"outDir": "./dist",
"declaration": true,
"strict": true,
"composite": true,
"declarationMap": true,
"sourceMap": true,
"isolatedModules": true,
"types": [], // Don't automatically import any @types modules.
"lib": ["es2022", "dom"],
"typeRoots": ["./types", "../node_modules/@types"]
"allowJs": false,
"allowSyntheticDefaultImports": true,
"downlevelIteration": true,
"removeComments": false,
"isolatedModules": false,
"noEmit": false
},
"references": [
{
"path": "./common"
},
{
"path": "./playback"
},
{
"path": "./playback/worklet"
},
{
"path": "./contribute"
},
{
"path": "./transport"
},
{
"path": "./media"
}
],
"paths": {
"@/*": ["*"]
}
"exclude": ["node_modules"]
}
9 changes: 9 additions & 0 deletions lib/types/workers.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
declare module "web-worker:*" {
const WorkerFactory: new () => Worker
export default WorkerFactory
}

declare module "audio-worklet:*" {
const value: any
export default value
}
Loading
Loading