欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

在Vue3中使用EasyPlayer.js播放器的具體流程

 更新時間:2025年04月03日 09:29:15   作者:EasyNTS  
EasyPlayer.js是一款強大的H5播放器,專為現(xiàn)代網(wǎng)頁設(shè)計,提供對多種視頻流協(xié)議的支持,這篇文章主要介紹了在Vue3中使用EasyPlayer.js播放器的具體流程,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

前言

隨著技術(shù)的發(fā)展,越來越多的H5流媒體播放器開始支持H.265編碼格式。例如,EasyPlayer.js播放器能夠支持H.264、H.265等多種音視頻編碼格式,這使得播放器能夠適應(yīng)不同的視頻內(nèi)容和網(wǎng)絡(luò)環(huán)境。

在Vue3中如何使用EasyPlayer.js播放器?具體流程如下:

1)首先通過npm引入easyplayer.js;

npm install @easydarwin/easyplayer

2)然后找到項目node_modules中的easydarwin,如下:

3)逐級點擊easyplayer->dist->element;

4)找到EasyPlayer-element.min.js、EasyPlayer.wasm,將這兩個文件復(fù)制到項目的根目錄下;

5)在項目的入口文件index.html中,通過script標簽引入EasyPlayer-element.min.js,如下圖:

6)完成以上操作后,就可以在vue組件中直接使用EasyPlayer播放器了。

注意:如果需要使用到快照功能,需要先獲取播放器easyplayer的vue實例,然后通過實例去調(diào)用snapshot方法。

EasyPlayer屬于一款高效、精煉、穩(wěn)定且免費的流媒體播放器,可支持多種流媒體協(xié)議播放,無須安裝任何插件,起播快、延遲低、兼容性強,使用非常便捷,并且已實現(xiàn)網(wǎng)頁端實時錄像、在iOS上實現(xiàn)低延時直播等功能。

H5流媒體播放器如EasyPlayer.js支持多種流媒體協(xié)議播放,無需安裝任何插件,即可在瀏覽器中直接播放視頻流。H5播放器不僅支持直播和點播播放,還具備錄像、快照截圖、MP4播放、多屏播放、倍數(shù)播放、全屏播放等功能特性。

H5流媒體播放器還具有跨平臺兼容性的優(yōu)勢,能夠無縫地運行在谷歌瀏覽器、火狐瀏覽器等主流瀏覽器上,為用戶提供一致的使用體驗。

附:vue3+easyplayer封裝組件

使用easyplayer.js版本為 https://github.com/EasyDarwin/EasyPlayer.js/tree/main

由于new easyplayer生成實例需要一段時間才能進行播放url,所以不斷請求play方法,或者設(shè)置按鈕手動點擊開始播放

由于監(jiān)聽不到截圖回調(diào)的事件,使用點擊監(jiān)聽元素,手動觸發(fā)截圖功能并調(diào)用自身邏輯

自定義禁用右鍵彈窗信息

<template>
  <div style="position: absolute; top: 0; left: 0; width: 100%; height: 100%">
    <slot name="header" v-if="!fullscreen"></slot>
    <div class="player-wrapper">
      <!-- 播放器容器 -->
      <div ref="playerContainer" class="player-box" @contextmenu="contextmenu">
        <div class="no-data" v-if="noData">{{ attrs.alt }}</div>
        <slot name="header" v-if="fullscreen"></slot>
        <slot></slot>
      </div>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, onBeforeUnmount, watch, nextTick } from 'vue';

// 接收父組件的動態(tài)屬性(包括所有配置項)
type easyPlayerProps = {
  alt?: string; // 無數(shù)據(jù)時顯示的文本
  videoUrl: string; // 視頻地址
  isLive?: boolean; // 是否直播
  hasAudio?: boolean; // 是否解析音頻
  isMute?: boolean; // 是否靜音
  stretch?: boolean; // 是否拉伸視頻
  bufferTime?: number; // 緩沖時間
  loadTimeOut?: number; // 加載超時時間
  loadTimeReplay?: number; // 重連次數(shù)
  MSE?: boolean; // MSE 模式
  WCS?: boolean; // WCS 模式
  WASM?: boolean; // WASM 模式
  isReplay?: boolean; // 是否回放
  gpuDecoder?: boolean; // 硬解碼
  watermark?: object | null; // 水印配置
  fullWatermark?: object | null; // 全屏水印
  debug?: boolean; // 是否打印日志
};

const attrs = withDefaults(defineProps<easyPlayerProps>(), {
  isLive: true,
  hasAudio: true,
  isMute: false,
  stretch: true,
  isReplay: false,
  bufferTime: 1,
  loadTimeOut: 30,
  loadTimeReplay: 3,
  MSE: false,
  WCS: true,
  WASM: false,
  gpuDecoder: false,
  watermark: null,
  fullWatermark: null,
  debug: false,
  videoUrl: ''
});

