国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

vue項目中視頻實時播放時播放器遇到的問題和解決過程 flv.js - EasyPlayer - LivePlayer

這篇具有很好參考價值的文章主要介紹了vue項目中視頻實時播放時播放器遇到的問題和解決過程 flv.js - EasyPlayer - LivePlayer。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

場景需求

  1. 需要畫面監(jiān)控設(shè)備實時播放,支持HTTP-FLV直播流,支持其他流后續(xù)可能會更換
  2. 需要類似于安防監(jiān)控多個視頻實時畫面同步
  3. 播放器可控制度強(qiáng),完全由我們來控制播放暫停進(jìn)行拉流斷流

實現(xiàn)過程

項目使用的是的vue3+ts

1. 使用flv.js

原本使用的video.js 但是不支持HTTP-FLV播放,改用flv.js

引入flv.js

npm install --save flv.js

開發(fā)問題和解決方案:

  • flv.js視頻暫停時會有延遲增長,隨著暫停時間越久延遲越長幾秒幾分鐘或者更長
    解決辦法:手動處理buffer時長,進(jìn)行刪減幀或加速播放
  • 我需要當(dāng)暫停播放按鈕觸發(fā)時呼叫服務(wù)端拉流斷流,flv.js視頻播放時離開此頁面或者有遮擋此頁面會自動觸發(fā)video標(biāo)簽的暫停事件,回到此頁面時也會自動幫你播放,但不會通知你也不會觸發(fā)video標(biāo)簽的播放事件
    解決辦法:執(zhí)行銷毀再創(chuàng)建flv.js

flv.js組件代碼(需要請自行修改監(jiān)聽部分邏輯)

<template>
  <div class="w-full h-full" v-if="deviceState !== 0">
    <video
      v-show="createEl"
      id="videoElement"
      ref="videoElement"
      controls
      disablePictureInPicture
      class="FlvVideo w-full h-full"
      @click.prevent="onClick"
      @pause="onPause"
      muted
      @play="play"
    ></video>
     <!--下面部分html是暫停時的畫面,flv.js沒有創(chuàng)建時是觸發(fā)不了播放,通過這個暫停畫面來創(chuàng)建實例/播放 -->
     <!-- class="rounded-md flex justify-center items-center w-full h-full maskLayer" 這個是Tailwind Css語法-->
    <div v-show="!createEl" class="rounded-md flex justify-center items-center w-full h-full maskLayer">
      <SvgIcon name="loading" size="30" class="rotate" v-if="loading" />
      <div class="wrap" @click="onPlay" v-else>
        <SvgIcon name="play" size="20" fillColor="#ffffff" class="ml-0.8" />
      </div>
    </div>
  </div>
  <div class="rounded-md flex justify-center items-center w-full h-full maskLayer text-light-50" v-else>
    設(shè)備離線
  </div>
</template>
<script setup name="videoFlv" lang="ts">
import { ref, onBeforeUnmount, watch } from "vue"
import flvjs from "flv.js"
import SvgIcon from "/@/components/Icon"
import _ from "lodash-es"

type VideoProps = {
  destroy: number | boolean//拉流斷流的狀態(tài)
  sources: string//視頻地址
  status?: number | undefined
  loading?: boolean
  deviceState?: number
}
const emit = defineEmits(["onPlay", "onPause"])
const props = defineProps<VideoProps>()

let flvPlayer: flvjs.Player | null = null
let videoElement = ref<HTMLMediaElement | null>(null)
let timer: any = null
let createEl = ref<boolean | null>(null)
const pauseState = ref<boolean>(true) //為了避免在銷毀時重復(fù)執(zhí)行暫停

