@omnimedia/omnitool 1.1.0-55 → 1.1.0-57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/package.json +1 -1
  2. package/s/demo/demo.bundle.ts +5 -3
  3. package/s/demo/routines/waveform-test.ts +30 -5
  4. package/s/index.html.ts +1 -2
  5. package/s/timeline/index.ts +3 -1
  6. package/s/timeline/parts/waveform/parts/collect.ts +72 -0
  7. package/s/timeline/parts/waveform/parts/render.ts +45 -0
  8. package/s/timeline/parts/waveform/parts/types.ts +24 -0
  9. package/s/timeline/parts/waveform/waveform.ts +155 -0
  10. package/x/demo/demo.bundle.js +2 -0
  11. package/x/demo/demo.bundle.js.map +1 -1
  12. package/x/demo/demo.bundle.min.js +11 -84
  13. package/x/demo/demo.bundle.min.js.map +4 -4
  14. package/x/demo/routines/waveform-test.js +24 -4
  15. package/x/demo/routines/waveform-test.js.map +1 -1
  16. package/x/index.html +3 -3
  17. package/x/index.html.js +1 -1
  18. package/x/timeline/index.d.ts +2 -1
  19. package/x/timeline/index.js +2 -1
  20. package/x/timeline/index.js.map +1 -1
  21. package/x/timeline/parts/waveform/parts/collect.d.ts +11 -0
  22. package/x/timeline/parts/waveform/parts/collect.js +56 -0
  23. package/x/timeline/parts/waveform/parts/collect.js.map +1 -0
  24. package/x/timeline/parts/waveform/parts/render.d.ts +5 -0
  25. package/x/timeline/parts/waveform/parts/render.js +29 -0
  26. package/x/timeline/parts/waveform/parts/render.js.map +1 -0
  27. package/x/timeline/parts/waveform/parts/types.d.ts +21 -0
  28. package/x/timeline/parts/waveform/parts/types.js +2 -0
  29. package/x/timeline/parts/waveform/parts/types.js.map +1 -0
  30. package/x/timeline/parts/waveform/waveform.d.ts +18 -0
  31. package/x/timeline/parts/waveform/waveform.js +128 -0
  32. package/x/timeline/parts/waveform/waveform.js.map +1 -0
  33. package/s/timeline/parts/waveform.ts +0 -61
  34. package/x/timeline/parts/waveform.d.ts +0 -9
  35. package/x/timeline/parts/waveform.js +0 -49
  36. package/x/timeline/parts/waveform.js.map +0 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnimedia/omnitool",
3
- "version": "1.1.0-55",
3
+ "version": "1.1.0-57",
4
4
  "description": "open source video processing tools",
5
5
  "license": "MIT",
6
6
  "author": "Przemysław Gałęzki",
@@ -26,8 +26,11 @@ let exportState: {timeline: TimelineFile; omni: Omni} | null = null
26
26
  }
27
27
 
