@omnimedia/omnitool 1.1.0-96 → 1.1.0-98

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.
package/README.md CHANGED
@@ -207,6 +207,42 @@ Caption options:
207
207
 
208
208
  import `captionPresets` to list available caption looks.
209
209
 
210
+ ## 🧼 Background Remover
211
+
212
+ ```ts
213
+ import {makeBgRemover, defaultBgRemoverSpec} from "@omnimedia/omnitool"
214
+
215
+ const bgRemover = await makeBgRemover({
216
+ spec: defaultBgRemoverSpec(),
217
+ workerUrl: new URL("/features/bg-remover/worker.bundle.min.js", import.meta.url),
218
+ onLoading: loading => console.log("loading", loading),
219
+ })
220
+
221
+ const outputFrame = await bgRemover.remove({frame: inputFrame})
222
+
223
+ bgRemover.dispose()
224
+ ```
225
+
226
+ Use it on image or while decoding a video:
227
+
228
+ ```ts
229
+ const bgRemover = await makeBgRemover({
230
+ spec: defaultBgRemoverSpec(),
231
+ workerUrl: new URL("/features/bg-remover/worker.bundle.min.js", import.meta.url),
232
+ onLoading: loading => console.log("loading", loading),
233
+ })
234
+
235
+ const video = driver.decodeVideo({
236
+ source: file,
237
+ onFrame: frame => bgRemover.remove({frame}),
238
+ })
239
+ ```
240
+
241
+ Notes:
242
+ - `defaultBgRemoverSpec()` uses `Xenova/modnet` on `webgpu` with `auto` dtype.
243
+ - `model`, `device`, and `dtype` are passed to Transformers.js and depend on browser/runtime support.
244
+ - Call `dispose()` when the remover is no longer needed.
245
+
210
246
  ## 🎛 Filters
211
247
 
212
248
  Filter application:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@omnimedia/omnitool",
3
- "version": "1.1.0-96",
3
+ "version": "1.1.0-98",
4
4
  "description": "open source video processing tools",
5
5
  "license": "MIT",
6
6
  "author": "Przemysław Gałęzki",
@@ -6,6 +6,7 @@ import {BackgroundRemovalPipeline} from "@huggingface/transformers"
6
6
  import {PipelineSpec} from "../parts/types.js"
7
7
  import {BgRemoverSchematic} from "./types.js"
8
8
  import {loadPipe} from "../parts/load-pipe.js"
9
+ import {exposeErrors} from "../parts/expose-errors.js"
9
10
 
10
11
  const deferred = defer<{spec: PipelineSpec, pipe: BackgroundRemovalPipeline}>()
11
12
  const makePrepare = (host: Host<BgRemoverSchematic>) => once(async(spec: PipelineSpec) => {
@@ -25,8 +26,8 @@ const ctx = canvas.getContext("2d")
25
26
  await Comrade.worker<BgRemoverSchematic>(shell => {
26
27
  const prepare = makePrepare(shell.host)
27
28
  return {
28
- prepare,
29
- async remove(request) {
29
+ prepare: exposeErrors(prepare),
30
+ remove: exposeErrors(async(request) => {
30
31
  const {pipe} = await deferred.promise
31
32
 
32
33
  canvas.width = request.displayWidth
@@ -44,7 +45,7 @@ await Comrade.worker<BgRemoverSchematic>(shell => {
44
45
  request.close()
45
46
  shell.transfer = [frame]
46
47
  return frame
47
- }
48
+ })
48
49
  }
49
50
  })
50
51
 
@@ -0,0 +1,41 @@
1
+ import {ExposedError} from "@e280/renraku"
2
+
3
+ export function exposeError(error: unknown) {
4
+ if (error instanceof ExposedError)
5
+ return error
6
+
7
+ const exposed = new ExposedError(errorToString(error))
8
+
9
+ if (error instanceof Error)
10
+ exposed.stack = error.stack
11
+
12
+ return exposed
13
+ }
14
+
15
+ export function exposeErrors<Args extends unknown[], Result>(
16
+ fn: (...args: Args) => Result | Promise<Result>
17
+ ) {
18
+ return async(...args: Args) => {
19
+ try {
20
+ return await fn(...args)
21
+ }
22
+ catch (error) {
23
+ throw exposeError(error)
24
+ }
25
+ }
26
+ }
27
+
28
+ function errorToString(error: unknown) {
29
+ if (error instanceof Error)
30
+ return error.message
31
+
32
+ if (typeof error === "string")
33
+ return error
34
+
35
+ try {
36
+ return JSON.stringify(error) ?? String(error)
37
+ }
38
+ catch {
39
+ return String(error)
40
+ }
41
+ }
@@ -5,6 +5,7 @@ import {AutomaticSpeechRecognitionPipeline, Pipeline} from "@huggingface/transfo
5
5
 
6
6
  import {loadPipe} from "../../parts/load-pipe.js"
7
7
  import {transcribe} from "./parts/transcribe.js"
8
+ import {exposeErrors} from "../../parts/expose-errors.js"
8
9
  import {TranscriberSchematic, TranscriberSpec} from "./types.js"
9
10
 
10
11
  const deferred = defer<{pipe: Pipeline, spec: TranscriberSpec}>()
@@ -23,8 +24,8 @@ const makePrepare = (host: Host<TranscriberSchematic>) => once(async(spec: Trans
23
24
  await Comrade.worker<TranscriberSchematic>(shell => {
24
25
  const prepare = makePrepare(shell.host)
25
26
  return {
26
- prepare,
27
- async transcribe(request) {
27
+ prepare: exposeErrors(prepare),
28
+ transcribe: exposeErrors(async(request) => {
28
29
  const {pipe, spec} = await deferred.promise
29
30
  return transcribe({
30
31
  pipe,
@@ -35,7 +36,7 @@ await Comrade.worker<TranscriberSchematic>(shell => {
35
36
  onTranscription: transcription => shell.host.deliverTranscription(transcription),
36
37
  },
37
38
  })
38
- }
39
+ })
39
40
  }
40
41
  })
41
42
 
@@ -12,6 +12,9 @@ export {captionPresets} from "./parts/captions.js"
12
12
  export * from "../features/speech/transcribe/default-spec.js"
13
13
  export * from "../features/speech/transcribe/transcriber.js"
14
14
  export * from "../features/speech/transcribe/types.js"
15
+ export * from "../features/bg-remover/default-spec.js"
16
+ export * from "../features/bg-remover/bg-remover.js"
17
+ export * from "../features/bg-remover/types.js"
15
18
 
16
19
  export * from "./parts/waveform/waveform.js"
17
20
  export * from "./parts/waveform/parts/types.js"