@omnimedia/omnitool 1.1.0-101 → 1.1.0-103

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 (38) hide show
  1. package/README.md +2 -0
  2. package/package.json +2 -1
  3. package/s/driver/driver.ts +4 -0
  4. package/s/driver/parts/compositor.ts +4 -0
  5. package/s/features/speech/transcribe/parts/prep-audio.ts +19 -14
  6. package/s/timeline/parts/basics.ts +1 -1
  7. package/s/timeline/parts/resource-pool.ts +2 -2
  8. package/s/timeline/parts/resource.ts +0 -1
  9. package/s/timeline/renderers/player/player.ts +4 -0
  10. package/s/timeline/utils/checksum.ts +12 -9
  11. package/s/timeline/utils/datafile.ts +2 -12
  12. package/x/demo/demo.bundle.min.js +103 -103
  13. package/x/demo/demo.bundle.min.js.map +4 -4
  14. package/x/driver/driver.d.ts +1 -0
  15. package/x/driver/driver.js +3 -0
  16. package/x/driver/driver.js.map +1 -1
  17. package/x/driver/parts/compositor.d.ts +1 -0
  18. package/x/driver/parts/compositor.js +3 -0
  19. package/x/driver/parts/compositor.js.map +1 -1
  20. package/x/features/speech/transcribe/parts/prep-audio.js +17 -13
  21. package/x/features/speech/transcribe/parts/prep-audio.js.map +1 -1
  22. package/x/index.html +2 -2
  23. package/x/tests.bundle.min.js +109 -109
  24. package/x/tests.bundle.min.js.map +4 -4
  25. package/x/tests.html +1 -1
  26. package/x/timeline/parts/basics.d.ts +1 -1
  27. package/x/timeline/parts/resource-pool.js +2 -2
  28. package/x/timeline/parts/resource-pool.js.map +1 -1
  29. package/x/timeline/parts/resource.d.ts +0 -1
  30. package/x/timeline/renderers/player/player.d.ts +1 -0
  31. package/x/timeline/renderers/player/player.js +3 -0
  32. package/x/timeline/renderers/player/player.js.map +1 -1
  33. package/x/timeline/utils/checksum.d.ts +2 -4
  34. package/x/timeline/utils/checksum.js +11 -12
  35. package/x/timeline/utils/checksum.js.map +1 -1
  36. package/x/timeline/utils/datafile.d.ts +1 -2
  37. package/x/timeline/utils/datafile.js +3 -14
  38. package/x/timeline/utils/datafile.js.map +1 -1
package/README.md CHANGED
@@ -509,6 +509,7 @@ const driver = await Driver.setup({workerUrl})
509
509
  const player = await omni.playback(timeline)
510
510
 
511
511
  document.body.appendChild(player.canvas)
512
+ player.resize(1280, 720)
512
513
  await player.play()
513
514
  player.playbackRate = 0.5 // slow motion
514
515
  player.playbackRate = -1 // reverse
@@ -516,6 +517,7 @@ player.playbackRate = -1 // reverse
516
517
 
517
518
  Notes:
518
519
  - Call `await player.update(timeline)` if you update the timeline.
520
+ - Call `player.resize(width, height)` to resize the preview canvas.
519
521
  - `playbackRate` supports slower, faster, and reverse visual playback. Audio currently plays only at `1`.
520
522
 
521
523
  ## 📤 Export
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnimedia/omnitool",
3
- "version": "1.1.0-101",
3
+ "version": "1.1.0-103",
4
4
  "description": "open source video processing tools",
5
5
  "license": "MIT",
6
6
  "author": "Przemysław Gałęzki",
@@ -38,6 +38,7 @@
38
38
  "@e280/strata": "^0.2.5",
39
39
  "@e280/stz": "^0.2.15",
40
40
  "@huggingface/transformers": "^3.8.1",
41
+ "@noble/hashes": "^2.2.0",
41
42
  "comrade": "^0.0.3",
42
43
  "gl-transitions": "^1.43.0",
43
44
  "gsap": "^3.14.2",
@@ -121,5 +121,9 @@ export class Driver {
121
121
  return await this.compositor.composite(composition)
122
122
  }
123
123
 
124
+ resize(width: number, height: number) {
125
+ this.compositor.resize(width, height)
126
+ }
127
+
124
128
  }
125
129
 
