diginext-utils
Version:
README.md
74 lines (73 loc) • 2.76 kB
JavaScript
import { createReadStream } from "fs";
export async function guessMimeType(filepath) {
return new Promise((resolve, reject) => {
const stream = createReadStream(filepath, {
start: 0,
end: 11, // Read only first 12 bytes
});
let buffer = new Uint8Array(0);
stream.on("data", (chunk) => {
const chunkArray = new Uint8Array(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
// Manual concatenation
const newBuffer = new Uint8Array(buffer.length + chunkArray.length);
newBuffer.set(buffer);
newBuffer.set(chunkArray, buffer.length);
buffer = newBuffer;
});
stream.on("end", () => {
// Convert to hex string
const toHex = (arr, start, end) => {
return Array.from(arr.slice(start, end))
.map((b) => b.toString(16).padStart(2, "0"))
.join("");
};
const signature = toHex(buffer, 0, 4);
switch (signature) {
case "89504e47":
resolve("image/png");
break;
case "47494638":
resolve("image/gif");
break;
case "52494646":
if (buffer.length >= 12) {
const webpSignature = toHex(buffer, 8, 12);
if (webpSignature === "57454250") {
resolve("image/webp");
}
else {
resolve("unknown");
}
}
else {
resolve("unknown");
}
break;
case "00000018":
case "0000001c":
case "00000020":
resolve("video/mp4");
break;
case "66747970":
resolve("video/quicktime");
break;
case "1a45dfa3":
resolve("video/webm");
break;
case "000001ba":
case "000001b3":
resolve("video/mpeg");
break;
default:
if (signature.startsWith("ffd8ff")) {
resolve("image/jpeg");
}
else {
resolve("application/octet-stream");
}
}
});
stream.on("error", reject);
});
}
export default guessMimeType;