@remotion/media-utils 4.0.393 → 4.0.394

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.
@@ -0,0 +1,12 @@
1
+ export declare const getPartialWaveData: ({ dataOffset, src, bitsPerSample, channelIndex, sampleRate, fromSeconds, toSeconds, blockAlign, fileSize, signal, }: {
2
+ dataOffset: number;
3
+ src: string;
4
+ bitsPerSample: number;
5
+ channelIndex: number;
6
+ sampleRate: number;
7
+ fromSeconds: number;
8
+ toSeconds: number;
9
+ blockAlign: number;
10
+ fileSize: number;
11
+ signal: AbortSignal;
12
+ }) => Promise<Float32Array<ArrayBuffer>>;
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPartialWaveData = void 0;
4
+ const fetch_with_cors_catch_1 = require("./fetch-with-cors-catch");
5
+ const probe_wave_file_1 = require("./probe-wave-file");
6
+ const getPartialWaveData = async ({ dataOffset, src, bitsPerSample, channelIndex, sampleRate, fromSeconds, toSeconds, blockAlign, fileSize, signal, }) => {
7
+ const startByte = dataOffset + Math.floor(fromSeconds * sampleRate) * blockAlign;
8
+ const endByte = Math.min(fileSize, (dataOffset + Math.floor(toSeconds * sampleRate)) * blockAlign) - 1;
9
+ const response = await (0, fetch_with_cors_catch_1.fetchWithCorsCatch)(src, {
10
+ headers: {
11
+ range: `bytes=${startByte}-${endByte}`,
12
+ },
13
+ signal,
14
+ });
15
+ if (response.status === 416) {
16
+ throw new Error(`Tried to read bytes ${startByte}-${endByte} from ${src}, but the response status code was 416 "Range Not Satisfiable". Were too many bytes requested? The file is ${fileSize} bytes long.`);
17
+ }
18
+ if (response.status !== 206) {
19
+ throw new Error(`Tried to read bytes ${startByte}-${endByte} from ${src}, but the response status code was ${response.status} (expected was 206). This means the server might not support returning a partial response.`);
20
+ }
21
+ const arrayBuffer = await response.arrayBuffer();
22
+ const uintArray = new Uint8Array(arrayBuffer);
23
+ const samples = new Float32Array(uintArray.length / blockAlign);
24
+ for (let i = 0; i < uintArray.length; i += blockAlign) {
25
+ const sampleStart = i + channelIndex * (bitsPerSample / 8);
26
+ let sample;
27
+ if (bitsPerSample === 16) {
28
+ sample = (0, probe_wave_file_1.getInt16AsFloat)(uintArray, sampleStart);
29
+ }
30
+ else if (bitsPerSample === 8) {
31
+ sample = (0, probe_wave_file_1.getInt8AsFloat)(uintArray, sampleStart);
32
+ }
33
+ else {
34
+ throw new Error(`Unsupported bits per sample: ${bitsPerSample}`);
35
+ }
36
+ samples[i / blockAlign] = sample;
37
+ }
38
+ return samples;
39
+ };
40
+ exports.getPartialWaveData = getPartialWaveData;
@@ -0,0 +1,12 @@
1
+ export declare const getInt16AsFloat: (bytes: Uint8Array, offset: number) => number;
2
+ export declare const getInt8AsFloat: (bytes: Uint8Array, offset: number) => number;
3
+ export type WaveProbe = {
4
+ dataOffset: number;
5
+ bitsPerSample: number;
6
+ numberOfChannels: number;
7
+ sampleRate: number;
8
+ blockAlign: number;
9
+ fileSize: number;
10
+ durationInSeconds: number;
11
+ };
12
+ export declare const probeWaveFile: (src: string, probeSize?: number) => Promise<WaveProbe>;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.probeWaveFile = exports.getInt8AsFloat = exports.getInt16AsFloat = void 0;
4
+ const fetch_with_cors_catch_1 = require("./fetch-with-cors-catch");
5
+ const getUint32 = (bytes, offset) => {
6
+ const val1 = bytes[offset + 3];
7
+ const val2 = bytes[offset + 2];
8
+ const val3 = bytes[offset + 1];
9
+ const val4 = bytes[offset];
10
+ return (val1 << 24) | (val2 << 16) | (val3 << 8) | val4;
11
+ };
12
+ const getUint16 = (bytes, offset) => {
13
+ const val1 = bytes[offset + 1];
14
+ const val2 = bytes[offset];
15
+ return (val1 << 8) | val2;
16
+ };
17
+ const getInt16AsFloat = (bytes, offset) => {
18
+ if (offset >= bytes.length) {
19
+ throw new Error(`Tried to read a 16-bit integer from offset ${offset} but the array length is ${bytes.length}`);
20
+ }
21
+ const val1 = bytes[offset + 1];
22
+ const val2 = bytes[offset];
23
+ const int16 = (val1 << 8) | val2;
24
+ return ((int16 << 16) >> 16) / 32768;
25
+ };
26
+ exports.getInt16AsFloat = getInt16AsFloat;
27
+ const getInt8AsFloat = (bytes, offset) => {
28
+ if (offset >= bytes.length) {
29
+ throw new Error(`Tried to read an 8-bit integer from offset ${offset} but the array length is ${bytes.length}`);
30
+ }
31
+ return bytes[offset] / 128;
32
+ };
33
+ exports.getInt8AsFloat = getInt8AsFloat;
34
+ const probeWaveFile = async (src, probeSize = 1024) => {
35
+ const response = await (0, fetch_with_cors_catch_1.fetchWithCorsCatch)(src, {
36
+ headers: {
37
+ range: `bytes=0-${probeSize - 1}`,
38
+ },
39
+ });
40
+ if (response.status === 416) {
41
+ throw new Error(`Tried to read bytes 0-1024 from ${src}, but the response status code was 416 "Range Not Satisfiable". Is the file at least 256 bytes long?`);
42
+ }
43
+ if (response.status !== 206) {
44
+ throw new Error(`Tried to read bytes 0-1024 from ${src}, but the response status code was ${response.status} (expected was 206). This means the server might not support returning a partial response.`);
45
+ }
46
+ const buffer = await response.arrayBuffer();
47
+ const uintArray = new Uint8Array(buffer);
48
+ const shouldBeRiff = new TextDecoder().decode(uintArray.slice(0, 4));
49
+ if (shouldBeRiff !== 'RIFF') {
50
+ throw new Error('getPartialAudioData() requires a WAVE file, but the first bytes are not RIFF. ');
51
+ }
52
+ const size = getUint32(uintArray, 4);
53
+ const shouldBeWAVE = new TextDecoder().decode(uintArray.slice(8, 12));
54
+ if (shouldBeWAVE !== 'WAVE') {
55
+ throw new Error('getPartialAudioData() requires a WAVE file, but the bytes 8-11 are not "WAVE". ');
56
+ }
57
+ const shouldBeFmt = new TextDecoder().decode(uintArray.slice(12, 16));
58
+ if (shouldBeFmt !== 'fmt ') {
59
+ throw new Error('getPartialAudioData() requires a WAVE file, but the bytes 12-15 are not "fmt ". ');
60
+ }
61
+ // const chunkSize = toUint32(uintArray.slice(16, 20));
62
+ const audioFormat = getUint16(uintArray, 20);
63
+ if (audioFormat !== 1) {
64
+ throw new Error('getPartialAudioData() supports only a WAVE file with PCM audio format, but the audio format is not PCM. ');
65
+ }
66
+ const numberOfChannels = getUint16(uintArray, 22);
67
+ const sampleRate = getUint32(uintArray, 24);
68
+ const blockAlign = getUint16(uintArray, 32);
69
+ const bitsPerSample = getUint16(uintArray, 34);
70
+ let offset = 36;
71
+ const shouldBeDataOrList = new TextDecoder().decode(uintArray.slice(offset, offset + 4));
72
+ if (shouldBeDataOrList === 'LIST') {
73
+ const listSize = getUint32(uintArray, 40);
74
+ offset += listSize;
75
+ offset += 8;
76
+ }
77
+ if (offset + 4 > probeSize) {
78
+ return (0, exports.probeWaveFile)(src, offset + 4);
79
+ }
80
+ const shouldBeData = new TextDecoder().decode(uintArray.slice(offset, offset + 4));
81
+ if (shouldBeData !== 'data') {
82
+ throw new Error(`getPartialAudioData() requires a WAVE file, but the bytes ${offset}-${offset + 4} are not "data". `);
83
+ }
84
+ const dataSize = getUint32(uintArray, offset + 4);
85
+ return {
86
+ dataOffset: offset + 8,
87
+ bitsPerSample,
88
+ numberOfChannels,
89
+ sampleRate,
90
+ blockAlign,
91
+ fileSize: size,
92
+ durationInSeconds: dataSize / (sampleRate * blockAlign),
93
+ };
94
+ };
95
+ exports.probeWaveFile = probeWaveFile;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "url": "https://github.com/remotion-dev/remotion/tree/main/packages/media-utils"
4
4
  },
5
5
  "name": "@remotion/media-utils",
6
- "version": "4.0.393",
6
+ "version": "4.0.394",
7
7
  "description": "Utilities for working with media files",
8
8
  "main": "dist/index.js",
9
9
  "sideEffects": false,
@@ -18,9 +18,9 @@
18
18
  "url": "https://github.com/remotion-dev/remotion/issues"
19
19
  },
20
20
  "dependencies": {
21
- "@remotion/media-parser": "4.0.393",
22
- "@remotion/webcodecs": "4.0.393",
23
- "remotion": "4.0.393",
21
+ "@remotion/media-parser": "4.0.394",
22
+ "@remotion/webcodecs": "4.0.394",
23
+ "remotion": "4.0.394",
24
24
  "mediabunny": "1.27.0"
25
25
  },
26
26
  "peerDependencies": {
@@ -28,7 +28,7 @@
28
28
  "react-dom": ">=16.8.0"
29
29
  },
30
30
  "devDependencies": {
31
- "@remotion/eslint-config-internal": "4.0.393",
31
+ "@remotion/eslint-config-internal": "4.0.394",
32
32
  "eslint": "9.19.0"
33
33
  },
34
34
  "keywords": [