@numairawan/video-duration
Version:
Get video duration from any url and video object in nodejs and browser.
98 lines (83 loc) • 2.99 kB
JavaScript
class VideoDuration {
async analyze(video) {
if (this.isURL(video)) {
try {
// Download video from the URL
const response = await fetch(video);
if (!response.ok) {
throw new Error(`Failed to download the video from the URL: HTTP ${response.status}`);
}
const videoBuffer = new Uint8Array(await response.arrayBuffer());
// Proceed with processing the downloaded video buffer
return this.processVideoBuffer(videoBuffer);
} catch (error) {
console.error(error);
}
} else if (video instanceof File && this.isVideoFile(video)) {
// Handle local video file
const videoBuffer = await this.readVideoFile(video);
// Proceed with processing the local video buffer
return this.processVideoBuffer(videoBuffer);
} else {
console.error('Invalid video source.');
}
}
processVideoBuffer(buffer) {
const header = new Uint8Array([109, 118, 104, 100]);
const start = this.indexOfSequence(buffer, header) + 16;
const timeScale = this.readUInt32BE(buffer, start);
const duration = this.readUInt32BE(buffer, start + 4);
let lengthSeconds = Math.floor(duration / timeScale);
let lengthMS = Math.floor((duration / timeScale) * 1000);
return {
ms: lengthMS,
seconds: lengthSeconds,
timeScale: timeScale,
duration: duration,
};
}
isURL(input) {
try {
new URL(input);
return true;
} catch (error) {
return false;
}
}
isVideoFile(file) {
return file.type.startsWith('video/');
}
readVideoFile(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = (event) => {
resolve(new Uint8Array(event.target.result));
};
reader.onerror = (event) => {
reject(event.error);
};
reader.readAsArrayBuffer(file);
});
}
readUInt32BE(buffer, offset) {
return (buffer[offset] << 24) |
(buffer[offset + 1] << 16) |
(buffer[offset + 2] << 8) |
buffer[offset + 3];
}
indexOfSequence(buffer, sequence) {
for (let i = 0; i < buffer.length - sequence.length + 1; i++) {
let match = true;
for (let j = 0; j < sequence.length; j++) {
if (buffer[i + j] !== sequence[j]) {
match = false;
break;
}
}
if (match) {
return i;
}
}
return -1;
}
}