2021-05-23 15:06:21 +00:00
|
|
|
import {IAudioMetadata} from "music-metadata-browser";
|
|
|
|
|
2021-05-23 13:40:43 +00:00
|
|
|
export const FLAC_HEADER = [0x66, 0x4C, 0x61, 0x43];
|
|
|
|
export const MP3_HEADER = [0x49, 0x44, 0x33];
|
|
|
|
export const OGG_HEADER = [0x4F, 0x67, 0x67, 0x53];
|
|
|
|
export const M4A_HEADER = [0x66, 0x74, 0x79, 0x70];
|
|
|
|
export const WMA_HEADER = [
|
|
|
|
0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11,
|
|
|
|
0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C,
|
|
|
|
]
|
|
|
|
export const WAV_HEADER = [0x52, 0x49, 0x46, 0x46]
|
|
|
|
export const AAC_HEADER = [0xFF, 0xF1]
|
2021-05-23 14:29:34 +00:00
|
|
|
export const AudioMimeType: { [key: string]: string } = {
|
|
|
|
mp3: "audio/mpeg",
|
|
|
|
flac: "audio/flac",
|
|
|
|
m4a: "audio/mp4",
|
|
|
|
ogg: "audio/ogg",
|
|
|
|
wma: "audio/x-ms-wma",
|
|
|
|
wav: "audio/x-wav"
|
|
|
|
};
|
2021-05-23 13:40:43 +00:00
|
|
|
|
|
|
|
export function BytesHasPrefix(data: Uint8Array, prefix: number[]): boolean {
|
|
|
|
if (prefix.length > data.length) return false
|
|
|
|
return prefix.every((val, idx) => {
|
|
|
|
return val === data[idx];
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export function BytesEquals(data: Uint8Array, another: Uint8Array): boolean {
|
|
|
|
if (another.length != data.length) return false
|
|
|
|
return data.every((val, idx) => {
|
|
|
|
return val === another[idx];
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
export function SniffAudioExt(data: Uint8Array, fallback_ext: string = "mp3"): string {
|
2021-05-23 14:29:34 +00:00
|
|
|
if (BytesHasPrefix(data, MP3_HEADER)) return "mp3"
|
|
|
|
if (BytesHasPrefix(data, FLAC_HEADER)) return "flac"
|
|
|
|
if (BytesHasPrefix(data, OGG_HEADER)) return "ogg"
|
2021-05-23 13:40:43 +00:00
|
|
|
if (data.length >= 4 + M4A_HEADER.length &&
|
2021-05-23 14:29:34 +00:00
|
|
|
BytesHasPrefix(data.slice(4), M4A_HEADER)) return "m4a"
|
|
|
|
if (BytesHasPrefix(data, WAV_HEADER)) return "wav"
|
|
|
|
if (BytesHasPrefix(data, WMA_HEADER)) return "wma"
|
|
|
|
if (BytesHasPrefix(data, AAC_HEADER)) return "aac"
|
2021-05-23 13:40:43 +00:00
|
|
|
return fallback_ext;
|
|
|
|
}
|
2021-05-23 13:59:33 +00:00
|
|
|
|
|
|
|
export function GetArrayBuffer(obj: Blob): Promise<ArrayBuffer> {
|
|
|
|
if (!!obj.arrayBuffer) return obj.arrayBuffer()
|
|
|
|
return new Promise((resolve, reject) => {
|
|
|
|
const reader = new FileReader();
|
|
|
|
reader.onload = (e) => {
|
|
|
|
const rs = e.target?.result
|
|
|
|
if (!rs) {
|
|
|
|
reject("read file failed")
|
|
|
|
} else {
|
|
|
|
resolve(rs as ArrayBuffer)
|
|
|
|
}
|
|
|
|
};
|
|
|
|
reader.readAsArrayBuffer(obj);
|
|
|
|
});
|
|
|
|
}
|
2021-05-23 15:06:21 +00:00
|
|
|
|
|
|
|
export function GetCoverFromFile(metadata: IAudioMetadata): string {
|
|
|
|
if (metadata.common?.picture && metadata.common.picture.length > 0) {
|
|
|
|
return URL.createObjectURL(new Blob(
|
|
|
|
[metadata.common.picture[0].data],
|
|
|
|
{type: metadata.common.picture[0].format}
|
|
|
|
));
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
export interface IMusicMetaBasic {
|
|
|
|
title: string
|
|
|
|
artist?: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export function GetMetaFromFile(filename: string, exist_title?: string, exist_artist?: string, separator = "-")
|
|
|
|
: IMusicMetaBasic {
|
|
|
|
const meta: IMusicMetaBasic = {title: exist_title ?? "", artist: exist_artist}
|
|
|
|
|
|
|
|
const items = filename.split(separator);
|
|
|
|
if (items.length > 1) {
|
|
|
|
if (!meta.artist) meta.artist = items[0].trim();
|
|
|
|
if (!meta.title) meta.title = items[1].trim();
|
|
|
|
} else if (items.length === 1) {
|
|
|
|
if (!meta.title) meta.title = items[0].trim();
|
|
|
|
}
|
|
|
|
return meta
|
|
|
|
}
|
2021-05-23 17:30:38 +00:00
|
|
|
|
|
|
|
export async function GetImageFromURL(src: string):
|
|
|
|
Promise<{ mime: string; buffer: ArrayBuffer; url: string } | undefined> {
|
|
|
|
try {
|
|
|
|
const resp = await fetch(src);
|
|
|
|
const mime = resp.headers.get("Content-Type");
|
|
|
|
if (mime?.startsWith("image/")) {
|
|
|
|
const buffer = await resp.arrayBuffer();
|
|
|
|
const url = URL.createObjectURL(new Blob([buffer], {type: mime}))
|
|
|
|
return {buffer, url, mime}
|
|
|
|
}
|
|
|
|
} catch (e) {
|
|
|
|
console.warn(e)
|
|
|
|
}
|
|
|
|
}
|