const emits = defineEmits<{
  (e: 'fullscreen', data: any): void;
  (e: 'snapInside', data: any): void;
  (e: 'customButtons', data: any): void;
  (e: 'videoInfo', data: any): void;
}>();

// 播放器 DOM 容器引用
const playerContainer = ref<HTMLDivElement | null>(null);
let playerInstance: any = null; // 播放器實例
const noData = ref(true); // 是否無數(shù)據(jù)

// 配置與狀態(tài)
const config = reactive({
  isLive: attrs.isLive,
  hasAudio: attrs.hasAudio,
  isMute: attrs.isMute,
  stretch: attrs.stretch,
  bufferTime: attrs.bufferTime,
  loadTimeOut: attrs.loadTimeOut,
  loadTimeReplay: attrs.loadTimeReplay,
  MSE: attrs.MSE,
  WCS: attrs.WCS,
  WASM: attrs.WASM,
  gpuDecoder: attrs.gpuDecoder,
  watermark: attrs.watermark,
  fullWatermark: attrs.fullWatermark,
  debug: attrs.debug
});

const fullscreen = ref(false);
let isPlay = false;

// 初始化播放器
const initializePlayer = () => {
  if (playerContainer.value) {
    playerInstance = new (window as any).EasyPlayerPro(playerContainer.value, {
      isLive: config.isLive,
      hasAudio: config.hasAudio,
      isMute: config.isMute,
      stretch: config.stretch,
      bufferTime: config.bufferTime,
      loadTimeOut: config.loadTimeOut,
      loadTimeReplay: config.loadTimeReplay,
      MSE: config.MSE,
      WCS: config.WCS,
      WASM: config.WASM,
      gpuDecoder: config.gpuDecoder,
      watermark: config.watermark,
      fullWatermark: config.fullWatermark,
      debug: config.debug
    });

    console.log('播放器實例', playerInstance);
    // 事件監(jiān)聽
    playerInstance.on('fullscreen', (status: boolean) => {
      console.log('全屏', status);
      fullscreen.value = status;
      emits('fullscreen', status);
    });

    playerInstance.on('videoInfo', (data: any) => {
      isPlay = true;
      playerContainer.value?.querySelector('.easyplayer-icon-screenshot')?.addEventListener('click', screenshot);
      emits('videoInfo', data);

      if (!attrs.isReplay) {
        return;
      }
      // 獲取子元素
      const childElement = document.querySelector('.easyplayer-record');
      if (childElement) {
        // 向上遍歷兩層父節(jié)點(根據(jù)實際HTML結(jié)構(gòu))
        const parentContainer = childElement.parentNode;
        // 確保父容器存在且是HTMLElement
        if (parentContainer instanceof HTMLElement) {
          parentContainer.style.display = 'none'; // 安全地設(shè)置樣式
        }
      }
    });

    playerInstance.on('timeout', (error: any) => console.error('timeout:', error));

    playerInstance.on('recordStart', () => {
      emits('customButtons', '錄像');
    });

    playerInstance.on('recordEnd', () => {
      emits('customButtons', '錄像');
    });

    playerInstance.on('error', (error: any) => {
      console.error('播放錯誤:', error);
      destroyPlayer();
    });
  }
};

// 鼠標右鍵事件隱藏
const contextmenu = () => {
  nextTick(() => {
    let playBtn = playerContainer.value?.querySelector('.easyplayer-contextmenu-btn') as any;
    playBtn?.remove();
  });
};

const screenshot = () => {
  const base64 = playerInstance.screenshot('', 'png', 0.2, 'base64');
  emits('snapInside', base64);
};

let timeout: any = null;
// 銷毀播放器
const destroyPlayer = () => {
  return new Promise(resolve => {
    if (playerInstance) {
      playerContainer.value?.querySelector('.easyplayer-icon-screenshot')?.removeEventListener('click', screenshot);
      playerInstance.destroy();
      playerInstance = null;
    }

    isPlay = false;
    clearTimeout(timeout);

    setTimeout(() => {
      resolve(null);
    }, 100);
  });
};

//重播
const onReplay = () => {
  destroyPlayer().then(() => {
    initializePlayer();
    play();
  });
};

// 播放功能
const play = () => {
  console.log('播放視頻', attrs.videoUrl);
  noData.value = false;
  setTimeout(
    url => {
      playerInstance &&
        playerInstance
          .play(url)
          .then(() => {
            if (playerContainer.value) {
              let playBtn = playerContainer.value.querySelector('.easyplayer-play') as any;
              playBtn.style = 'display:block';
            }
            timeout = setTimeout(() => {
              console.log(isPlay);
              if (!isPlay) {
                play();
              }
            }, 1000);
          })
          .catch((error: any) => {
            console.error('播放失敗:', error);
          });
    },
    100,
    attrs.videoUrl
  );
};

// 暫停功能
const pause = () => {
  playerInstance?.pause();
};