// 清除緩存延遲
const buffered = () => {
  timer = window.setInterval(() => {
    if (videoElement.value && videoElement.value.buffered.length > 0) {
      const end = videoElement.value.buffered.end(0) // 視頻結(jié)尾時間
      const current = videoElement.value.currentTime //  視頻當(dāng)前時間
      const diff = end - current // 相差時間
      const diffCritical = 4 // 這里設(shè)定了超過4秒以上就進(jìn)行跳轉(zhuǎn)
      const diffSpeedUp = 1 // 這里設(shè)置了超過1秒以上則進(jìn)行視頻加速播放
      const maxPlaybackRate = 4 // 自定義設(shè)置允許的最大播放速度
      let playbackRate = 1.0 // 播放速度

      if (diff > diffCritical) {
        // console.log("相差超過4秒,進(jìn)行跳轉(zhuǎn)");
        videoElement.value.currentTime = end - 1.5
        playbackRate = Math.max(1, Math.min(diffCritical, 16))
      } else if (diff > diffSpeedUp) {
        // console.log("相差超過1秒,進(jìn)行加速");
        playbackRate = Math.max(1, Math.min(diff, maxPlaybackRate, 16))
      }

      videoElement.value.playbackRate = playbackRate
    }
  }, 1000)
}
// 創(chuàng)建flv.js實例
const createVideo = (url) => {
  if (flvjs.isSupported()) {
    flvPlayer = flvjs.createPlayer(
      {
        type: "flv",
        url, //你的url地址
        isLive: true,
        hasVideo: true,
        hasAudio: true
      },
      {
        enableWorker: false, //不啟用分離線程
        enableStashBuffer: true, //關(guān)閉IO隱藏緩沖區(qū)
        reuseRedirectedURL: true, //重用301/302重定向url,用于隨后的請求,如查找、重新連接等。
        autoCleanupSourceBuffer: true, //自動清除緩存
        lazyLoad: false, // 去掉懶加載,新增
        fixAudioTimestampGap: false //false才會音視頻同步,新增
      }
    )
    flvPlayer.attachMediaElement(videoElement.value as HTMLMediaElement)
    flvPlayer.load()
    flvPlayer.play()

    flvPlayer.on(flvjs.Events.ERROR, () => {
      flvPlayer && reloadVideo()
    })
  }
  createEl.value = true
}
const antiShake = (Fn) => _.throttle(Fn, 2000, { leading: true })

const onClick = antiShake(() => {
  if (!videoElement.value || !flvPlayer) return
  if (videoElement.value.paused) {
    flvPlayer.play()
  } else {
    flvPlayer.pause()
  }
})

// 這一步其實處理buffer有沒有都可以,只不過防止拉流中卡頓的可能性
const play = () => {
  buffered()
}

// 自定義暫停頁面的paly事件
const onPlay = antiShake(() => {
  emit("onPlay", true)
})

const onPause = antiShake(() => {
  //初始化靜音時頁面被遮擋才會由flv.js觸發(fā)puase
  timer && window.clearInterval(timer)
  if (!props.status && !pauseState.value) {
    destoryVideo()
    emit("onPause", false)
    pauseState.value = true
  }
})

// 重置
const reloadVideo = () => {
  destoryVideo()
  createVideo(props.sources)
}

// 銷毀/創(chuàng)建
const watchDestroy = watch(
  () => props.destroy,
  () => {
    if (props.destroy && createEl.value) {
      timer && window.clearInterval(timer)
      destoryVideo()
    } else if (props.destroy === 0) {
      pauseState.value = false
      createVideo(props.sources)
    }
  }
)

// 銷毀
const destoryVideo = () => {
  if (!pauseState.value) {
    flvPlayer!.pause() //暫停播放數(shù)據(jù)流
    pauseState.value = true
  }
  flvPlayer!.unload() //取消數(shù)據(jù)流加載
  flvPlayer!.detachMediaElement() //將播放實例從節(jié)點中取出
  flvPlayer!.destroy() //銷毀播放實例
  flvPlayer = null
  createEl.value = false
}

// 組件卸載/清除監(jiān)聽
onBeforeUnmount(() => {
  watchDestroy()
  timer && window.clearInterval(timer)
  props.destroy && createEl.value && destoryVideo()
})
</script>
<style scoped>
html[data-theme="dark"] .wrap,
html[data-theme="dark"] .maskLayer {
  background-color: #000;
}

.maskLayer {
  background-color: var(--bg-dark-color);
}

@keyframes rotate {
  0% {
    transform: rotate(0);
  }

  25% {
    transform: rotate(90deg);
  }

  50% {
    transform: rotate(180deg);
  }

  75% {
    transform: rotate(270deg);
  }

  100% {
    transform: rotate(360deg);
  }
}

.FlvVide {
  object-fit: fill;
}

video::-webkit-media-controls-timeline {
  display: none;
}

video::-webkit-media-controls-current-time-display {
  display: none;
}

.wrap {
  width: 65px;
  height: 65px;
  display: flex;
  justify-content: center;
  align-items: center;
  border-radius: 50%;
  background: rgb(154 154 154 / 0%);
  border: 2px solid #fff;
  cursor: pointer;
}

.rotate {
  animation: rotate 3s linear infinite;
}
</style>


我是借鑒這位博主的 https://blog.csdn.net/weixin_45906632/article/details/115031633

