@remotion/webcodecs 4.0.287 → 4.0.288

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 (78) hide show
  1. package/dist/audio-data/data-types.d.ts +1 -0
  2. package/dist/audio-data/data-types.js +26 -0
  3. package/dist/audio-data/is-planar-format.d.ts +1 -0
  4. package/dist/audio-data/is-planar-format.js +7 -0
  5. package/dist/audio-encoder.js +5 -1
  6. package/dist/can-reencode-audio-track.d.ts +2 -1
  7. package/dist/can-reencode-audio-track.js +2 -2
  8. package/dist/convert-audiodata.d.ts +10 -0
  9. package/dist/convert-audiodata.js +85 -0
  10. package/dist/create/iso-base-media/codec-specific/create-codec-specific-data.js +8 -0
  11. package/dist/create/iso-base-media/create-iso-base-media.js +2 -0
  12. package/dist/create/iso-base-media/example-stts.js +620 -0
  13. package/dist/create/matroska/create-matroska-media.js +1 -1
  14. package/dist/create/matroska/matroska-utils.d.ts +1 -1
  15. package/dist/default-on-audio-track-handler.js +2 -0
  16. package/dist/esm/index.mjs +176 -15
  17. package/dist/get-wave-audio-decoder.js +29 -1
  18. package/dist/index.d.ts +1 -0
  19. package/dist/index.js +3 -1
  20. package/dist/on-audio-track-handler.d.ts +1 -0
  21. package/dist/on-audio-track.js +3 -3
  22. package/dist/resample-audiodata.d.ts +4 -0
  23. package/dist/resample-audiodata.js +35 -0
  24. package/dist/wav-audio-encoder.d.ts +1 -1
  25. package/dist/wav-audio-encoder.js +11 -4
  26. package/package.json +12 -7
  27. package/dist/test/avc1.test.d.ts +0 -1
  28. package/dist/test/avc1.test.js +0 -39
  29. package/dist/test/avcc.test.d.ts +0 -1
  30. package/dist/test/avcc.test.js +0 -15
  31. package/dist/test/avi-to-mp4.test.d.ts +0 -1
  32. package/dist/test/avi-to-mp4.test.js +0 -15
  33. package/dist/test/cmt.test.d.ts +0 -1
  34. package/dist/test/cmt.test.js +0 -13
  35. package/dist/test/colr.test.d.ts +0 -1
  36. package/dist/test/colr.test.js +0 -16
  37. package/dist/test/correct-byte-length.test.d.ts +0 -1
  38. package/dist/test/correct-byte-length.test.js +0 -23
  39. package/dist/test/create-ftyp.test.d.ts +0 -1
  40. package/dist/test/create-ftyp.test.js +0 -47
  41. package/dist/test/create-mvhd.test.d.ts +0 -1
  42. package/dist/test/create-mvhd.test.js +0 -108
  43. package/dist/test/ctts.test.d.ts +0 -1
  44. package/dist/test/ctts.test.js +0 -49
  45. package/dist/test/dinf.test.d.ts +0 -1
  46. package/dist/test/dinf.test.js +0 -12
  47. package/dist/test/ilst.test.d.ts +0 -1
  48. package/dist/test/ilst.test.js +0 -22
  49. package/dist/test/mdhd.test.d.ts +0 -1
  50. package/dist/test/mdhd.test.js +0 -17
  51. package/dist/test/meta.test.d.ts +0 -1
  52. package/dist/test/meta.test.js +0 -26
  53. package/dist/test/mp4-header-length.test.d.ts +0 -1
  54. package/dist/test/mp4-header-length.test.js +0 -12
  55. package/dist/test/mp4a.test.d.ts +0 -1
  56. package/dist/test/mp4a.test.js +0 -24
  57. package/dist/test/pasp.test.d.ts +0 -1
  58. package/dist/test/pasp.test.js +0 -12
  59. package/dist/test/remux-serverside.test.d.ts +0 -1
  60. package/dist/test/remux-serverside.test.js +0 -23
  61. package/dist/test/stbl.test.d.ts +0 -0
  62. package/dist/test/stbl.test.js +0 -176
  63. package/dist/test/stco.test.d.ts +0 -1
  64. package/dist/test/stco.test.js +0 -34
  65. package/dist/test/stsc.test.d.ts +0 -1
  66. package/dist/test/stsc.test.js +0 -63
  67. package/dist/test/stss.test.d.ts +0 -1
  68. package/dist/test/stss.test.js +0 -14
  69. package/dist/test/stsz.test.d.ts +0 -1
  70. package/dist/test/stsz.test.js +0 -43
  71. package/dist/test/stts.test.d.ts +0 -1
  72. package/dist/test/stts.test.js +0 -12
  73. package/dist/test/tkhd.test.d.ts +0 -1
  74. package/dist/test/tkhd.test.js +0 -175
  75. package/dist/test/too.test.d.ts +0 -1
  76. package/dist/test/too.test.js +0 -12
  77. package/dist/test/url.test.d.ts +0 -1
  78. package/dist/test/url.test.js +0 -11