@@ -47,6 +47,10 @@ export class Compositor {
47
47
  #activeObjects = new Map<number, {sprite: Container, dispose: () => void}>()
48
48
  #cropMasks = new WeakMap<Container, Graphics>()
49
49
 
50
+ resize(width: number, height: number) {
51
+ this.pixi.renderer.resize(width, height)
52
+ }
53
+
50
54
  async composite(
51
55
  composition: Composition,
52
56
  ) {
@@ -4,20 +4,25 @@ import {Driver} from "../../../../driver/driver.js"
4
4
  export async function prepAudio(driver: Driver, source: Blob) {
5
5
  const arrayBuffer = await source.arrayBuffer()
6
6
  const audioCTX = new AudioContext({sampleRate: 16000})
7
- const audioData = await audioCTX.decodeAudioData(arrayBuffer)
8
- let audio: Float32Array
9
- if (audioData.numberOfChannels === 2) {
10
- const SCALING_FACTOR = Math.sqrt(2)
11
- const left = audioData.getChannelData(0)
12
- const right = audioData.getChannelData(1)
13
- audio = new Float32Array(left.length)
14
- for (let i = 0; i < audioData.length; ++i) {
15
- audio[i] = (SCALING_FACTOR * (left[i] + right[i])) / 2
7
+ try {
8
+ const audioData = await audioCTX.decodeAudioData(arrayBuffer)
9
+ let audio: Float32Array
10
+
11
+ if (audioData.numberOfChannels === 2) {
12
+ const SCALING_FACTOR = Math.sqrt(2)
13
+ const left = audioData.getChannelData(0)
14
+ const right = audioData.getChannelData(1)
15
+ audio = new Float32Array(left.length)
16
+
17
+ for (let i = 0; i < audioData.length; ++i)
18
+ audio[i] = (SCALING_FACTOR * (left[i] + right[i])) / 2
19
+ } else {
20
+ audio = audioData.getChannelData(0)
16
21
  }
17
- } else {
18
- audio = audioData.getChannelData(0)
22
+
23
+ const duration = await driver.getAudioDuration(source)
24
+ return {audio, duration}
25
+ } finally {
26
+ await audioCTX.close()
19
27
  }
20
- const duration = await driver.getAudioDuration(source)
21
- return {audio, duration}
22
28
  }
23
-
@@ -1,7 +1,7 @@
1
1
 
2
2
  import {Item} from "./item.js"
3
3
 
4
- /** sha256 hash */
4
+ /** BLAKE3 hash */
5
5
  export type Hash = string
6
6
 
7
7
  /** item identifier */
@@ -12,14 +12,14 @@ export class ResourcePool {
12
12
  async store(datafile: Datafile) {
13
13
  const media = await Media.analyze(datafile)
14
14
  const {hash} = media.datafile.checksum
15
- const {filename, bytes, url, blob} = media.datafile
15
+ const {filename, url, blob} = media.datafile
16
16
 
17
17
  if (this.#map.has(hash)) {
18
18
  const alreadyExists = this.#map.require(hash)
19
19
  alreadyExists.filename = filename
20
20
  }
21
21
  else
22
- this.#map.set(hash, {kind: "media", filename, bytes, url, blob, duration: media.duration})
22
+ this.#map.set(hash, {kind: "media", filename, url, blob, duration: media.duration})
23
23
 
24
24
  return media
25
25
  }
@@ -3,7 +3,6 @@ export namespace Resource {
3
3
  export type Media = {
4
4
  kind: "media"
5
5
  filename: string
6
- bytes: Uint8Array
7
6
  blob: Blob
8
7
  url: string
9
8
  duration: number
@@ -41,6 +41,10 @@ export class VideoPlayer {
41
41
  this.playback.setFps(fps(value))
42
42
  }
43
43
 
44
+ resize(width: number, height: number) {
45
+ this.driver.resize(width, height)
46
+ }
47
+
44
48
  get isSeeking() {
45
49
  return this.#flushTask !== null
46
50
  }
@@ -1,22 +1,25 @@
1
1
 
2
- import {Hex, Thumbprint} from "@e280/stz"
2
+ import {hex, thumbprint} from "@e280/stz"
3
+ import {blake3} from "@noble/hashes/blake3.js"
3
4
 
4
5
  import {Hash} from "../parts/basics.js"
5
6
 
6
7
  export class Checksum {
7
8
  constructor(
8
- public data: Uint8Array,
9
- public bytes: Uint8Array,
10
9
  public hash: Hash,
11
10
  public nickname: string,
12
11
  ) {}
13
12
 
14
- static async make(data: Uint8Array) {
15
- const data2 = new Uint8Array(data)
16
- const bytes = new Uint8Array(await crypto.subtle.digest("SHA-256", data2))
17
- const hash = Hex.fromBytes(bytes)
18
- const nickname = Thumbprint.sigil.fromBytes(bytes)
19
- return new this(data, bytes, hash, nickname)
13
+ static async make(file: Blob) {
14
+ const hasher = blake3.create()
15
+
16
+ for await (const chunk of file.stream())
17
+ hasher.update(chunk)
18
+
19
+ const digest = hasher.digest()
20
+ const hash = hex.fromBytes(digest)
21
+ const nickname = thumbprint.sigil.fromBytes(digest)
22
+ return new this(hash, nickname)
20
23
  }
21
24
  }
22
25
 
@@ -4,29 +4,19 @@ import {Checksum} from "./checksum.js"
4
4
  export class Datafile {
5
5
  constructor(
6
6
  public url: string,
7
- public bytes: Uint8Array,
8
7
  public blob: Blob,
9
8
  public filename: string,
10
9
  public checksum: Checksum,
11
10
  ) {}
12
11
 
13
12
  static async make(file: Blob, name?: string) {
14
- const buffer = await file.arrayBuffer()
15
- const bytes = new Uint8Array(buffer)
16
- const checksum = await Checksum.make(bytes)
13
+ const checksum = await Checksum.make(file)
17
14
  const filename = name ?? checksum.nickname
18
15
  const url = URL.createObjectURL(file)
19
- return new this(url, bytes, file, filename, checksum)
16
+ return new this(url, file, filename, checksum)
20
17
  }
21
18
 
22
19
  static async load(path: string) {
23
- // const file = await fetch(path)
24
- // const buffer = await file.arrayBuffer()
25
- // const bytes = new Uint8Array(buffer)
26
- // const filename = file?.headers.get('Content-Disposition')?.split('filename=')[1] ?? "file"
27
- // console.log(filename)
28
- // const checksum = await Checksum.make(bytes)
29
- // return new this(path, bytes, filename, checksum)
30
20
  }
31
21
  }
32
22