pixi-effects 0.47.5 → 0.48.0

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.
@@ -1,11 +1,11 @@
1
1
  import { CompositionSequence, maskSourceOf } from './chunk-UI7CEUTP.js';
2
+ import { loadMediabunny } from './chunk-K3XOEC3C.js';
2
3
  import { EXPRESSION_NAMES, createTimeline, lengthen, ensureFilterLibrary, checkEase, parseEase, homeDistance, DEFAULT_FOV, random, noise, flattenSvgPath, trimPolylines, rand, DEG, timeRemapOf, contentLength, resolveAt, parseSpring, springDuration, spansMeta } from './chunk-4PYVHLIK.js';
3
4
  import { analyzeAudio, fft, resampleThrough, playSpan, measureLoudness } from './chunk-G4PXCV2B.js';
4
5
  import { usesAdvancedBlend, enableAdvancedBlend } from './chunk-JBDBICS2.js';
5
6
  import { describeLayer } from './chunk-BFRWSV3R.js';
6
7
  import { warnUnknownOptions, suggestName } from './chunk-WGRWFQOB.js';
7
8
  import { extensions, CullerPlugin, Application, Container, Rectangle, Culler, CanvasTextMetrics, TextStyle, Assets, ExtensionType, Filter, Texture, UniformGroup, GpuProgram, GlProgram, defaultFilterVert, Text, CanvasTextGenerator, CanvasPool } from 'pixi.js';
8
- import { Output, BufferTarget, CanvasSource, AudioBufferSource, Input, ALL_FORMATS, BlobSource, WavOutputFormat, Conversion, VideoSampleSink, OggOutputFormat, QUALITY_VERY_HIGH, QUALITY_HIGH, QUALITY_MEDIUM, QUALITY_LOW, QUALITY_VERY_LOW, MkvOutputFormat, WebMOutputFormat, MovOutputFormat, Mp4OutputFormat, canEncodeVideo, getFirstEncodableAudioCodec } from 'mediabunny';
9
9
 
10
10
  // src/core/gpuShare.ts