這篇分享的也很完整 https://juejin.cn/post/7050739831403446286

2. 使用EasyPlayer.js

上面flv.js已經(jīng)解決了我一部分的使用需求,但是銷毀創(chuàng)建的方法,用戶體驗很差,只是暫停每次都要等個三秒左右才可以播放(因為要重新創(chuàng)建加拉流這個過程),并且不能支持其他直播協(xié)議,不能同時控制多個直播分屏畫面(flv.js 創(chuàng)建六個視頻共同維護(hù)起來很不方便),這些問題EasyPlayer都有做相應(yīng)的改善

引入EasyPlayer

npm install @easydarwin/easyplayer --save

Vue 集成調(diào)用
copy node_modules/@easydarwin/easyplayer/dist/component/EasyPlayer.swf 到 靜態(tài)文件 根目錄
copy node_modules/@easydarwin/easyplayer/dist/component/crossdomain.xml 到 靜態(tài)文件 根目錄
copy node_modules/@easydarwin/easyplayer/dist/component/EasyPlayer-lib.min.js 到 靜態(tài)文件 根目錄

注意: 沒有調(diào)用會出現(xiàn)無法加載對應(yīng)插件的報錯
在 html 中引用 dist/component/EasyPlayer-lib.min.js
###H.265 copy node_modules/@easydarwin/easyplayer/dist/component/EasyPlayer.wasm 到 靜態(tài)文件 根目錄

詳細(xì)引入可以查看官網(wǎng)文檔 https://github.com/tsingsee/EasyPlayer.js/?tab=readme-ov-file

gitHub打不開的可以看這個https://www.npmjs.com/package/@easydarwin/easyplayer

開發(fā)問題和解決方案:

  • 引入時,因為官方針對vue的引入方式是npm ,通過npm安裝包import引入組件使用,引入組件后一直報錯,我以為是沒有將文件copy到根目錄的原因(官網(wǎng)有說copy node_modules的文件),我又根據(jù)文檔copy了文件并且在html中引入,還是會有報錯
    解決方法:只要不用npm的引入即可,也就不用import的導(dǎo)入了,也就是npm安裝只是為了讓你能copy對應(yīng)的文件,具體的使用還是通過cdn的方式,copy之后就可以移除包,這么看像是文檔有誤導(dǎo)了
    這篇文章就給了很好的解答 https://juejin.cn/post/7235908012673089573#comment

EasyPlayer組件代碼
使用就很簡單了,暫時還沒有需要多屏實時播放,也不需要處理buffer,只需要暫停播放時觸發(fā)接口就好

<template>
  <div class="video-box">
    <easy-player
      :video-url="sources"
      ref="videoEl"
      aspect="16:9"
      live
      autoplay
      stretch
      @pause="onPause"
      @play="onPlay"
      :video-title="title || ''"
    />
  </div>
</template>
<script setup lang="ts" name="EasyPlayerFlv">
import { ref, onUnmounted } from "vue"

type VideoProps = {
  sources: string//url
  title?: string//直播名稱
}
const emit = defineEmits(["onPlay", "onPause"])
defineProps<VideoProps>()

let videoEl = ref<any>(null)

const onPlay = () => {
  emit("onPlay", true)
}

const onPause = () => {
  emit("onPause", false)
}

onUnmounted(() => {
  console.log("videoEl.value :>> ", videoEl.value)
  // easyPlayer.value!.destroyPlayer()
})
</script>

<style scoped>
.video-box {
  aspect-ratio: 16/9;
  width: 100%;
}

.video-box video {
  width: 100%;
  object-fit: cover;
}
</style>

3. 使用LivePlayer.js

EasyPlayer多屏實時播放 | 時差 | 延遲處理的很完善,EasyPlayer對于fvl.js的延遲問題采用的是追幀和加速播放,隨著你暫停時間越久他追幀速度越慢,并且在追到延遲在10s時就停止了,也就是直播畫面總是有10s的延遲(直播設(shè)備是測試過沒問題的,并且在銷毀重創(chuàng)畫面是實時的)
后來又發(fā)現(xiàn)了livePlayer,測試使用發(fā)現(xiàn)以上問題都不存在了,延遲也最慢控制在3s,也是我們項目中能接受的范圍

引入

	vue2
	
	npm install @liveqing/liveplayer
	
	vue3
	
	npm install @liveqing/liveplayer-v3

第一步 :復(fù)制依賴文件(示例 通過 webpack 插件自動復(fù)制依賴)