@@ -0,0 +1 @@
1
+ export declare const getDataTypeForAudioFormat: (format: AudioSampleFormat) => Uint8ArrayConstructor | Float32ArrayConstructor | Int16ArrayConstructor | Int32ArrayConstructor;
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getDataTypeForAudioFormat = void 0;
4
+ const getDataTypeForAudioFormat = (format) => {
5
+ switch (format) {
6
+ case 'f32':
7
+ return Float32Array;
8
+ case 'f32-planar':
9
+ return Float32Array;
10
+ case 's16':
11
+ return Int16Array;
12
+ case 's16-planar':
13
+ return Int16Array;
14
+ case 'u8':
15
+ return Uint8Array;
16
+ case 'u8-planar':
17
+ return Uint8Array;
18
+ case 's32':
19
+ return Int32Array;
20
+ case 's32-planar':
21
+ return Int32Array;
22
+ default:
23
+ throw new Error(`Unsupported audio format: ${format}`);
24
+ }
25
+ };
26
+ exports.getDataTypeForAudioFormat = getDataTypeForAudioFormat;
@@ -0,0 +1 @@
1
+ export declare const isPlanarFormat: (format: AudioSampleFormat) => boolean;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isPlanarFormat = void 0;
4
+ const isPlanarFormat = (format) => {
5
+ return format.includes('-planar');
6
+ };
7
+ exports.isPlanarFormat = isPlanarFormat;
@@ -9,7 +9,11 @@ const createAudioEncoder = ({ onChunk, onError, codec, controller, config: audio
9
9
  throw new media_parser_1.MediaParserAbortError('Not creating audio encoder, already aborted');
10
10
  }
11
11
  if (codec === 'wav') {
12
- return (0, wav_audio_encoder_1.getWaveAudioEncoder)({ onChunk, controller });
12
+ return (0, wav_audio_encoder_1.getWaveAudioEncoder)({
13
+ onChunk,
14
+ controller,
15
+ config: audioEncoderConfig,
16
+ });
13
17
  }
14
18
  const ioSynchronizer = (0, io_synchronizer_1.makeIoSynchronizer)({
15
19
  logLevel,
@@ -1,7 +1,8 @@
1
1
  import type { AudioTrack } from '@remotion/media-parser';
2
2
  import type { ConvertMediaAudioCodec } from './get-available-audio-codecs';
3
- export declare const canReencodeAudioTrack: ({ track, audioCodec, bitrate, }: {
3
+ export declare const canReencodeAudioTrack: ({ track, audioCodec, bitrate, sampleRate, }: {
4
4
  track: AudioTrack;
5
5
  audioCodec: ConvertMediaAudioCodec;
6
6
  bitrate: number;
7
+ sampleRate: number | null;
7
8
  }) => Promise<boolean>;
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.canReencodeAudioTrack = void 0;
4
4
  const audio_decoder_config_1 = require("./audio-decoder-config");
5
5
  const audio_encoder_config_1 = require("./audio-encoder-config");
6
- const canReencodeAudioTrack = async ({ track, audioCodec, bitrate, }) => {
6
+ const canReencodeAudioTrack = async ({ track, audioCodec, bitrate, sampleRate, }) => {
7
7
  const audioDecoderConfig = await (0, audio_decoder_config_1.getAudioDecoderConfig)(track);
8
8
  if (audioCodec === 'wav' && audioDecoderConfig) {
9
9
  return true;
@@ -11,7 +11,7 @@ const canReencodeAudioTrack = async ({ track, audioCodec, bitrate, }) => {
11
11
  const audioEncoderConfig = await (0, audio_encoder_config_1.getAudioEncoderConfig)({
12
12
  codec: audioCodec,
13
13
  numberOfChannels: track.numberOfChannels,
14
- sampleRate: track.sampleRate,
14
+ sampleRate: sampleRate ?? track.sampleRate,
15
15
  bitrate,
16
16
  });
17
17
  return Boolean(audioDecoderConfig && audioEncoderConfig);
@@ -0,0 +1,10 @@
1
+ export type ConvertAudioDataOptions = {
2
+ audioData: AudioData;
3
+ newSampleRate?: number;
4
+ format?: AudioSampleFormat | null;
5
+ };
6
+ /**
7
+ * Converts an `AudioData` object to a new `AudioData` object with a different sample rate or format.
8
+ * @see [Documentation](https://remotion.dev/docs/webcodecs/convert-audiodata)
9
+ */
10
+ export declare const convertAudioData: ({ audioData, newSampleRate, format, }: ConvertAudioDataOptions) => AudioData;
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.convertAudioData = void 0;
4
+ const data_types_1 = require("./audio-data/data-types");
5
+ const is_planar_format_1 = require("./audio-data/is-planar-format");
6
+ const validateRange = (format, value) => {
7
+ if (format === 'f32' || format === 'f32-planar') {
8
+ if (value < -1 || value > 1) {
9
+ throw new Error('All values in a Float32 array must be between -1 and 1');
10
+ }
11
+ }
12
+ };
13
+ /**
14
+ * Converts an `AudioData` object to a new `AudioData` object with a different sample rate or format.
15
+ * @see [Documentation](https://remotion.dev/docs/webcodecs/convert-audiodata)
16
+ */
17
+ const convertAudioData = ({ audioData, newSampleRate = audioData.sampleRate, format = audioData.format, }) => {
18
+ const { numberOfChannels, sampleRate: currentSampleRate, numberOfFrames: currentNumberOfFrames, } = audioData;
19
+ const ratio = currentSampleRate / newSampleRate;
20
+ const newNumberOfFrames = Math.floor(currentNumberOfFrames / ratio);
21
+ if (newNumberOfFrames === 0) {
22
+ throw new Error('Cannot resample - the given sample rate would result in less than 1 sample');
23
+ }
24
+ if (newSampleRate < 3000 || newSampleRate > 768000) {
25
+ throw new Error('newSampleRate must be between 3000 and 768000');
26
+ }
27
+ if (!format) {
28
+ throw new Error('AudioData format is not set');
29
+ }
30
+ if (format === audioData.format &&
31
+ newNumberOfFrames === currentNumberOfFrames) {
32
+ return audioData.clone();
33
+ }
34
+ const DataType = (0, data_types_1.getDataTypeForAudioFormat)(format);
35
+ const isPlanar = (0, is_planar_format_1.isPlanarFormat)(format);
36
+ const planes = isPlanar ? numberOfChannels : 1;
37
+ const srcChannels = new Array(planes)
38
+ .fill(true)
39
+ .map(() => new DataType((isPlanar ? 1 : numberOfChannels) * currentNumberOfFrames));
40
+ for (let i = 0; i < planes; i++) {
41
+ audioData.clone().copyTo(srcChannels[i], {
42
+ planeIndex: i,
43
+ format,
44
+ });
45
+ }
46
+ const data = new DataType(newNumberOfFrames * numberOfChannels);
47
+ const chunkSize = currentNumberOfFrames / newNumberOfFrames;
48
+ for (let newFrameIndex = 0; newFrameIndex < newNumberOfFrames; newFrameIndex++) {
49
+ const start = Math.floor(newFrameIndex * chunkSize);
50
+ const end = Math.max(Math.floor(start + chunkSize), start + 1);
51
+ if (isPlanar) {
52
+ for (let channelIndex = 0; channelIndex < numberOfChannels; channelIndex++) {
53
+ const chunk = srcChannels[channelIndex].slice(start, end);
54
+ const average = chunk.reduce((a, b) => {
55
+ return a + b;
56
+ }, 0) / chunk.length;
57
+ validateRange(format, average);
58
+ data[newFrameIndex + channelIndex * newNumberOfFrames] = average;
59
+ }
60
+ }
61
+ else {
62
+ const sampleCountAvg = end - start;
63
+ for (let channelIndex = 0; channelIndex < numberOfChannels; channelIndex++) {
64
+ const items = [];
65
+ for (let k = 0; k < sampleCountAvg; k++) {
66
+ const num = srcChannels[0][(start + k) * numberOfChannels + channelIndex];
67
+ items.push(num);
68
+ }
69
+ const average = items.reduce((a, b) => a + b, 0) / items.length;
70
+ validateRange(format, average);
71
+ data[newFrameIndex * numberOfChannels + channelIndex] = average;
72
+ }
73
+ }
74
+ }
75
+ const newAudioData = new AudioData({
76
+ data,
77
+ format,
78
+ numberOfChannels,
79
+ numberOfFrames: newNumberOfFrames,
80
+ sampleRate: newSampleRate,
81
+ timestamp: audioData.timestamp,
82
+ });
83
+ return newAudioData;
84
+ };
85
+ exports.convertAudioData = convertAudioData;
@@ -10,6 +10,10 @@ const mp4a_1 = require("./mp4a");
10
10
  const createCodecSpecificData = (track) => {
11
11
  if (track.type === 'video') {
12
12
  if (track.codec === 'h264') {
13
+ // May not have it initially
14
+ if (!track.codecPrivate) {
15
+ return new Uint8Array([]);
16
+ }
13
17
  return (0, avc1_1.createAvc1Data)({
14
18
  avccBox: (0, create_avcc_1.createAvccBox)(track.codecPrivate),
15
19
  compressorName: 'WebCodecs',
@@ -23,6 +27,10 @@ const createCodecSpecificData = (track) => {
23
27
  });
24
28
  }
25
29
  if (track.codec === 'h265') {
30
+ // May not have it initially
31
+ if (!track.codecPrivate) {
32
+ return new Uint8Array([]);
33
+ }
26
34
  return (0, hvc1_1.createHvc1Data)({
27
35
  hvccBox: (0, create_hvcc_1.createHvccBox)(track.codecPrivate),
28
36
  compressorName: 'WebCodecs',
@@ -127,6 +127,8 @@ const createIsoBaseMedia = async ({ writer, onBytesProgress, onMillisecondsProgr
127
127
  dts: Math.round((chunk.dts / 1000000) * currentTrack.timescale),
128
128
  duration: Math.round(((chunk.duration ?? 0) / 1000000) * currentTrack.timescale),
129
129
  size: chunk.data.length,
130
+ bigEndian: false,
131
+ chunkSize: null,
130
132
  };
131
133
  lastChunkWasVideo = isVideo;
132
134
  samplePositions[trackNumber].push(samplePositionToAdd);