// 靜音功能
const toggleMute = () => {
  const isMuted = playerInstance?.isMute();
  playerInstance?.setMute(!isMuted);
};

// 全屏功能
const toggleFullscreen = () => {
  playerInstance?.setFullscreen();
};

// 屬性監(jiān)聽:當(dāng)配置變化時重新初始化播放器
watch(
  () => attrs.videoUrl,
  newVal => {
    console.log(newVal, playerInstance);
    if (newVal) {
      onReplay();
    } else {
      noData.value = true;
      destroyPlayer();
    }
  },
  { deep: true }
);

// 生命周期管理
onMounted(() => {
  if (attrs.videoUrl) {
    initializePlayer();
    play();
  }
});

onBeforeUnmount(() => {
  destroyPlayer();
});

// 暴露方法供父組件調(diào)用
defineExpose({
  pause,
  onReplay,
  play,
  toggleMute,
  toggleFullscreen,
  stop,
  destroyPlayer
});
</script>

<style scoped>
.player-wrapper {
  position: absolute;
  width: 100%;
  height: 100%;
  margin: auto;
}
.player-box {
  position: relative;
  width: 100%;
  height: 100%;
  background-color: black;
}
.no-data {
  position: absolute;
  top: 50%;
  left: 50%;
  z-index: 999;
  font-size: 16px;
  color: #ffffff;
  transform: translate(-50%, -50%);
}
</style>

總結(jié)

到此這篇關(guān)于在Vue3中使用EasyPlayer.js播放器的文章就介紹到這了,更多相關(guān)Vue3使用EasyPlayer.js播放器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決vue3中內(nèi)存泄漏的問題

    解決vue3中內(nèi)存泄漏的問題

    在項目中會發(fā)現(xiàn)一個奇怪的現(xiàn)象,當(dāng)我們在使用element-plus中的圖標組件時會出現(xiàn)內(nèi)存泄漏,所以本文講給大家講講如何解決vue3中的內(nèi)存泄漏的問題,需要的朋友可以參考下
    2023-07-07
  • vue3.0-monaco組件封裝存檔代碼解析

    vue3.0-monaco組件封裝存檔代碼解析

    這篇文章主要介紹了vue3.0-monaco組件封裝存檔代碼解析,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2024-03-03
  • 如何解決Element UI中NavMenu折疊菜單的坑

    如何解決Element UI中NavMenu折疊菜單的坑

    這篇文章主要介紹了如何解決Element UI中NavMenu折疊菜單的坑,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-07-07
  • Vue利用computer解決單項數(shù)據(jù)流的問題詳解

    Vue利用computer解決單項數(shù)據(jù)流的問題詳解

    Vue 是一個非常流行和強大的前端框架,它讓我們可以用簡潔和優(yōu)雅的方式來構(gòu)建用戶界面,今天我們來分享一個 Vue 中非常經(jīng)典的問題,也是一個非常實用的技巧,希望對大家有所幫助
    2023-07-07
  • 詳解vue數(shù)據(jù)響應(yīng)式原理之?dāng)?shù)組

    詳解vue數(shù)據(jù)響應(yīng)式原理之?dāng)?shù)組

    這篇文章主要為大家詳細介紹了vue數(shù)據(jù)響應(yīng)式原理之?dāng)?shù)組,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-02-02
  • vue組件props屬性監(jiān)聽不到值變化問題

    vue組件props屬性監(jiān)聽不到值變化問題

    這篇文章主要介紹了vue組件props屬性監(jiān)聽不到值變化問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue?axios庫發(fā)送請求的示例介紹

    Vue?axios庫發(fā)送請求的示例介紹

    axios是基于promise的HTTP庫,可以使用在瀏覽器和node.js中,它不是vue的第三方插件,vue-axios是axios集成到Vue.js的小包裝器,可以像插件一樣安裝使用:Vue.use(VueAxios,?axios),本文給大家介紹Vue?axios和vue-axios關(guān)系,感興趣的朋友一起看看吧
    2022-08-08
  • vue實現(xiàn).md文件預(yù)覽功能的兩種方法詳解

    vue實現(xiàn).md文件預(yù)覽功能的兩種方法詳解

    這篇文章主要介紹了Vue預(yù)覽.md文件的兩種方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2025-04-04
  • 關(guān)于怎么在vue項目里寫react詳情

    關(guān)于怎么在vue項目里寫react詳情

    本篇文章是在vue項目里寫tsx的一篇介紹。其實vue里面寫jsx也挺有意思的,接下來小編九給大家詳細介紹吧,感興趣的小伙伴請參考下面的文章內(nèi)容
    2021-09-09
  • vue中調(diào)接口的方式詳解this.$api、直接調(diào)用、axios

    vue中調(diào)接口的方式詳解this.$api、直接調(diào)用、axios

    這篇文章主要介紹了vue中調(diào)接口的方式:this.$api、直接調(diào)用、axios,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-11-11

最新評論