11
11
  function sharedGpuOf(renderer) {
@@ -41,7 +41,8 @@ function ensureLoadersRegistered(audioContext) {
41
41
  extension: { type: ExtensionType.LoadParser, name: "pixi-effects-video", priority: 1 },
42
42
  test: (url) => /\.(mp4|webm|mov|mkv)$/i.test(url),
43
43
  async load(url) {
44
- const blob = await fetch(url).then((r) => r.blob());
44
+ const [M, blob] = await Promise.all([loadMediabunny(), fetch(url).then((r) => r.blob())]);
45
+ const { Input, BlobSource, ALL_FORMATS, Output, WavOutputFormat, BufferTarget, Conversion, VideoSampleSink } = M;
45
46
  const input = new Input({ source: new BlobSource(blob), formats: ALL_FORMATS });
46
47
  const videoTrack = await input.getPrimaryVideoTrack();
47
48
  if (!videoTrack || !await videoTrack.canDecode()) {
@@ -598,10 +599,10 @@ var AUDIO_PREFERENCE = {
598
599
  mkv: ["opus", "vorbis", "aac", "flac", "mp3"],
599
600
  ogg: ["opus", "vorbis", "flac"]
600
601
  };
601
- async function chooseAudioCodec(fmt, requested, container, audio, bitrate) {
602
+ async function chooseAudioCodec(M, fmt, requested, container, audio, bitrate) {
602
603
  const supported = container.getSupportedAudioCodecs?.();
603
604
  const preferred = AUDIO_PREFERENCE[fmt].filter((c) => !supported || supported.includes(c));
604
- const canEncode = (list) => getFirstEncodableAudioCodec(list, { numberOfChannels: audio.numberOfChannels ?? 2, sampleRate: audio.sampleRate, bitrate });
605
+ const canEncode = (list) => M.getFirstEncodableAudioCodec(list, { numberOfChannels: audio.numberOfChannels ?? 2, sampleRate: audio.sampleRate, bitrate });
605
606
  if (requested) {
606
607
  if (await canEncode([requested])) return requested;
607
608
  const alt = await canEncode(preferred.filter((c) => c !== requested));
@@ -614,27 +615,34 @@ async function chooseAudioCodec(fmt, requested, container, audio, bitrate) {
614
615
  }
615
616
  return chosen;
616
617
  }
617
- var qualityMap = {
618
- "very-low": QUALITY_VERY_LOW,
619
- "low": QUALITY_LOW,
620
- "medium": QUALITY_MEDIUM,
621
- "high": QUALITY_HIGH,
622
- "very-high": QUALITY_VERY_HIGH
623
- };
624
- function bitrateOf(v, fallback) {
618
+ function qualityOf(M, name) {
619
+ switch (name) {
620
+ case "very-low":
621
+ return M.QUALITY_VERY_LOW;
622
+ case "low":
623
+ return M.QUALITY_LOW;
624
+ case "medium":
625
+ return M.QUALITY_MEDIUM;
626
+ case "very-high":
627
+ return M.QUALITY_VERY_HIGH;
628
+ default:
629
+ return M.QUALITY_HIGH;
630
+ }
631
+ }
632
+ function bitrateOf(M, v) {
625
633
  const b = parseBitrate(v);
626
- return b.bps ?? (b.quality ? qualityMap[b.quality] : fallback);
634
+ return b.bps ?? qualityOf(M, b.quality ?? "high");
627
635
  }
628
- function makeOutputFormat(name) {
636
+ function makeOutputFormat(M, name) {
629
637
  switch (name) {
630
638
  case "mp4":
631
- return new Mp4OutputFormat({ fastStart: "in-memory" });
639
+ return new M.Mp4OutputFormat({ fastStart: "in-memory" });
632
640
  case "mov":
633
- return new MovOutputFormat({ fastStart: "in-memory" });
641
+ return new M.MovOutputFormat({ fastStart: "in-memory" });
634
642
  case "webm":
635
- return new WebMOutputFormat();
643
+ return new M.WebMOutputFormat();
636
644
  case "mkv":
637
- return new MkvOutputFormat();
645
+ return new M.MkvOutputFormat();
638
646
  }
639
647
  }
640
648
  function sliceAudio(buffer, fromSec, toSec, fadeIn, fadeOut) {
@@ -649,18 +657,19 @@ async function exportAudioOnly(movie, options, fmt, range2) {
649
657
  throw new Error(`pixi-effects: render({ format: '${fmt}' }): this movie has no sound to export (add an audio layer, an sfx or a music score); for the picture use mp4, webm, mov or mkv`);
650
658
  }
651
659
  if (options.video) console.warn(`pixi-effects: render({ format: '${fmt}' }): video options are ignored, only the sound is written`);
660
+ const M = await loadMediabunny();
652
661
  const audio = range2.partial ? sliceAudio(movie.audioBuffer, range2.fromSec, range2.toSec, range2.fromFrame > 0, range2.toFrame < movie.totalFrames) : movie.audioBuffer;
653
- const container = fmt === "wav" ? new WavOutputFormat() : new OggOutputFormat();
662
+ const container = fmt === "wav" ? new M.WavOutputFormat() : new M.OggOutputFormat();
654
663
  let codec;
655
664
  if (fmt === "wav") {
656
665
  codec = options.audio?.codec ?? "pcm-s16";
657
666
  const held = container.getSupportedAudioCodecs();
658
667
  if (!held.includes(codec)) throw new Error(`pixi-effects: render({ format: 'wav', audio: { codec: "${codec}" } }): wav holds ${held.join(", ")} (the usual is pcm-s16)`);
659
668
  } else {
660
- codec = await chooseAudioCodec("ogg", options.audio?.codec, container, audio, bitrateOf(options.audio?.bitrate, QUALITY_HIGH));
669
+ codec = await chooseAudioCodec(M, "ogg", options.audio?.codec, container, audio, bitrateOf(M, options.audio?.bitrate));
661
670
  }
662
- const output = new Output({ format: container, target: new BufferTarget() });
663
- const source = new AudioBufferSource({ codec, ...fmt === "wav" ? {} : { bitrate: bitrateOf(options.audio?.bitrate, QUALITY_HIGH) } });
671
+ const output = new M.Output({ format: container, target: new M.BufferTarget() });
672
+ const source = new M.AudioBufferSource({ codec, ...fmt === "wav" ? {} : { bitrate: bitrateOf(M, options.audio?.bitrate) } });
664
673
  output.addAudioTrack(source);
665
674
  movie.emit("progress", { progress: 0, frame: range2.fromFrame, totalFrames: movie.totalFrames });
666
675
  await output.start();
@@ -678,21 +687,22 @@ async function exportFrames(movie, options = {}) {
678
687
  if (!["mp4", "mov", "webm", "mkv"].includes(fmt)) throw new Error(`pixi-effects: render({ format: "${String(fmt)}" }): use mp4, mov, webm, mkv (a picture) or wav, ogg (only the sound)`);
679
688
  warnUnknownOptions("movie.render({ video })", options.video, ["codec", "bitrate", "hardware", "keyFrameInterval"]);
680
689
  warnUnknownOptions("movie.render({ audio })", options.audio, ["codec", "bitrate"]);
681
- const videoBitrate = bitrateOf(eff.bitrate ?? "high", QUALITY_HIGH);
690
+ const M = await loadMediabunny();
691
+ const videoBitrate = bitrateOf(M, eff.bitrate ?? "high");
682
692
  const opts = {
683
693
  format: fmt,
684
694
  video: { codec: "", bitrate: videoBitrate },
685
695
  audio: {
686
696
  codec: options.audio?.codec ?? (fmt === "mp4" || fmt === "mov" ? "aac" : "opus"),
687
- bitrate: bitrateOf(options.audio?.bitrate, QUALITY_HIGH)
697
+ bitrate: bitrateOf(M, options.audio?.bitrate)
688
698
  }
689
699
  };
690
- const container = makeOutputFormat(opts.format);
700
+ const container = makeOutputFormat(M, opts.format);
691
701
  const audio = movie.audioBuffer && range2.partial ? sliceAudio(movie.audioBuffer, range2.fromSec, range2.toSec, range2.fromFrame > 0, range2.toFrame < movie.totalFrames) : movie.audioBuffer;
692
- if (audio) opts.audio.codec = await chooseAudioCodec(fmt, options.audio?.codec, container, audio, opts.audio.bitrate);
693
- const output = new Output({
702
+ if (audio) opts.audio.codec = await chooseAudioCodec(M, fmt, options.audio?.codec, container, audio, opts.audio.bitrate);
703
+ const output = new M.Output({
694
704
  format: container,
695
- target: new BufferTarget()
705
+ target: new M.BufferTarget()
696
706
  });
697
707
  const mb = eff.motionBlur !== void 0 ? resolveMotionBlur(eff.motionBlur, "movie.render()") : movie.motionBlur ?? null;
698
708
  const stage = movie.app.canvas;
@@ -704,7 +714,7 @@ async function exportFrames(movie, options = {}) {
704
714
  fmt,
705
715
  requested: options.video?.codec,
706
716
  supported: container.getSupportedVideoCodecs(),
707
- canEncode: (c) => canEncodeVideo(c, { width: picture.width, height: picture.height, bitrate: opts.video.bitrate })
717
+ canEncode: (c) => M.canEncodeVideo(c, { width: picture.width, height: picture.height, bitrate: opts.video.bitrate })
708
718
  });
709
719
  if (chosen.fellBackFrom) console.warn(`pixi-effects: this browser cannot encode ${chosen.fellBackFrom.toUpperCase()} video, so the ${fmt} carries ${chosen.codec.toUpperCase()} instead (name a codec with render({ video: { codec } }) to choose yourself).`);
710
720
  opts.video.codec = chosen.codec;
@@ -712,14 +722,14 @@ async function exportFrames(movie, options = {}) {
712
722
  if (hardware !== void 0 && !["no-preference", "prefer-hardware", "prefer-software"].includes(hardware)) {
713
723
  throw new Error(`pixi-effects: render({ video: { hardware: "${String(hardware)}" } }): use 'prefer-hardware', 'prefer-software' or 'no-preference'`);
714
724
  }
715
- const canvasSource = new CanvasSource(picture, {
725
+ const canvasSource = new M.CanvasSource(picture, {
716
726
  codec: opts.video.codec,
717
727
  bitrate: opts.video.bitrate,
718
728
  ...hardware ? { hardwareAcceleration: hardware } : {}
719
729
  });
720
730
  output.addVideoTrack(canvasSource, { frameRate: movie.frameRate });
721
731
  if (audio) {
722
- const audioSource = new AudioBufferSource({
732
+ const audioSource = new M.AudioBufferSource({
723
733
  codec: opts.audio.codec,
724
734
  bitrate: opts.audio.bitrate
725
735
  }, { startTimestamp: opts.audio.codec === "aac" ? -2112 / audio.sampleRate : 0 });
@@ -5013,5 +5023,5 @@ function withFade(spec, opts) {
5013
5023
  }
5014
5024
 
5015
5025
  export { Movie, animateText, audioEnvelope, bpmEnvelope, cameraPath, computeEnvelope, dismissLoader, failLoader, followPath, kenBurns, measureText, musicBuffer, musicEnvelope, musicEvents, orbit, parseEase2 as parseEase, particles, react, resolveLoader, samplePath, splitText, stagger, wiggle, withFade };
5016
- //# sourceMappingURL=chunk-LHUIEFMH.js.map
5017
- //# sourceMappingURL=chunk-LHUIEFMH.js.map
5026
+ //# sourceMappingURL=chunk-GX2WQV4A.js.map
5027
+ //# sourceMappingURL=chunk-GX2WQV4A.js.map