如果正在使用 vue2 + vue-cli, 編輯你的 vue.config.js

const CopyWebpackPlugin = require('copy-webpack-plugin');

module.exports = {
    configureWebpack: {
      plugins: [
        new CopyWebpackPlugin([
            { from: 'node_modules/@liveqing/liveplayer/dist/component/crossdomain.xml'},
            { from: 'node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf'},
            { from: 'node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js', to: 'js/'},
        ])
      ]
    }
  }

如果正在使用 vue3 + vite, 編輯你的 vite.config.js

import copy from 'rollup-plugin-copy'

export default defineConfig({
  plugins: [vue(), copy({
    targets: [
      {src: 'node_modules/@liveqing/liveplayer-v3/dist/component/liveplayer-lib.min.js', dest: 'public/js'},
    ]
  })]
})

第二步: html模板中引入依賴js

在 html 中引用 www 根目錄 liveplayer-lib.min.js

<!DOCTYPE HTML>
<html>
    <head>
        <title>template</title>
        ......
        <script src="js/liveplayer-lib.min.js"></script>
        <!-- 如果正在使用 vue-cli:
            <script src="<%= BASE_URL %>js/liveplayer-lib.min.js"></script>
        -->
    </head>
    <body>
        ......
    </body>
</html>

第三步 編輯你的 Vue 組件

import LivePlayer from '@liveqing/liveplayer' // vue2

// import LivePlayer from '@liveqing/liveplayer-v3' // vue3

  components: {
    LivePlayer
  }//vue3,語法糖就不需要這一步了

<LivePlayer :videoUrl="videoUrl" fluent autoplay live stretch></LivePlayer>

如果你上述有報錯或者一些問題可以轉(zhuǎn)變成手動復(fù)制文件

copy node_modules/@liveqing/liveplayer/dist/component/liveplayer.swf 到根目錄

copy node_modules/@liveqing/liveplayer/dist/component/crossdomain.xml 到根目錄

copy node_modules/@liveqing/liveplayer/dist/component/liveplayer-lib.min.js 到根目錄

我遇到swf文件不能訪問的錯誤,這個問題很簡單,只是因為我在html引入LivePlayer文件時沒有刪除EasyPlayer的引入導(dǎo)致它們互相影響,本來是想做一下比較所以才沒有刪除EasyPlayer(這時候就要提醒一下引入任何相同插件時確保項目中只有一種此功能插件,可能會因為內(nèi)部使用相同東西導(dǎo)致沖突,真的會查不到問題在哪,也查不到遇到相關(guān)問題的??)

更多詳細(xì)了解可以看官方文檔https://www.liveqing.com/docs/manuals/LivePlayer.html#%E5%AE%89%E8%A3%85文章來源地址http://www.zghlxwxcb.cn/news/detail-791191.html

