@remotion/media-utils 3.1.7 → 3.1.8
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/dist/create-smooth-svg-path.d.ts +4 -0
- package/dist/create-smooth-svg-path.js +39 -0
- package/dist/get-audio-duration.d.ts +11 -0
- package/dist/get-audio-duration.js +49 -0
- package/dist/validate-channel.d.ts +1 -0
- package/dist/validate-channel.js +21 -0
- package/dist/visualize-audio-waveform.d.ts +11 -0
- package/dist/visualize-audio-waveform.js +32 -0
- package/package.json +3 -3
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.smoothenSvgPath = void 0;
|
|
4
|
+
const line = (pointA, pointB) => {
|
|
5
|
+
const lengthX = pointB[0] - pointA[0];
|
|
6
|
+
const lengthY = pointB[1] - pointA[1];
|
|
7
|
+
return {
|
|
8
|
+
length: Math.sqrt(lengthX ** 2 + lengthY ** 2),
|
|
9
|
+
angle: Math.atan2(lengthY, lengthX),
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
const controlPoint = (current, previous, next, reverse) => {
|
|
13
|
+
const p = previous || current;
|
|
14
|
+
const n = next || current;
|
|
15
|
+
// The smoothing ratio
|
|
16
|
+
const smoothing = 0.2;
|
|
17
|
+
// Properties of the opposed-line
|
|
18
|
+
const o = line(p, n);
|
|
19
|
+
const angle = o.angle + (reverse ? Math.PI : 0);
|
|
20
|
+
const length = o.length * smoothing;
|
|
21
|
+
const x = current[0] + Math.cos(angle) * length;
|
|
22
|
+
const y = current[1] + Math.sin(angle) * length;
|
|
23
|
+
return [x, y];
|
|
24
|
+
};
|
|
25
|
+
const smoothenSvgPath = (points) => {
|
|
26
|
+
return points.reduce((acc, current, i, a) => {
|
|
27
|
+
if (i === 0) {
|
|
28
|
+
return `M ${current[0]},${current[1]}`;
|
|
29
|
+
}
|
|
30
|
+
const [x, y] = current;
|
|
31
|
+
const previous = a[i - 1];
|
|
32
|
+
const twoPrevious = a[i - 2];
|
|
33
|
+
const next = a[i + 1];
|
|
34
|
+
const [cp1x, cp1y] = controlPoint(previous, twoPrevious, current, false);
|
|
35
|
+
const [cp2x, cp2y] = controlPoint(current, previous, next, true);
|
|
36
|
+
return `${acc} C ${cp1x},${cp1y} ${cp2x},${cp2y} ${x},${y}`;
|
|
37
|
+
}, '');
|
|
38
|
+
};
|
|
39
|
+
exports.smoothenSvgPath = smoothenSvgPath;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Get the audio file passed in parameter duration in seconds
|
|
3
|
+
* @async
|
|
4
|
+
* @param src path to the audio file
|
|
5
|
+
* @return {number} duration of the audio file in seconds
|
|
6
|
+
*/
|
|
7
|
+
export declare const getAudioDurationInSeconds: (src: string) => Promise<number>;
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Renamed to `getAudioDurationInSeconds`
|
|
10
|
+
*/
|
|
11
|
+
export declare const getAudioDuration: (src: string) => Promise<number>;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getAudioDuration = exports.getAudioDurationInSeconds = void 0;
|
|
4
|
+
const p_limit_1 = require("./p-limit");
|
|
5
|
+
const limit = (0, p_limit_1.pLimit)(3);
|
|
6
|
+
const metadataCache = {};
|
|
7
|
+
const fn = (src) => {
|
|
8
|
+
if (metadataCache[src]) {
|
|
9
|
+
return Promise.resolve(metadataCache[src]);
|
|
10
|
+
}
|
|
11
|
+
if (typeof document === 'undefined') {
|
|
12
|
+
throw new Error('getAudioDuration() is only available in the browser.');
|
|
13
|
+
}
|
|
14
|
+
const audio = document.createElement('audio');
|
|
15
|
+
audio.src = src;
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
const onError = () => {
|
|
18
|
+
reject(audio.error);
|
|
19
|
+
cleanup();
|
|
20
|
+
};
|
|
21
|
+
const onLoadedMetadata = () => {
|
|
22
|
+
metadataCache[src] = audio.duration;
|
|
23
|
+
resolve(audio.duration);
|
|
24
|
+
cleanup();
|
|
25
|
+
};
|
|
26
|
+
const cleanup = () => {
|
|
27
|
+
audio.removeEventListener('loadedmetadata', onLoadedMetadata);
|
|
28
|
+
audio.removeEventListener('error', onError);
|
|
29
|
+
audio.remove();
|
|
30
|
+
};
|
|
31
|
+
audio.addEventListener('loadedmetadata', onLoadedMetadata, { once: true });
|
|
32
|
+
audio.addEventListener('error', onError, { once: true });
|
|
33
|
+
});
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Get the audio file passed in parameter duration in seconds
|
|
37
|
+
* @async
|
|
38
|
+
* @param src path to the audio file
|
|
39
|
+
* @return {number} duration of the audio file in seconds
|
|
40
|
+
*/
|
|
41
|
+
const getAudioDurationInSeconds = (src) => {
|
|
42
|
+
return limit(fn, src);
|
|
43
|
+
};
|
|
44
|
+
exports.getAudioDurationInSeconds = getAudioDurationInSeconds;
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Renamed to `getAudioDurationInSeconds`
|
|
47
|
+
*/
|
|
48
|
+
const getAudioDuration = (src) => (0, exports.getAudioDurationInSeconds)(src);
|
|
49
|
+
exports.getAudioDuration = getAudioDuration;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const validateChannel: (channel: unknown, numberOfChannels: number) => void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateChannel = void 0;
|
|
4
|
+
const validateChannel = (channel, numberOfChannels) => {
|
|
5
|
+
if (typeof channel !== 'number') {
|
|
6
|
+
throw new TypeError(`"channel" must be a number`);
|
|
7
|
+
}
|
|
8
|
+
if (channel % 1 !== 0) {
|
|
9
|
+
throw new TypeError(`"channel" must an integer, got ${channel}`);
|
|
10
|
+
}
|
|
11
|
+
if (Number.isNaN(channel)) {
|
|
12
|
+
throw new TypeError(`The channel parameter is NaN.`);
|
|
13
|
+
}
|
|
14
|
+
if (channel < 0) {
|
|
15
|
+
throw new TypeError('"channel" cannot be negative');
|
|
16
|
+
}
|
|
17
|
+
if (channel > numberOfChannels - 1) {
|
|
18
|
+
throw new TypeError(`"channel" must be ${numberOfChannels - 1} or lower. The audio has ${numberOfChannels} channels`);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
exports.validateChannel = validateChannel;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { AudioData } from './types';
|
|
2
|
+
declare type FnParameters = {
|
|
3
|
+
audioData: AudioData;
|
|
4
|
+
frame: number;
|
|
5
|
+
fps: number;
|
|
6
|
+
windowInSeconds: number;
|
|
7
|
+
numberOfSamples: number;
|
|
8
|
+
channel: number;
|
|
9
|
+
};
|
|
10
|
+
export declare const visualizeAudioWaveform: ({ ...parameters }: FnParameters) => number[];
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.visualizeAudioWaveform = void 0;
|
|
4
|
+
const get_waveform_portion_1 = require("./get-waveform-portion");
|
|
5
|
+
const cache = {};
|
|
6
|
+
const visualizeAudioWaveformFrame = ({ audioData, frame, fps, numberOfSamples, windowInSeconds, channel, }) => {
|
|
7
|
+
if (windowInSeconds * audioData.sampleRate < numberOfSamples) {
|
|
8
|
+
throw new TypeError(windowInSeconds +
|
|
9
|
+
's audiodata does not have ' +
|
|
10
|
+
numberOfSamples +
|
|
11
|
+
' bars. Increase windowInSeconds or decrease numberOfSamples');
|
|
12
|
+
}
|
|
13
|
+
const cacheKey = audioData.resultId + frame + fps + numberOfSamples + 'waveform';
|
|
14
|
+
if (cache[cacheKey]) {
|
|
15
|
+
return cache[cacheKey];
|
|
16
|
+
}
|
|
17
|
+
const time = frame / fps;
|
|
18
|
+
const startTimeInSeconds = time - windowInSeconds / 2;
|
|
19
|
+
return (0, get_waveform_portion_1.getWaveformPortion)({
|
|
20
|
+
audioData,
|
|
21
|
+
startTimeInSeconds,
|
|
22
|
+
durationInSeconds: windowInSeconds,
|
|
23
|
+
numberOfSamples,
|
|
24
|
+
outputRange: 'minus-one-to-one',
|
|
25
|
+
channel,
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const visualizeAudioWaveform = ({ ...parameters }) => {
|
|
29
|
+
const data = visualizeAudioWaveformFrame(parameters);
|
|
30
|
+
return data.map((value) => value.amplitude);
|
|
31
|
+
};
|
|
32
|
+
exports.visualizeAudioWaveform = visualizeAudioWaveform;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remotion/media-utils",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.8",
|
|
4
4
|
"description": "Utility functions for audio and video",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"url": "https://github.com/remotion-dev/remotion/issues"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"remotion": "3.1.
|
|
21
|
+
"remotion": "3.1.8"
|
|
22
22
|
},
|
|
23
23
|
"peerDependencies": {
|
|
24
24
|
"react": ">=16.8.0",
|
|
@@ -44,5 +44,5 @@
|
|
|
44
44
|
"publishConfig": {
|
|
45
45
|
"access": "public"
|
|
46
46
|
},
|
|
47
|
-
"gitHead": "
|
|
47
|
+
"gitHead": "57f34a02b0f830053f92af426a6b70b6824f887e"
|
|
48
48
|
}
|