next-ucap-messenger/projects/ucap-webmessenger-core/src/lib/utils/file.util.ts

257 lines
7.6 KiB
TypeScript

const regFileExtension = /(?:\.([^.]+))?$/;
export class FileUtil {
static getExtension(fileName: string): string | undefined {
return regFileExtension.exec(fileName)[1];
}
static getExtensions(fileList: FileList): string[] {
const extensions: string[] = [];
// tslint:disable-next-line: prefer-for-of
for (let i = 0; i < fileList.length; i++) {
extensions.push(FileUtil.getExtension(fileList[i].name));
}
return extensions;
}
static fromBlobToDataUrl(blob: Blob): Promise<string | ArrayBuffer> {
return new Promise<string | ArrayBuffer>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => {
return resolve(fileReader.result);
};
fileReader.onerror = (event: ProgressEvent) => {
fileReader.abort();
return reject(fileReader.error);
};
fileReader.readAsDataURL(blob);
});
}
static fromBlobToBuffer(blob: Blob): Promise<Buffer> {
return new Promise<Buffer>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => {
return resolve(Buffer.from(fileReader.result as ArrayBuffer));
};
fileReader.onerror = (event: ProgressEvent) => {
fileReader.abort();
return reject(fileReader.error);
};
fileReader.readAsArrayBuffer(blob);
});
}
static fromBlobToString(blob: Blob): Promise<string> {
return new Promise<string>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => {
return resolve(fileReader.result.toString());
};
fileReader.onerror = (event: ProgressEvent) => {
fileReader.abort();
return reject(fileReader.error);
};
fileReader.readAsArrayBuffer(blob);
});
}
static downloadFromBlob(blob: Blob, fileName: string) {
const a = document.createElement('a');
document.body.appendChild(a);
a.style.display = 'none';
const url = URL.createObjectURL(blob);
a.href = url;
a.download = fileName;
a.click();
window.URL.revokeObjectURL(url);
a.remove();
}
static save(
buffer: Buffer,
fileName: string,
mimeType: string
): Promise<string> {
return new Promise<string>((resolve, reject) => {
const defaultMime = 'application/octet-stream';
const mime = !!mimeType ? mimeType : defaultMime;
const blob = new Blob([buffer], { type: mime });
if (navigator.msSaveBlob) {
// IE10+ : (has Blob, but not a[download] or URL)
navigator.msSaveBlob(blob, fileName);
resolve(fileName);
return;
}
const download = (url: string, mode: boolean = false) => {
const anchor = document.createElement('a');
if ('download' in anchor) {
// html5 A[download]
anchor.href = url;
anchor.setAttribute('download', fileName);
anchor.className = 'download-js-link';
anchor.innerHTML = 'downloading...';
anchor.style.display = 'none';
document.body.appendChild(anchor);
setTimeout(() => {
anchor.click();
document.body.removeChild(anchor);
resolve(fileName);
if (mode) {
setTimeout(() => {
window.URL.revokeObjectURL(anchor.href);
}, 250);
}
}, 66);
return;
}
// handle non-a[download] safari as best we can:
if (
/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(
navigator.userAgent
)
) {
url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
if (!window.open(url)) {
// popup blocked, offer direct download:
if (
confirm(
'Displaying New Document\n\nUse Save As... to download, then click back to return to this page.'
)
) {
location.href = url;
}
}
resolve(fileName);
return;
}
// do iframe dataURL download (old ch+FF):
const f = document.createElement('iframe');
document.body.appendChild(f);
if (!mode) {
// force a mime that will download:
url = 'data:' + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
}
f.src = url;
setTimeout(() => {
document.body.removeChild(f);
}, 333);
};
if (window.URL) {
download(window.URL.createObjectURL(blob), true);
} else {
if (
typeof blob === 'string' ||
(blob as any).constructor === this.toString
) {
try {
download(
'data:' + mime + ';base64,' + window.btoa((blob as any) as string)
);
} catch (e) {
download(
'data:' +
mime +
';base64,' +
encodeURIComponent((blob as any) as string)
);
}
} else {
const fileReader = new FileReader();
fileReader.onload = () => {
download(fileReader.result as string);
};
fileReader.readAsDataURL(blob);
}
}
});
}
static thumbnail(file: File): Promise<File> {
return new Promise<File>((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = () => {
const blob = new Blob([fileReader.result], { type: file.type });
const url = URL.createObjectURL(blob);
const video = document.createElement('video');
const snapImage = () =>
new Promise<Blob>((imgResolve, imgReject) => {
const canvas = document.createElement('canvas');
// thumbnail image resize
const width = video.videoWidth;
const height = video.videoHeight;
let resizeWidth = 0;
let resizeHeight = 0;
// max size
const maxWidth = 320;
const maxHeight = 320;
if (width > maxWidth || height > maxHeight) {
if (width > height) {
resizeWidth = maxWidth;
resizeHeight = Math.round((height * resizeWidth) / width);
} else {
resizeHeight = maxHeight;
resizeWidth = Math.round((width * resizeHeight) / height);
}
} else {
resizeWidth = width;
resizeHeight = height;
}
canvas.width = resizeWidth;
canvas.height = resizeHeight;
canvas
.getContext('2d')
.drawImage(video, 0, 0, canvas.width, canvas.height);
canvas.toBlob(imgBlob => {
imgResolve(imgBlob);
});
});
const timeupdate = () => {
snapImage().then(imgBlob => {
video.removeEventListener('timeupdate', timeupdate);
video.pause();
resolve(new File([imgBlob], file.name));
});
};
video.onloadeddata = () => {
snapImage().then(imgBlob => {
video.removeEventListener('timeupdate', timeupdate);
resolve(new File([imgBlob], file.name));
});
};
video.addEventListener('timeupdate', timeupdate);
video.preload = 'metadata';
video.src = url;
// Load video in Safari / IE11
video.muted = true;
// tslint:disable-next-line: no-string-literal
video['playsInline'] = true;
video.play();
};
fileReader.onerror = (event: ProgressEvent) => {
fileReader.abort();
return reject(fileReader.error);
};
fileReader.readAsArrayBuffer(file);
});
}
}