vue加載視頻流,實(shí)現(xiàn)直播功能的過程
前言
最近在項(xiàng)目中有一個(gè)播放監(jiān)控站點(diǎn)圖像視頻的功能(類似與直播),然后對(duì)此進(jìn)行了一個(gè)記錄與總結(jié)!
在此功能中,后臺(tái)本來給的是rtmp格式的視頻流,后在網(wǎng)上找了幾種方式,發(fā)現(xiàn)rtmp視頻流需要使用flash播放器,然而各大主流瀏覽器已經(jīng)放棄flash,因此最后又改用hls格式的視頻流,最終完成這個(gè)功能!(如果只是想要成功的代碼,請(qǐng)直接看:三、vue加載hls視頻流)
一、視頻流是什么?
- 視頻流:視頻流其實(shí)就是流媒體(streaming media),是指將一連串?dāng)?shù)據(jù)壓縮后,經(jīng)過網(wǎng)絡(luò)分段發(fā)送,即時(shí)傳輸以供觀看音視頻的一種技術(shù)。監(jiān)控、直播等實(shí)時(shí)播放的功能一般都使用的是流媒體。
- 流媒體協(xié)議:流媒體協(xié)議是一種標(biāo)準(zhǔn)化的傳遞方法,用于將視頻分解為多個(gè)塊,將其發(fā)送給視頻播放器,播放器重新組合播放,常見的有rtmp、hls、hds、mss、MPEG-DASH等。
- 視頻格式(format):視頻格式指視頻文件格式(container format)。常見 container format 包括 .mp4、.m4v、.avi、.mov等。
三種定義在這里不做過多贅述,有想深入了解的小伙伴可以自己再去了解一下;rtmp視頻流實(shí)際上就是以rtmp流媒體協(xié)議生成的流媒體;hls視頻流同理(這個(gè)視頻流的格式一般由后臺(tái)進(jìn)行控制)
二、vue加載rtmp視頻流
1.方法一:video.js
npm install --save vue-video-player npm install --save videojs-flash
<template> ?? ?<div class="box"> ?? ??? ?<section id="video" class="video-js vjs-default-skin" ref="viodeRef"></section> ?? ?</div> </template>
<script> ?? ?import Video from 'video.js' ?? ?import 'video.js/dist/video-js.min.css' ? export default { ? ? name: 'video-play-box', ? ? mounted(){ ? ? ? this.player = Video('video', { ? ? ? ? //確定播放器是否具有用戶可以與之交互的控件。沒有控件,啟動(dòng)視頻播放的唯一方法是使用autoplay屬性或通過Player API。 ? ? ? ? controls: true, ? ? ? ? //自動(dòng)播放屬性,muted:靜音播放 ? ? ? ? muted: false, ? ? ? ? autoplay: true, ? ? ? ? //建議瀏覽器是否應(yīng)在<video>加載元素后立即開始下載視頻數(shù)據(jù)。 ? ? ? ? preload: "auto", ? ? ? ? //設(shè)置視頻播放器的顯示寬度(以像素為單位) ? ? ? ? width: "800px", ? ? ? ? //設(shè)置視頻播放器的顯示高度(以像素為單位) ? ? ? ? height: "500px", ? ? ? ? // poster: 'https://static.shuxuejia.com/img/video_image.png', // 封面圖片 ? ? ? ? sources: [{ ? ? ? ? ? src:"rtmp://58.200.131.2:1935/livetv/cctv3", ? ? ? ? ? type:'video/rtmp' ? ? ? ? }], ?? ??? ??? ? ? ? ? ? playbackRates: [0.5, 1, 1.5, 2] //倍速播放 ? ? ? }, function onPlayerReady() { ? ? ? ? Video.log('Your player is ready!'); // 比如: 播放量+1請(qǐng)求 ? ? ? ? this.on('ended', function() { ? ? ? ? ? Video.log('Awww...over so soon?!'); ? ? ? ? }); ? ? ? }); ? ? ? // this.myPlayer.src('rtmp://10.15.3.31:1935/live/openUrl/QUDplmM') ? ? ? // this.myPlayer.load('rtmp://10.15.3.31:1935/live/openUrl/QUDplmM') ?? ??? ?}, ? ? beforeDestroy() { ? ? ? if (this.player) { ? ? ? ? this.player.dispose() ? ? ? } ? ? }, ?? ??? ? ? } </script>
<style scoped lang="scss"> .box{ ?? ?width:100%; ?? ?height:100%; ?? ?display:flex; ?? ?align-items: center; ?? ?justify-content: center; ?? ?.video{ ?? ??? ?margin:0 auto; ?? ?} } </style>
2.方法二:ckplayer
因?yàn)楸救艘呀?jīng)嘗試過由于flash原因不可用,所以已經(jīng)都刪掉了,沒有部分截圖,就文字描述一下,感興趣的小伙伴可以自己搜一下。
- 第一步:官網(wǎng)下載ckplayer
- 第二步:將下載好的文件夾解壓后放到項(xiàng)目中的static(靜態(tài)資源文件夾)下
- 第三步:在index.html中對(duì)應(yīng)引入ckplayer.js文件
- 第四步:創(chuàng)建播放視頻的vue文件,代碼如下:
<template> ? <div> ? ? <label>ckplayer播放器插件Vue使用Demo</label> ? ? <div id="video"></div> ? </div> </template>
<script> export default { ? name: 'ckplayerPlugin', ? data () { ? ? return { ? ? } ? }, ? mounted: function(){ ? ? // 掛載完成后進(jìn)行 ? ? var videoObject = { ? ? ? ? ? ? ? ? container: '#video', //容器的ID或className ? ? ? ? ? ? ? ? variable: 'player', //播放函數(shù)名稱 ? ? ? ? ? ? ? ? loaded: 'loadedHandler', //當(dāng)播放器加載后執(zhí)行的函數(shù) ? ? ? ? ? ? ? ? loop: true, //播放結(jié)束是否循環(huán)播放 ? ? ? ? ? ? ? ? cktrack: 'static/ckplayer/material/srt.srt', //字幕文件 ? ? ? ? ? ? ? ? poster: 'static/ckplayer/material/poster.jpg', //封面圖片 ? ? ? ? ? ? ? ? preview: { //預(yù)覽圖片 ? ? ? ? ? ? ? ? ? ? file: ['static/ckplayer/material/mydream_en1800_1010_01.png', 'static/ckplayer/material/mydream_en1800_1010_02.png'], ? ? ? ? ? ? ? ? ? ? scale: 2 ? ? ? ? ? ? ? ? }, ? ? ? ? ? ? ? ? config: '', //指定配置函數(shù) ? ? ? ? ? ? ? ? debug: true, //是否開啟調(diào)試模式 ? ? ? ? ? ? ? ? drag: 'start', //拖動(dòng)的屬性 ? ? ? ? ? ? ? ? seek: 0, //默認(rèn)跳轉(zhuǎn)的時(shí)間 ? ? ? ? ? ? ? ? //廣告部分開始 ? ? ? ? ? ? ? ? adfront: 'http://×××w.ckplayer.com/yytf/swf/front001.swf,http://×××w.ckplayer.com/yytf/swf/front002.swf', //前置廣告 ? ? ? ? ? ? ? ? adfronttime: '15,15', ? ? ? ? ? ? ? ? adfrontlink: '', ? ? ? ? ? ? ? ? adpause: 'http://×××w.ckplayer.com/yytf/swf/pause001.swf,http://×××w.ckplayer.com/yytf/swf/pause002.swf', ? ? ? ? ? ? ? ? adpausetime: '5,5', ? ? ? ? ? ? ? ? adpauselink: '', ? ? ? ? ? ? ? ? adinsert: 'http://×××w.ckplayer.com/yytf/swf/insert001.swf,http://×××w.ckplayer.com/yytf/swf/insert002.swf', ? ? ? ? ? ? ? ? adinserttime: '10,10', ? ? ? ? ? ? ? ? adinsertlink: '', ? ? ? ? ? ? ? ? inserttime: '10,80', ? ? ? ? ? ? ? ? adend: 'http://×××w.ckplayer.com/yytf/swf/end001.swf,http://×××w.ckplayer.com/yytf/swf/end002.swf', ? ? ? ? ? ? ? ? adendtime: '15,15', ? ? ? ? ? ? ? ? adendlink: '', ? ? ? ? ? ? ? ? //廣告部分結(jié)束 ? ? ? ? ? ? ? ? promptSpot: [ //提示點(diǎn) ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? words: '提示點(diǎn)文字01', ? ? ? ? ? ? ? ? ? ? ? ? time: 30 ? ? ? ? ? ? ? ? ? ? }, ? ? ? ? ? ? ? ? ? ? { ? ? ? ? ? ? ? ? ? ? ? ? words: '提示點(diǎn)文字02', ? ? ? ? ? ? ? ? ? ? ? ? time: 150 ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ], ? ? ? ? ? ? ? ? video: [ ? ? ? ? ? ? ? ? ? ? ['http://img.ksbbs.com/asset/Mon_1703/05cacb4e02f9d9e.mp4', 'video/mp4', '中文標(biāo)清', 0], ? ? ? ? ? ? ? ? ? ? ['http://img.ksbbs.com/asset/Mon_1703/d0897b4e9ddd9a5.mp4', 'video/mp4', '中文高清', 0], ? ? ? ? ? ? ? ? ? ? ['http://img.ksbbs.com/asset/Mon_1703/eb048d7839442d0.mp4', 'video/mp4', '英文高清', 10], ? ? ? ? ? ? ? ? ? ? ['http://img.ksbbs.com/asset/Mon_1703/d30e02a5626c066.mp4', 'video/mp4', '英文超清', 0] ? ? ? ? ? ? ? ? ] ? ? ? ? ? ? }; ? ? ? // 定義一個(gè)對(duì)象 ? ? ? var player = new ckplayer(videoObject); ? } } </script>
<style scoped> ? #video { ? ? width: 600px; ? ? height: 400px; ? ? margin: 0px auto; ? } </style>
總結(jié):經(jīng)檢驗(yàn),以上兩種方法加載均需要flash的支持,然而目前大眾瀏覽器均已放棄flash,所以建議使用下方hls視頻流播放;
三、vue加載hls視頻流
1.index.html中
添加:
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
2.video-player.vue文件
<template> ? <div class="hls"> ? ? <video id="video" muted></video> ? </div> </template>
<script> export default { ? name: 'hls-video', ? components: { ? }, ? data() { ? ? return{ ? ? ? ? video:null, ? ? ? ? hls:null ? ? } ? }, ? props: { ? ? selectStdInfo:{ ? ? ? type:Object, ? ? ? required:true ? ? } ? }, ? watch:{ ? ? // 視頻彈窗時(shí)如果彈窗已存在,重新加載視頻流 ? ? "selectStdInfo.mourl":function(oldV,newV){ ? ? ? if(newV!=oldV){ ? ? ? ? this.initVideo() ? ? ? } ? ? } ? }, ? mounted() { ? ? this.initVideo() ? }, ? destroyed(){ ? ? this.reset() ? }, ? methods: { ? ?? ? ?//組件銷毀時(shí),調(diào)用該方法,停止請(qǐng)求;detachMedia和stopLoad為hls官網(wǎng)方法 ? ? ? reset(){ ? ? ? ? ? this.hls.detachMedia(this.video) ? ? ? ? ? this.hls.stopLoad() ?? ? ? ? }, ? ? ? //初始化video ? ? ? ? initVideo () { ? ? ?? ? ? ? ? ? this.video = document.getElementById('video') ? ? ? ? ? // 瀏覽器是否支持hls? ? ? ? ? ? if(Hls.isSupported()) { ? ? ? ? ? ? ?//如果hls已存在,先清空 ? ? ? ? ? ? ?if(this.hls){ ?? ? ? ? ? ? ? ?this.reset() ?? ? ? ? ? ? ?}else{ ?? ? ? ? ? ? ? ?this.hls = new Hls() ?? ? ? ? ? ? ?} ?? ? ? ? ? ? ?//this.selectStdInfo.mourl為父組件傳給該子組件的視頻url ?? ? ? ? ? ? ?this.hls.loadSource(this.selectStdInfo.mourl) ?? ? ? ? ? ? ?this.hls.attachMedia(this.video) ?? ? ? ? ? ? ?this.hls.on(Hls.Events.MANIFEST_PARSED,()=>{ ?? ? ? ? ? ? ? ?this.video.play() ?? ? ? ? ? ? ?}); ?? ? ? ? ?}else if (video.canPlayType('http://kbs-dokdo.gscdn.com/dokdo_300/_definst_/dokdo_300.stream/playlist.m3u8')) { ? ? ? ? ?? ?// 不支持hls ,支持蘋果原生? ? ? ? ? ? ?? ?this.video.src = '' ? ? ? ? ? ??? ?this.video.addEventListener('loadedmetadata',function() { ? ? ? ? ? ? ? ? this.video.play() ? ? ? ? ? ?}) ? ? ? ? ?} ? ? ? } ? }, }
</script> <style scoped lang="scss"> .hls{ ?? ?width:100%; ?? ?height:100%; ?? ?display:flex; ?? ?align-items: center; ?? ?justify-content: center; ?? ?#video{ ? ? width:100%; ?? ??? ?margin:0 auto; ?? ?} } </style>
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Vue實(shí)現(xiàn)購(gòu)物車詳情頁(yè)面的方法
這篇文章主要介紹了Vue實(shí)戰(zhàn)之購(gòu)物車詳情頁(yè)面的實(shí)現(xiàn),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-08-08一文搞懂Vue3中的異步組件defineAsyncComponentAPI的用法
這篇文章主要介紹了一文搞懂Vue3中的異步組件,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07vue-socket.io接收不到數(shù)據(jù)問題的解決方法
這篇文章主要介紹了解決vue-socket.io接收不到數(shù)據(jù)問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05vue3 Teleport瞬間移動(dòng)函數(shù)使用方法詳解
這篇文章主要為大家詳細(xì)介紹了vue3 Teleport瞬間移動(dòng)函數(shù)使用方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03關(guān)于vue狀態(tài)過渡transition不起作用的原因解決
這篇文章主要介紹了關(guān)于vue狀態(tài)過渡transition不起作用的原因解決,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-04-04關(guān)于Vue Webpack2單元測(cè)試示例詳解
這篇文章主要給大家介紹了關(guān)于Vue Webpack2單元測(cè)試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08