| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378 |
- // TIP: ctrl+cmd+t,生成函数注释
- import { getRangeRandom } from 'billd-utils';
- import sparkMD5 from 'spark-md5';
- export const formatTimeHour = (timestamp: number) => {
- function addZero(num: number) {
- return num < 10 ? `0${num}` : num;
- }
- const date = new Date(timestamp);
- // 获取小时
- const hours = date.getHours();
- // 获取分钟
- const minutes = date.getMinutes();
- // 打印结果
- return `${addZero(hours)}:${addZero(minutes)}`;
- };
- export const formatTime = (timestamp: number) => {
- function addZero(num: number) {
- return num < 10 ? `0${num}` : num;
- }
- const date = new Date(timestamp);
- // 获取年份
- const year = date.getFullYear();
- // 获取月份(注意月份是从0开始的,所以要加1)
- const month = date.getMonth() + 1;
- // 获取日期
- const day = date.getDate();
- // 获取小时
- const hours = date.getHours();
- // 获取分钟
- const minutes = date.getMinutes();
- // 获取秒数
- const seconds = date.getSeconds();
- // 打印结果
- return `${year}-${addZero(month)}-${addZero(day)} ${addZero(hours)}:${addZero(
- minutes
- )}:${addZero(seconds)}`;
- };
- export const getLiveRoomPageUrl = (liveRoomId: number) => {
- return `${getHostnameUrl()}/pull/${liveRoomId}`;
- };
- export const getHostnameUrl = () => {
- // window.location.host,包含了域名的一个DOMString,可能在该串最后带有一个":"并跟上 URL 的端口号。
- // window.location.hostname,包含了域名的一个DOMString
- const { protocol, host } = window.location;
- return `${protocol}//${host}`;
- };
- /**
- * 根据文件内容获取hash,同一个文件不管重命名还是改文件名后缀,hash都一样
- * @param file
- * @returns
- */
- export const getHash = (file: File) => {
- return new Promise<{
- hash: string;
- ext: string;
- buffer: ArrayBuffer;
- }>((resolve) => {
- const reader = new FileReader();
- reader.readAsArrayBuffer(file);
- reader.onload = (e) => {
- const spark = new sparkMD5.ArrayBuffer();
- const buffer = e.target!.result as ArrayBuffer;
- spark.append(buffer);
- const hash = spark.end();
- const arr = file.name.split('.');
- const ext = arr[arr.length - 1];
- resolve({ hash, ext, buffer });
- };
- });
- };
- // 文件切片
- export const splitFile = (file: File) => {
- const chunkList: { chunk: Blob; chunkName: string }[] = [];
- // 先以固定的切片大小1024*100
- let max = 50 * 100;
- let count = Math.ceil(file.size / max);
- let index = 0;
- // 限定最多100个切片
- if (count > 100) {
- max = Math.ceil(file.size / 100);
- count = 100;
- }
- /**
- * 0:0,max
- * 1:max,2max
- * 2:2max,3max
- */
- while (index < count) {
- chunkList.push({
- chunkName: `${index}`,
- chunk: new File([file.slice(index * max, (index + 1) * max)], file.name),
- });
- index += 1;
- }
- return chunkList;
- };
- /**
- * 格式化倒计时
- * @param endTime
- * @param startTime
- */
- export function formatDownTime(data: {
- endTime: number;
- startTime: number;
- showMs?: boolean;
- }) {
- const times = (data.endTime - data.startTime) / 1000;
- // js获取剩余天数
- const d = parseInt(String(times / 60 / 60 / 24));
- // js获取剩余小时
- let h = parseInt(String((times / 60 / 60) % 24));
- // js获取剩余分钟
- let m = parseInt(String((times / 60) % 60));
- // js获取剩余秒
- let s = parseInt(String(times % 60));
- let ms = new Date(data.endTime).getMilliseconds();
- if (h < 10) {
- // @ts-ignore
- h = `0${h}`;
- }
- if (m < 10) {
- // @ts-ignore
- m = `0${m}`;
- }
- if (s < 10) {
- // @ts-ignore
- s = `0${s}`;
- }
- if (Number(ms) < 100) {
- if (ms < 10) {
- // @ts-ignore
- ms = `00${ms}`;
- } else {
- // @ts-ignore
- ms = `0${ms}`;
- }
- }
- const msRes = data.showMs ? `${ms}毫秒` : '';
- if (d > 0) {
- return `${d}天${h}时${m}分${s}秒${msRes}`;
- } else if (h > 0) {
- return `${h}时${m}分${s}秒${msRes}`;
- } else {
- return `${m}分${s}秒${msRes}`;
- }
- }
- /**
- * requestFileSystem保存文件,成功返回code:1,失败返回code:2
- * @param data
- */
- export function saveFile(data: { file: File; fileName: string }) {
- return new Promise<{ code: number }>((resolve) => {
- const { file, fileName } = data;
- const requestFileSystem =
- // @ts-ignore
- window.requestFileSystem || window.webkitRequestFileSystem;
- if (!requestFileSystem) {
- console.error('不支持requestFileSystem');
- resolve({ code: 2 });
- return;
- }
- function onError(err) {
- console.error('saveFile错误', data.fileName);
- console.log(err);
- resolve({ code: 2 });
- }
- function onFs(fs) {
- // 创建文件
- fs.root.getFile(
- fileName,
- { create: true },
- (fileEntry) => {
- // 创建文件写入流
- fileEntry.createWriter(function (fileWriter) {
- fileWriter.onwriteend = () => {
- // 完成后关闭文件
- fileWriter.abort();
- resolve({ code: 1 });
- };
- // 写入文件内容
- fileWriter.write(file);
- });
- },
- onError
- );
- }
- // Opening a file system with temporary storage
- requestFileSystem(
- // @ts-ignore
- window.PERSISTENT,
- 0,
- onFs,
- onError
- );
- });
- }
- /**
- * requestFileSystem读取文件,成功返回code:1,失败返回code:2
- * @param data
- */
- export function readFile(fileName: string) {
- return new Promise<{ code: number; file?: File }>((resolve) => {
- const requestFileSystem =
- // @ts-ignore
- window.requestFileSystem || window.webkitRequestFileSystem;
- if (!requestFileSystem) {
- console.error('不支持requestFileSystem');
- resolve({ code: 2 });
- return;
- }
- function onError(err) {
- console.error('readFile错误', fileName);
- console.log(err);
- resolve({ code: 2 });
- }
- function onFs(fs) {
- fs.root.getFile(
- fileName,
- {},
- (fileEntry) => {
- fileEntry.file(function (file) {
- resolve({ code: 1, file });
- }, onError);
- },
- onError
- );
- }
- // Opening a file system with temporary storage
- requestFileSystem(
- // @ts-ignore
- window.PERSISTENT,
- 0,
- onFs,
- onError
- );
- });
- }
- export function generateBase64(dom: CanvasImageSource) {
- const canvas = document.createElement('canvas');
- // @ts-ignore
- const { width, height } = dom.getBoundingClientRect();
- const rate = width / height;
- let ratio = 0.5;
- function geturl() {
- const coverWidth = width * ratio;
- const coverHeight = coverWidth / rate;
- canvas.width = coverWidth;
- canvas.height = coverHeight;
- canvas.getContext('2d')!.drawImage(dom, 0, 0, coverWidth, coverHeight);
- // webp比png的体积小非常多!因此coverWidth就可以不用压缩太夸张
- return canvas.toDataURL('image/webp');
- }
- let dataURL = geturl();
- while (dataURL.length > 1000 * 20) {
- ratio = ratio * 0.8;
- dataURL = geturl();
- }
- return dataURL;
- }
- /**
- * @description 获取随机字符串(ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz)
- * @example: getRandomString(4) ===> abd3
- * @param {number} length
- * @return {*}
- */
- export const getRandomEnglishString = (length: number): string => {
- const str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
- let res = '';
- for (let i = 0; i < length; i += 1) {
- res += str.charAt(getRangeRandom(0, str.length - 1));
- }
- return res;
- };
- export const createVideo = ({
- muted = true,
- autoplay = true,
- appendChild = false,
- show = false,
- controls = false,
- size = 100,
- }) => {
- const videoEl = document.createElement('video');
- videoEl.autoplay = autoplay;
- videoEl.muted = muted;
- videoEl.playsInline = true;
- videoEl.loop = true;
- videoEl.controls = controls;
- videoEl.setAttribute('webkit-playsinline', 'true');
- videoEl.setAttribute('x5-video-player-type', 'h5');
- videoEl.setAttribute('x5-video-player-fullscreen', 'true');
- videoEl.setAttribute('x5-video-orientation', 'portraint');
- videoEl.oncontextmenu = (e) => {
- e.preventDefault();
- };
- if (appendChild) {
- if (!show) {
- videoEl.style.width = `1px`;
- videoEl.style.height = `1px`;
- videoEl.style.opacity = '0';
- videoEl.style.pointerEvents = 'none';
- } else {
- videoEl.style.width = `${size}px`;
- videoEl.style.height = `${size}px`;
- }
- videoEl.style.position = 'fixed';
- videoEl.style.bottom = '0';
- videoEl.style.right = '0';
- document.body.appendChild(videoEl);
- }
- return videoEl;
- };
- export function videoToCanvas(data: {
- videoEl: HTMLVideoElement;
- resize?: (data: { w: number; h: number }) => void;
- }) {
- const { videoEl } = data;
- if (!videoEl) {
- throw new Error('videoEl不能为空!');
- }
- const canvas = document.createElement('canvas');
- const ctx = canvas.getContext('2d')!;
- let timer;
- let w = videoEl.videoWidth;
- let h = videoEl.videoHeight;
- function handleResize() {
- w = videoEl.videoWidth;
- h = videoEl.videoHeight;
- data.resize?.({ w, h });
- }
- data.resize?.({ w, h });
- videoEl.addEventListener('resize', handleResize);
- function drawCanvas() {
- canvas.width = w;
- canvas.height = h;
- if (w > h) {
- canvas.style.minWidth = '100%';
- } else {
- canvas.style.minHeight = '100%';
- }
- ctx.drawImage(videoEl, 0, 0, w, h);
- timer = requestAnimationFrame(drawCanvas);
- }
- function stopDrawing() {
- videoEl.removeEventListener('resize', handleResize);
- cancelAnimationFrame(timer);
- }
- drawCanvas();
- return { drawCanvas, stopDrawing, canvas };
- }
|