vue3 獲取視頻第一幀/base64轉(zhuǎn)為blob/blob轉(zhuǎn)為file

img標(biāo)簽使用第一幀方法

:poster="url+'?x-oss-process=video/snapshot,t_1,m_fast'"

獲取視頻第一幀

//  使用示例
getVideoposter(url, 512, 300)
       .then((base64Data) => {
              let blob = dataURLtoBlob(base64Data);
              let newName = `${file.name.split(".")[file.name.split(".").length - 2]
                }.png`;
              let newFile = blobToFile(blob, newName);
              // 通過(guò)上傳方法上傳至服務(wù)器獲取返回的URL
              uploadImg(newFile).then((imageUrl) => {
                // you have  an imgUrl! do sth now!
              });
            })
            .catch((e) => {
              console.log("e:", e);
            })
            .finally(() => {});
        } 

// 獲取視頻封幀數(shù)封面base64
/**  
  因?yàn)橐曨l中有手機(jī)中橫屏視頻也有豎屏視頻  本方法內(nèi)含視頻中間區(qū)域截屏
  而非全部截屏 所以有些關(guān)于長(zhǎng)寬的判斷 
  注注注:還有一點(diǎn)需要注明的 也是費(fèi)了我不少時(shí)間才大約弄明白 瀏覽器好像對(duì)base64截圖有大小的限制  
  剛開始寫的時(shí)候沒有限制大小取全屏的截圖 結(jié)果cavas繪制的圖 總是上面一部分 
  下面并未繪制  這時(shí)候有兩個(gè)方案 一是降低清晰度 第二是修改瀏覽器對(duì)這個(gè)的默認(rèn)大小
  具體方法百度 總之希望大家不要像我這樣自查cavans方法 耽誤太多時(shí)間 這不是我們的問(wèn)題
*/
const getVideoposter = async (url, w, h) => {
  return new Promise((resolve, reject) => {
    let imgbase64 = null;
    let video = document.createElement("video");
    video.setAttribute("crossOrigin", "Anonymous");
    video.setAttribute("src", url);
    video.setAttribute("preload", "auto"); // 不設(shè)置該項(xiàng)就不會(huì)開啟預(yù)先加載視頻,那么拿到的會(huì)是黑屏
    //如果不設(shè)置currentTime,畫出來(lái)的圖片是空的 當(dāng)前為截取第0.001秒
    video.currentTime = 0.001;
    // video.onloadeddata = loadedmetadata;
    video.addEventListener("loadeddata", function () {
      let canvas = document.createElement("canvas");
      let vWidth = video.videoWidth;
      let vHeight = video.videoHeight;
      let whScale = vWidth / vHeight;
      let widthBg = 512;
      let heightBg;
      let splitHeight = 0;
      if (vWidth < vHeight) {
        console.log("上下長(zhǎng)圖片");
        heightBg = 300;
        // heightBg = vHeight * 512 / vWidth;
        splitHeight = vHeight / 2 - 150;
        console.log("splitHeight:", splitHeight);
      } else {
        console.log("左右寬圖片");
        heightBg = vHeight;
        // widthBg = heightBg * whScale;
        // console.log('左右寬的widthBg:', widthBg);
      }
      //設(shè)置倍數(shù)是rate,倍數(shù)越大畫圖的圖片越大,加載速度越慢
      let rate = 1;
      canvas.width = widthBg * rate;
      canvas.height = 300;
      // canvas.height = '100%'
      canvas
        .getContext("2d")
        .drawImage(
          video,
          0,
          splitHeight,
          vWidth,
          heightBg,
          0,
          0,
          canvas.width,
          canvas.height
        );
      imgbase64 = canvas.toDataURL("image/png");
      // console.log("uimgbase64rl:",imgbase64);
      resolve(imgbase64);

      // 以下為保存本地圖片方案 備用之
      // const MIME_TYPE = 'image/png'; // 保存文件類型
      // const dlLink = document.createElement('a');
      // dlLink.download = '截圖'; // 文件名
      // dlLink.href = imgbase64;
      // dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');
      // document.body.appendChild(dlLink);
      // dlLink.click();
      // document.body.removeChild(dlLink);
    });
  });
};

// 將base64轉(zhuǎn)換為blob
const dataURLtoBlob = (dataurl) => {
  let arr = dataurl.split(",");
  let mime = arr[0].match(/:(.*?);/)[1];
  let bstr = window.atob(arr[1]);
  let n = bstr.length;
  let u8arr = new Uint8Array(n);
  while (n--) {
    u8arr[n] = bstr.charCodeAt(n);
  }
  return new Blob([u8arr], { type: mime });
};
// 將blob轉(zhuǎn)換為file
const blobToFile = (theBlob, fileName) => {
  theBlob.lastModifiedDate = new Date();
  theBlob.name = fileName;
  return theBlob;
};
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容