28
28
  const setProgress = (card: HTMLElement, state: "idle" | "running" | "done") => {
29
- const progress = card.querySelector(".progress") as HTMLProgressElement
30
- const status = card.querySelector(".status") as HTMLSpanElement
29
+ const progress = card.querySelector(".progress") as HTMLProgressElement | null
30
+ const status = card.querySelector(".status") as HTMLSpanElement | null
31
+
32
+ if (!progress || !status)
33
+ return
31
34
 
32
35
  if (state === "running") {
33
36
  progress.removeAttribute("value")
@@ -124,4 +127,3 @@ exportButton.addEventListener("click", async () => {
124
127
  await exportState.omni.render(exportState.timeline)
125
128
  setProgress(exportCard, "done")
126
129
  })
127
-
@@ -1,14 +1,39 @@
1
+
1
2
  import {Driver} from "../../driver/driver.js"
2
- import {Waveform} from "../../timeline/parts/waveform.js"
3
+ import {Waveform} from "../../timeline/parts/waveform/waveform.js"
3
4
 
4
5
  export async function waveformTest(driver: Driver, source: File, root: HTMLElement) {
5
- const container = root.querySelector(".waveform-canvas") as HTMLElement
6
+ const container = root.querySelector(".waveform-canvas") as HTMLDivElement
6
7
  const widthSlider = root.querySelector(".width") as HTMLInputElement
8
+
7
9
  container.replaceChildren()
8
- const waveform = await Waveform.init(driver, source, container)
10
+ container.style.position = "relative"
11
+ container.style.height = "96px"
12
+ container.style.overflow = "hidden"
13
+
14
+ const waveform = await Waveform.init(driver, source, {
15
+ tileHeight: 96,
16
+ onChange: () => renderTiles()
17
+ })
9
18
 
10
- widthSlider.oninput = () => {
19
+ const renderTiles = () => {
11
20
  const width = +widthSlider.value
12
- waveform.width = width
21
+ const zoom = pixelsPerSecond(width, waveform.duration)
22
+ waveform.zoom = zoom
23
+ container.style.width = `${width}px`
24
+ container.replaceChildren(...[...waveform.getTiles().values()].map(tile => {
25
+ tile.canvas.style.position = "absolute"
26
+ tile.canvas.style.top = "0"
27
+ tile.canvas.style.left = `${tile.startTime * pixelsPerSecond(width, waveform.duration)}px`
28
+ tile.canvas.style.height = "100%"
29
+ return tile.canvas
30
+ }))
13
31
  }
32
+
33
+ widthSlider.oninput = renderTiles
34
+ waveform.range = [0, waveform.duration]
35
+ }
36
+
37
+ function pixelsPerSecond(width: number, duration: number) {
38
+ return duration > 0 ? width / duration : 0
14
39
  }
package/s/index.html.ts CHANGED
@@ -85,7 +85,7 @@ export default ssg.page(import.meta.url, async orb => ({
85
85
  </div>
86
86
  <div class="waveform-controls">
87
87
  <label>width</label>
88
- <input class="width" type="range" min="100" max="1000000" value="1000" />
88
+ <input class="width" type="range" min="100" max="1000000" value="1000" step="100" />
89
89
  </div>
90
90
  <div class="waveform-canvas"></div>
91
91
  </article>
@@ -134,4 +134,3 @@ export default ssg.page(import.meta.url, async orb => ({
134
134
  </section>
135
135
  `,
136
136
  }))
137
-
@@ -5,7 +5,9 @@ export * from "./parts/media.js"
5
5
  export * from "./parts/resource-pool.js"
6
6
  export * from "./parts/resource.js"
7
7
  export * from "./parts/filmstrip.js"
8
- export * from "./parts/waveform.js"
8
+
9
+ export * from "./parts/waveform/waveform.js"
10
+ export * from "./parts/waveform/parts/types.js"
9
11
  export * from "./renderers/player/player.js"
10
12
 
11
13
  export * from "./sugar/o.js"
@@ -0,0 +1,72 @@
1
+
2
+ import {Driver} from "../../../../driver/driver.js"
3
+ import {DecoderSource} from "../../../../driver/fns/schematic.js"
4
+
5
+ export const PEAK_LEVELS = [2048, 1024, 512, 256, 128, 64, 32] as const
6
+
7
+ export async function collectPeakLevels(driver: Driver, source: DecoderSource) {
8
+ const duration = (await driver.getAudioDuration(source)) ?? 0
9
+ const readable = driver.decodeAudio({source}).readable
10
+ const finestSamplesPerPeak = PEAK_LEVELS[PEAK_LEVELS.length - 1]
11
+ const finestPeaks: number[] = []
12
+
13
+ let currentMax = 0
14
+ let sampleCount = 0
15
+ let sampleRate = 0
16
+
17
+ for await (const audioData of readable) {
18
+ sampleRate ||= audioData.sampleRate
19
+
20
+ const frames = audioData.numberOfFrames
21
+ const plane = new Float32Array(frames)
22
+ audioData.copyTo(plane, {planeIndex: 0})
23
+
24
+ for (let i = 0; i < plane.length; i++) {
25
+ const amplitude = Math.abs(plane[i]!)
26
+ if (amplitude > currentMax) currentMax = amplitude
27
+
28
+ sampleCount++
29
+ if (sampleCount >= finestSamplesPerPeak) {
30
+ finestPeaks.push(currentMax)
31
+ currentMax = 0
32
+ sampleCount = 0
33
+ }
34
+ }
35
+
36
+ audioData.close()
37
+ }
38
+
39
+ if (sampleCount > 0) finestPeaks.push(currentMax)
40
+
41
+ const base = new Float32Array(finestPeaks)
42
+ const levels = PEAK_LEVELS.map(samplesPerPeak => {
43
+ const factor = Math.max(1, Math.round(samplesPerPeak / finestSamplesPerPeak))
44
+ const peaks = factor === 1 ? base : downsampleMax(base, factor)
45
+ return {
46
+ samplesPerPeak,
47
+ peaks,
48
+ peaksPerSecond: sampleRate > 0 ? sampleRate / samplesPerPeak : 0,
49
+ }
50
+ })
51
+
52
+ return {duration, levels}
53
+ }
54
+
55
+ function downsampleMax(peaks: Float32Array, factor: number) {
56
+ const downsampled = new Float32Array(Math.ceil(peaks.length / factor))
57
+
58
+ for (let i = 0; i < downsampled.length; i++) {
59
+ let maxPeak = 0
60
+ const start = i * factor
61
+ const end = Math.min(start + factor, peaks.length)
62
+
63
+ for (let j = start; j < end; j++) {
64
+ if (peaks[j]! > maxPeak) maxPeak = peaks[j]!
65
+ }
66
+
67
+ downsampled[i] = maxPeak
68
+ }
69
+
70
+ return downsampled
71
+ }
72
+
@@ -0,0 +1,45 @@
1
+
2
+ export function renderTile(
3
+ peaks: Float32Array,
4
+ opts: {
5
+ width: number
6
+ height: number
7
+ color: string
8
+ }
9
+ ) {
10
+ const dpr = typeof window !== "undefined" ? window.devicePixelRatio || 1 : 1
11
+ const canvas = document.createElement("canvas")
12
+ canvas.width = opts.width * dpr
13
+ canvas.height = opts.height * dpr
14
+ canvas.style.width = `${opts.width}px`
15
+ canvas.style.height = `${opts.height}px`
16
+
17
+ const ctx = canvas.getContext("2d")
18
+ if (!ctx) return canvas
19
+
20
+ ctx.scale(dpr, dpr)
21
+ ctx.fillStyle = opts.color
22
+
23
+ const centerY = opts.height / 2
24
+ const columns = Math.max(1, opts.width)
25
+ const peaksPerPixel = peaks.length / columns
26
+
27
+ for (let px = 0; px < columns; px++) {
28
+ const startIndex = Math.floor(px * peaksPerPixel)
29
+ const endIndex = Math.max(
30
+ startIndex + 1,
31
+ Math.floor((px + 1) * peaksPerPixel)
32
+ )
33
+
34
+ let maxPeak = 0
35
+ for (let i = startIndex; i < endIndex && i < peaks.length; i++) {
36
+ if (peaks[i]! > maxPeak) maxPeak = peaks[i]!
37
+ }
38
+
39
+ const barHeight = maxPeak * opts.height
40
+ ctx.fillRect(px, centerY - barHeight / 2, 1, barHeight)
41
+ }
42
+
43
+ return canvas
44
+ }
45
+
@@ -0,0 +1,24 @@
1
+ export interface WaveformTileData {
2
+ startTime: number
3
+ endTime: number
4
+ peaks: Float32Array
5
+ canvas: HTMLCanvasElement
6
+ }
7
+
8
+ export interface WaveformOptions {
9
+ tileSize?: number
10
+ zoom?: number
11
+ tileWidth?: number
12
+ tileHeight?: number
13
+ preloadMargin?: number
14
+ color?: string
15
+ onChange?: (tiles: WaveformTileData[]) => void
16
+ }
17
+
18
+ export type WaveformTimeRange = [start: number, end: number]
19
+
20
+ export type WaveformPeakLevel = {
21
+ samplesPerPeak: number
22
+ peaks: Float32Array
23
+ peaksPerSecond: number
24
+ }
@@ -0,0 +1,155 @@
1
+
2
+ import {renderTile} from "./parts/render.js"
3
+ import {Driver} from "../../../driver/driver.js"
4
+ import {collectPeakLevels} from "./parts/collect.js"
5
+ import {DecoderSource} from "../../../driver/fns/schematic.js"
6
+ import {WaveformOptions, WaveformPeakLevel, WaveformTileData, WaveformTimeRange} from "./parts/types.js"
7
+
8
+ const MAX_TILE_WIDTH = 4096
9
+
10
+ export class Waveform {
11
+ #tiles = new Map<number, WaveformTileData>()
12
+ #activeRange: WaveformTimeRange = [0, 0]
13
+
14
+ #zoom
15
+ #levels
16
+ #onChange
17
+ #updateQueued = false
18
+
19
+ readonly color
20
+ readonly duration
21
+ readonly tileSize
22
+ readonly tileHeight
23
+ readonly preloadMargin
24
+
25
+ private constructor(levels: WaveformPeakLevel[], duration: number, options: WaveformOptions) {
26
+ this.#levels = levels
27
+ this.duration = duration
28
+ this.tileSize = options.tileSize ?? 1
29
+ this.#zoom = options.zoom ?? ((options.tileWidth ?? 256) / this.tileSize)
30
+ this.tileHeight = options.tileHeight ?? 96
31
+ this.preloadMargin = options.preloadMargin ?? 2
32
+ this.color = options.color ?? "rgb(3, 148, 129)"
33
+ this.#onChange = options.onChange
34
+ }
35
+
36
+ static async init(driver: Driver, source: DecoderSource, options: WaveformOptions = {}) {
37
+ const {duration, levels} = await collectPeakLevels(driver, source)
38
+ return new Waveform(levels, duration, options)
39
+ }
40
+
41
+ set zoom(value: number) {
42
+ const next = Math.max(1, value)
43
+ if (next === this.#zoom)
44
+ return
45
+
46
+ this.#zoom = next
47
+ this.#tiles.clear()
48
+ this.#queueUpdate()
49
+ }
50
+
51
+ get zoom() {
52
+ return this.#zoom
53
+ }
54
+
55
+ get range() {
56
+ return this.#activeRange
57
+ }
58
+
59
+ #computeActiveRange([start, end]: WaveformTimeRange, margin = 1): WaveformTimeRange {
60
+ const visibleSize = end - start
61
+ return [
62
+ Math.max(0, start - visibleSize * margin),
63
+ Math.min(this.duration, end + visibleSize * margin),
64
+ ]
65
+ }
66
+
67
+ set range(visibleRange: WaveformTimeRange) {
68
+ const [visibleStart, visibleEnd] = visibleRange
69
+ const visibleSize = visibleEnd - visibleStart
70
+ const [activeStart, activeEnd] = this.#activeRange
71
+
72
+ const leftTrigger = activeStart + visibleSize
73
+ const rightTrigger = activeEnd - visibleSize
74
+
75
+ if (visibleStart >= leftTrigger && visibleEnd <= rightTrigger) return
76
+
77
+ this.#activeRange = this.#computeActiveRange(visibleRange, this.preloadMargin)
78
+ this.#queueUpdate()
79
+ }
80
+
81
+ #queueUpdate() {
82
+ if (this.#updateQueued) return
83
+ this.#updateQueued = true
84
+
85
+ queueMicrotask(() => {
86
+ this.#updateQueued = false
87
+ this.#generateTiles()
88
+ })
89
+ }
90
+
91
+ #generateTiles() {
92
+ const [rangeStart, rangeEnd] = this.#activeRange
93
+ const neededStarts = new Set<number>()
94
+ const level = this.#levelForZoom()
95
+
96
+ const firstStart = Math.max(0, Math.floor(rangeStart / this.tileSize) * this.tileSize)
97
+ const lastStart = Math.min(this.duration, rangeEnd)
98
+
99
+ for (let startTime = firstStart; startTime <= lastStart; startTime += this.tileSize) {
100
+ neededStarts.add(startTime)
101
+ }
102
+
103
+ for (const startTime of neededStarts) {
104
+ if (!this.#tiles.has(startTime)) {
105
+ const endTime = Math.min(startTime + this.tileSize, this.duration)
106
+ this.#tiles.set(startTime, this.#buildTileData(startTime, endTime, level))
107
+ }
108
+ }
109
+
110
+ for (const startTime of this.#tiles.keys()) {
111
+ if (!neededStarts.has(startTime)) this.#tiles.delete(startTime)
112
+ }
113
+
114
+ this.#emit()
115
+ }
116
+
117
+ #buildTileData(startTime: number, endTime: number, level: WaveformPeakLevel): WaveformTileData {
118
+ const peaks = this.#slicePeaks(level, startTime, endTime)
119
+ return {
120
+ startTime,
121
+ endTime,
122
+ peaks,
123
+ canvas: renderTile(peaks, {
124
+ width: this.#tilePixelWidth(startTime, endTime),
125
+ height: this.tileHeight,
126
+ color: this.color,
127
+ }),
128
+ }
129
+ }
130
+
131
+ #levelForZoom() {
132
+ return this.#levels.find(level => level.peaksPerSecond >= this.#zoom)
133
+ ?? this.#levels[this.#levels.length - 1]!
134
+ }
135
+
136
+ #slicePeaks(level: WaveformPeakLevel, startTime: number, endTime: number) {
137
+ if (!level.peaksPerSecond) return new Float32Array()
138
+ const from = Math.max(0, Math.floor(startTime * level.peaksPerSecond))
139
+ const to = Math.max(from + 1, Math.min(level.peaks.length, Math.ceil(endTime * level.peaksPerSecond)))
140
+ return level.peaks.slice(from, to)
141
+ }
142
+
143
+ #tilePixelWidth(startTime: number, endTime: number) {
144
+ return Math.min(MAX_TILE_WIDTH, Math.max(1, Math.ceil((endTime - startTime) * this.#zoom)))
145
+ }
146
+
147
+ #emit() {
148
+ if (!this.#onChange) return
149
+ this.#onChange([...this.#tiles.values()].sort((a, b) => a.startTime - b.startTime))
150
+ }
151
+
152
+ getTiles() {
153
+ return this.#tiles
154
+ }
155
+ }
@@ -23,6 +23,8 @@ let exportState = null;
23
23
  const setProgress = (card, state) => {
24
24
  const progress = card.querySelector(".progress");
25
25
  const status = card.querySelector(".status");
26
+ if (!progress || !status)
27
+ return;
26
28
  if (state === "running") {
27
29
  progress.removeAttribute("value");
28
30
  status.textContent = "running";
@@ -1 +1 @@
1
- {"version":3,"file":"demo.bundle.js","sourceRoot":"","sources":["../../s/demo/demo.bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"demo.bundle.js","sourceRoot":"","sources":["../../s/demo/demo.bundle.ts"],"names":[],"mappings":"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"}