到了這里,關(guān)于vue項目中視頻實時播放時播放器遇到的問題和解決過程 flv.js - EasyPlayer - LivePlayer的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【VideoJs】初識videojs && video.js 視頻播放器的基本使用 && videojs基礎(chǔ)用法 && videojs視頻播放器 && vue3中使用videojs

    免費,開源 插件多 可自定義 【推】 雖然,但是Videojs算好了,但我覺得有點雜,特別是文檔與插件,且自定義插件有點困難,也可能是我比較菜吧 相比之下,我還是強(qiáng)烈推薦 【Xgplayer ——點我進(jìn)入】 備用地址 http://t.csdn.cn/H0cAV Xgplayer 優(yōu)點 優(yōu)雅、美觀 文檔清晰明了 大廠出

    2024年02月03日
    瀏覽(57)
  • 音視頻項目—基于FFmpeg和SDL的音視頻播放器解析(三)

    介紹 在本系列,我打算花大篇幅講解我的 gitee 項目音視頻播放器,在這個項目,您可以學(xué)到音視頻解封裝,解碼,SDL渲染相關(guān)的知識。您對源代碼感興趣的話,請查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本文,可參考我的前一篇文章音視頻項目—基于FFmpeg和SDL的音視

    2024年02月05日
    瀏覽(106)
  • springboot + vue3實現(xiàn)視頻播放Demo(video.js & Vue3-video-play視頻播放器)

    springboot + vue3實現(xiàn)視頻播放Demo(video.js & Vue3-video-play視頻播放器)

    ffmpeg官網(wǎng) 長時長視頻java存儲及vue播放解決方法 【 攻城略地 】vue3 + video.js播放m3u8視頻流格式 Vue3-video-play組件官網(wǎng) Vue3視頻播放器組件Vue3-video-play入門教程 vue-video-player播放m3u8格式的視頻 Spring boot視頻播放(解決MP4大文件無法播放),整合ffmpeg,用m3u8切片播放。 Java獲取MP4視頻文

    2024年02月07日
    瀏覽(33)
  • java項目之網(wǎng)絡(luò)視頻播放器(ssm+mysql+jsp)

    java項目之網(wǎng)絡(luò)視頻播放器(ssm+mysql+jsp)

    風(fēng)定落花生,歌聲逐流水,大家好我是風(fēng)歌,混跡在java圈的辛苦碼農(nóng)。今天要和大家聊的是一款基于ssm的網(wǎng)絡(luò)視頻播放器。 技術(shù)交流和部署相關(guān)看文章末尾!? 開發(fā)語言:Java 框架:ssm,mybatis JDK版本:JDK1.8 數(shù)據(jù)庫:mysql 5.7+ 數(shù)據(jù)庫工具:Navicat11+ 開發(fā)軟件:eclipse/idea Maven包

    2024年02月16日
    瀏覽(21)
  • 音視頻項目—基于FFmpeg和SDL的音視頻播放器解析(二十一)

    介紹 在本系列,我打算花大篇幅講解我的 gitee 項目音視頻播放器,在這個項目,您可以學(xué)到音視頻解封裝,解碼,SDL渲染相關(guān)的知識。您對源代碼感興趣的話,請查看基于FFmpeg和SDL的音視頻播放器 如果您不理解本文,可參考我的前一篇文章音視頻項目—基于FFmpeg和SDL的音視

    2024年02月02日
    瀏覽(101)
  • 創(chuàng)維電視機(jī) | 用當(dāng)貝播放器解決創(chuàng)維電視機(jī)不能播放MKV視頻的問題

    小故事在下面,感興趣可以看看,開頭我就直接放解決方案 創(chuàng)維電視雖然是基于Android開發(fā)的,可以安裝apk軟件,但是基本不能用,一定要選擇適配電視的視頻播放器,或者使用本文中提供的創(chuàng)維版當(dāng)貝播放器。 原軟件已與本文綁定,可以通過csdn下載 或者通過我發(fā)布的gite

    2024年02月19日
    瀏覽(25)
  • 【Android入門到項目實戰(zhàn)-- 11.4】—— ExoPlayer視頻播放器框架的詳細(xì)使用

    【Android入門到項目實戰(zhàn)-- 11.4】—— ExoPlayer視頻播放器框架的詳細(xì)使用

    目錄 什么是ExoPlayer 一、基本使用 ?1、添加依賴項 ?2、布局 3、Activity 二、自定義播放暫停 1、首先如何隱藏默認(rèn)的開始暫停和快進(jìn)? 2、自定義 三、控制視頻畫面旋轉(zhuǎn)和比例調(diào)整 四、全屏放大和縮小 1、雙擊視頻放大縮小 2、按鈕放大縮小 五、完整的實現(xiàn)代碼 XML Activity ??

    2024年02月11日
    瀏覽(28)
  • 【QT項目:視頻播放器——Qt opengl編程】通過shader完成顯示yuv

    【QT項目:視頻播放器——Qt opengl編程】通過shader完成顯示yuv

    通過Qt opengl不是為了3D繪制,而是為了將視頻繪制起來 使用opengl 可以極大降低yuv轉(zhuǎn)rgb的轉(zhuǎn)換開銷 1、為什么用QT的opengl 簡單,界面可以自動疊加 void paintGL(); // 具體的繪制寫在該函數(shù)里 void initializeGL(); // 材質(zhì)初始化 void resizeGL(int width, int height); // 當(dāng)窗口發(fā)生變化(縮放) QO

    2023年04月09日
    瀏覽(27)
  • 信號:pause、alarm、kill;第二個項目:基于Mplayer的視頻播放器

    int pause(void); 功能:讓進(jìn)程睡眠直到接收到捕捉的信號才能繼續(xù)向下執(zhí)行 unsigned int alarm(unsigned int seconds); 功能:定時seconds秒后給進(jìn)程調(diào)用發(fā)送SIGALRM信號 參數(shù):seconds定時的秒數(shù) 返回值: ????????成功返回之前設(shè)定剩余的秒數(shù) int kill(pid_t, int sig) 功能:給PID對應(yīng)的進(jìn)程發(fā)送

    2024年03月10日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包