uniapp實現H5、APP、微信小程序播放.m3u8監控視頻

? ? ? ?

目錄

1.APP播放.m3u8監控視頻

2.H5播放.m3u8監控視頻

3.微信小程序播放.m3u8監控視頻


? ? ? ?最近在寫一個uniapp實現h5、app、微信小程序兼容三端的播放監控視頻功能,我原本以為一套代碼多處運行,但事實并非如此,h5可以運行,微信小程序不一定可以運行,APP也是如此。上網查閱很多資料,最終3端效果實現成功。

1.APP播放.m3u8監控視頻

APP對原生支持比較好,可以直接使用uniapp官網的video組件,本人親自試過正常播放。

video地址:uni-app官網

代碼實現如下:

    <!-- APP 端 --><video id="myVideo":src="videoUrl"controlsautoplayenable-play-gestureobject-fit="contain"class="video-player"@error="videoError"></video>

代碼還是比較簡單的,將videoUrl替換成自己的.m3u8格式Url即可。

2.H5播放.m3u8監控視頻

? ? ? ?這里一開始我也以為直接使用上面的代碼就可以,但是uniapp運行起來發現根本播放不出來,雖然 HTML5 視頻播放器支持多種視頻格式,但并不是所有的瀏覽器都支持 .m3u8 格式的視頻流。確保您使用的瀏覽器支持 HLS。我上網查閱資料最終效果實現成功!

實現代碼:

<template>		
<div id="app1"><div class="video-js" ref="videos"></div>
</div>
</template><script>
export default {data() {return {videoUrl: '',// H5 相關狀態player: null,visibilityChange: null,hidden: null,}}, mounted() {// 動態加載video.js CDN資源this.loadScript('https://vjs.zencdn.net/7.21.2/video.min.js', () => {this.loadStyle('https://vjs.zencdn.net/7.21.2/video-js.min.css');// 設置頁面可見性API的兼容性處理this.setupVisibilityAPI();// 等待資源加載完成setTimeout(() => {this.setupVideoPlayer();}, 300);});},beforeDestroy() {// 組件銷毀時移除事件監聽document.removeEventListener(this.visibilityChange, this.handleVisibilityChange);// 銷毀播放器if (this.player) {this.player.dispose();this.player = null;}},methods: {loadScript(src, callback) {const script = document.createElement('script');script.src = src;script.onload = callback;document.body.appendChild(script);},loadStyle(href) {const link = document.createElement('link');link.href = href;link.rel = 'stylesheet';document.head.appendChild(link);},setupVisibilityAPI() {// 設置頁面可見性API的兼容性處理if (typeof document.hidden !== "undefined") {this.hidden = "hidden";this.visibilityChange = "visibilitychange";} else if (typeof document.msHidden !== "undefined") {this.hidden = "msHidden";this.visibilityChange = "msvisibilitychange";} else if (typeof document.webkitHidden !== "undefined") {this.hidden = "webkitHidden";this.visibilityChange = "webkitvisibilitychange";}// 添加事件監聽document.addEventListener(this.visibilityChange, this.handleVisibilityChange.bind(this), false);},handleVisibilityChange() {if (!this.player) return;if (document[this.hidden]) {// 頁面不可見時暫停播放this.player.pause();} else {// 頁面重新可見時恢復播放this.player.play().catch(e => {console.log('自動播放失敗:', e);});}},setupVideoPlayer() {if (!window.videojs) {console.error('video.js未加載成功');return;}let video = document.createElement('video');video.id = 'video';video.className = 'video-js vjs-default-skin';video.preload = "auto";video.setAttribute('playsinline', true);video.setAttribute('webkit-playsinline', true);video.setAttribute('x5-video-player-type', 'h5');let source = document.createElement('source');source.src = this.videoUrl;video.appendChild(source);this.$refs.videos.appendChild(video);this.player = window.videojs('video', {autoDisable: true,preload: 'none',language: 'zh-CN',fluid: true,muted: false,aspectRatio: '16:9',controls: true,autoplay: false,loop: true,controlBar: {volumePanel: {inline: true},timeDivider: true,durationDisplay: true,progressControl: true,remainingTimeDisplay: true,fullscreenToggle: true,pictureInPictureToggle: false,}}, function() {this.on('error', function(err) {console.log("請求數據時遇到錯誤", err);});this.on('stalled', function(stalled) {console.log("網速失速", stalled);});});}}
}
</script>
<style>
#app1 {width: 100vw;height: 95vh;background: #000;display: flex;justify-content: center;align-items: center;}/* 視頻播放器主體 */.video-js {width: 90%;max-width: 1200px;height: auto;aspect-ratio: 16/9;border-radius: 8px;overflow: hidden;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);margin-top: -200px;}/* 控制欄整體樣式 */.video-js .vjs-control-bar {background: rgba(20, 20, 20, 0.8);height: 3.5em;padding: 0 10px;}/* 按鈕樣式 */.video-js .vjs-control {width: 2.5em;height: 2.5em;margin: 0 2px;color: #fff;transition: all 0.3s;}.video-js .vjs-control:hover {color: #00a1d6;transform: scale(1.1);}/* 進度條樣式 */.video-js .vjs-progress-control {position: absolute;top: -1em;width: 100%;height: 0.5em;}.video-js .vjs-progress-holder {height: 100%;background: rgba(255, 255, 255, 0.2);}.video-js .vjs-play-progress {background: #00a1d6;}/* 音量控制 */.video-js .vjs-volume-panel {order: 4;}/* 時間顯示 */.video-js .vjs-time-control {min-width: 3em;padding: 0 5px;font-size: 1.1em;}/* 全屏按鈕 */.video-js .vjs-fullscreen-control {order: 5;}/* 加載動畫 */.video-js .vjs-loading-spinner {border-color: rgba(0, 161, 214, 0.7);}/* 大播放按鈕 */.video-js .vjs-big-play-button {width: 2.5em;height: 2.5em;line-height: 2.5em;border-radius: 50%;border: none;background: rgba(0, 161, 214, 0.8);top: 50%;left: 50%;transform: translate(-50%, -50%);transition: all 0.3s;}.video-js .vjs-big-play-button:hover {background: rgba(0, 161, 214, 1);transform: translate(-50%, -50%) scale(1.1);}/* 響應式調整 */@media (max-width: 768px) {.video-js {width: 100%;border-radius: 0;}.video-js .vjs-control-bar {height: 2.5em;}}</style>

本人親自實踐,電腦瀏覽器,與手機瀏覽器訪問,都可以成功。

3.微信小程序播放.m3u8監控視頻

? ? ?在這里我是卡的最久的,因為直接使用video組件播放,在微信開發者工具中可以正常播放,但是在真機調試,小程序查看就是一直黑屏轉圈圈,有時候可以播放成功,但是幾秒中過后就是又是一直轉圈圈,最后就會報錯。有大佬會的可以在下方留言,最后采用web-view組件,實現播放,直接頁面跳轉。但是使用web-view跳轉監控視頻,又會有另一個問題,本地測試正常,但是上線,線上微信小程序就會出現提示不支持打開該頁面。一定得在微信開發者后臺校驗文件才可以打開,因為這是微信小程序的強制規則,這個校驗文件必須放在對應服務器才可以成功,假如我是調整螢石云的監控,那按照微信的說法,就要將校驗文件放入螢石云服務器的后臺,這樣顯然不現實,所以這里有兩種方案,第一使用代理,第二自己在寫一個頁面部署到自己的服務器,通過web-view跳轉到自己寫的頁面中,將監控視頻url一并傳入頁面,即可完成播放。


實現代碼:

 <web-view :src="'https://你的域名/player.html?videoUrl='+encodeURIComponent(videoUrl)+
'&cameraTitle='+encodeURIComponent(cameraTitle)"></web-view>

注意,這里跳轉必須是https,在這里viderUrl是視頻監控的鏈接,cameraTitle是標題,比如你播放的是那個監控,可加可不加,我這邊是加上了。

跳轉playeer.html頁面代碼實現:
其實下面的代碼保存,videoUrl替換即可播放,我只不過寫了兩套,你們可以選擇一套使用。

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title id="pageTitle">監控播放器</title><style>body {margin: 0;padding: 270px 0px 0px 0px;font-family: Arial, sans-serif;background: #000;}}/* 容器樣式 */#app1 {background: #000;display: flex;justify-content: center;align-items: center;}/* 視頻播放器主體 */.video-js {width: 100%;max-width: 1200px;height: auto;aspect-ratio: 16/9;border-radius: 8px;overflow: hidden;box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);}</style>
</head>
<body><div id="app1"><div class="video-js" id="videos"></div></div><script>function getQueryParam(name) {const query = window.location.search.substring(1);const vars = query.split('&');for (let i = 0; i < vars.length; i++) {const pair = vars[i].split('=');if (decodeURIComponent(pair[0]) === name) {return decodeURIComponent(pair[1]);}}return null;
}// 從URL參數獲取視頻地址
const videoUrl = getQueryParam('videoUrl');// 從URL獲取攝像頭標題并設置頁面標題const cameraTitle = getQueryParam('cameraTitle');if (cameraTitle) {document.title = cameraTitle;document.getElementById('pageTitle').textContent = cameraTitle;}document.addEventListener('DOMContentLoaded', function() {const app = {player: null,visibilityChange: null,hidden: null,init: function() {// 動態加載video.js CDN資源this.loadScript('https://vjs.zencdn.net/7.21.2/video.min.js', () => {this.loadStyle('https://vjs.zencdn.net/7.21.2/video-js.min.css');// 設置頁面可見性API的兼容性處理this.setupVisibilityAPI();// 等待資源加載完成setTimeout(() => {this.setupVideoPlayer();}, 300);});},loadScript: function(src, callback) {const script = document.createElement('script');script.src = src;script.onload = callback;document.body.appendChild(script);},loadStyle: function(href) {const link = document.createElement('link');link.href = href;link.rel = 'stylesheet';document.head.appendChild(link);},setupVisibilityAPI: function() {// 設置頁面可見性API的兼容性處理if (typeof document.hidden !== "undefined") {this.hidden = "hidden";this.visibilityChange = "visibilitychange";} else if (typeof document.msHidden !== "undefined") {this.hidden = "msHidden";this.visibilityChange = "msvisibilitychange";} else if (typeof document.webkitHidden !== "undefined") {this.hidden = "webkitHidden";this.visibilityChange = "webkitvisibilitychange";}// 添加事件監聽document.addEventListener(this.visibilityChange, this.handleVisibilityChange.bind(this), false);},handleVisibilityChange: function() {if (!this.player) return;if (document[this.hidden]) {// 頁面不可見時暫停播放this.player.pause();} else {// 頁面重新可見時恢復播放this.player.play().catch(e => {console.log('自動播放失敗:', e);});}},setupVideoPlayer: function() {if (!window.videojs) {console.error('video.js未加載成功');return;}let video = document.createElement('video');video.id = 'video';video.className = 'video-js vjs-default-skin';video.preload = "auto";video.setAttribute('playsinline', true);video.setAttribute('webkit-playsinline', true);video.setAttribute('x5-video-player-type', 'h5');let source = document.createElement('source');source.src = videoUrl ;video.appendChild(source);document.getElementById('videos').appendChild(video);this.player = window.videojs('video', {autoDisable: true,preload: 'none',language: 'zh-CN',fluid: true,muted: false,aspectRatio: '16:9',controls: true,autoplay: false,loop: true,controlBar: {volumePanel: {inline: true},timeDivider: true,durationDisplay: true,progressControl: true,remainingTimeDisplay: true,fullscreenToggle: true,pictureInPictureToggle: false,}}, function() {this.on('error', function(err) {console.log("請求數據時遇到錯誤", err);});this.on('stalled', function(stalled) {console.log("網速失速", stalled);});});}};// 初始化應用app.init();});</script>
</body>
</html>

本人親自測試,3端都可以播放,有問題可以在下方評論留言。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/81389.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/81389.shtml
英文地址,請注明出處:http://en.pswp.cn/web/81389.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

螢石云實際視頻實時接入(生產環境)

螢石云視頻接入 本示例可用于實際接入螢石云開放平臺視頻&#xff0c;同時支持音頻輸入和輸出。 實際優化內容 1.動態獲取token 2.切換各公司和車間時&#xff0c;自動重新初始化播放器 let EZUIKit null; // 第三方庫引用 let EZUIKitPlayers []; // 播放器實例數組 le…

【Dify平臺】使用Dify API 實現網頁內嵌式AI助手

使用 Dify API 實現網頁內嵌式 AI 助手 一. 引言二. Dify API 概述三. 實現網頁內嵌式 AI 助手的技術架構四. 前端實現五. 后端實現六. 功能擴展與優化七. 測試與部署一. 引言 隨著 AI 技術的不斷發展,越來越多的企業希望將智能助手集成到自己的網頁中,實現用戶自動接待、問…

mysql8配置文件my.ini講解,原汁原味直接拷貝再講解

文章目錄 一、原英文版本&#xff0c;不帶注釋二、由原版逐字翻譯成的中文版&#xff08;行行對應&#xff09;三、最常用的配置 一、原英文版本&#xff0c;不帶注釋 # Other default tuning values # MySQL Server Instance Configuration File # -------------------------…

Go語言中內存釋放 ≠ 資源釋放

// QueryUserFileMetas : 批量獲取用戶文件信息 func QueryUserFileMetas(username string, limit int) ([]UserFile, error) {stmt, err : mydb.DBConn().Prepare("select file_sha1,file_name,file_size,upload_at," "last_update from tbl_user_file where u…

win11+vs2022 安裝opencv 4.11.0圖解教程

1. 下載opencv opencv官網下載地址&#xff1a;Releases - OpenCV 2. 雙擊運行該exe&#xff0c;即可進行安裝&#xff0c;安裝文件夾可自行選擇 安裝后目錄如下&#xff1a; 3. 配置環境變量 使用win鍵搜索環境變量&#xff0c;選中系統變量中的Path&#xff0c;然后點擊編輯…

【Linux】進程 信號的產生

&#x1f33b;個人主頁&#xff1a;路飛雪吖~ &#x1f320;專欄&#xff1a;Linux 目錄 一、掌握Linux信號的基本概念 &#x1f320;前臺進程 VS 后臺進程 &#x1f320; 小貼士&#xff1a; &#x1fa84;?個系統函數 --- signal() &#x1fa84;查看信號 --- man 7 sign…

Python 網絡編程入門

目錄 一、前言 二、網絡通信基礎12&#xff1a;TCP 與 UDP 協議解析 2.1 TCP 協議&#xff1a;可靠的面向連接通信 2.2 UDP 協7議&#xff1a;無連接的快速通信 2.3 Sock12et&#xff1a;網絡通信的基石 三、TCP 編程實15戰&#xff1a;從單工通信到雙向聊天 3.1 TCP 客…

Django壓縮包形式下載文件

通過web將minio上的文件以壓縮包-文件夾-文件的形式下載到本地 import os from bx_mes import settings from io import BytesIO import zipfile from django.http import StreamingHttpResponse class FileRemote(GenericAPIView):def post(self,request):# 壓縮包名folder_n…

Enhancing Relation Extractionvia Supervised Rationale Verifcation and Feedback

Enhancing Relation Extraction via Supervised Rationale Verification and Feedback| Proceedings of the AAAI Conference on Artificial Intelligencehttps://ojs.aaai.org/index.php/AAAI/article/view/34631 1. 概述 關系抽取(RE)任務旨在抽取文本中實體之間的語義關

【RAG】ragflow源碼亮點:文檔embedding向量化加權融合

引言&#xff1a; 最近在看ragflow源碼&#xff0c;其中有一個較為巧妙地設計&#xff1a;分別將 文字 、 標題 行向量化 之后&#xff0c;直接根據權重&#xff0c;進行加法運算&#xff0c;得到向量融合&#xff0c;增強了文本向量化的表示能力&#xff0c;這里開始討論一下…

限流系列:sentinel

目錄 滑動窗口算法 Sentinel 數據模型 示例 大致流程 ???????entry ???????entryWithPriority ???????FlowSlot.entry ???????checkFlow ???????canPass ???????avgUsedTokens ???????passQps ???????pa…

Java 訪問者模式深度重構:從靜態類型到動態行為的響應式設計實踐

一、訪問者模式的本質與核心價值 在軟件開發的漫長演進中&#xff0c;設計模式始終是架構師手中的利刃。當我們面對復雜對象結構上的多種操作需求時&#xff0c;訪問者模式&#xff08;Visitor Pattern&#xff09;猶如一把精密的手術刀&#xff0c;能夠優雅地分離數據結構與作…

UE 5 C++設置物體位置和旋轉,初始化虛幻引擎樣條線、加載引用虛幻編輯器中的藍圖、設置虛幻編輯器中Actor大小

一、設置物體位置和旋轉 UE.cpp文件中代碼&#xff1a; Mesh->SetWorldLocationAndRotation(FVector(50.0f, 50.0f, 50.0f),FRotator(0,-90,0)); vs代碼編輯器中旋轉信息順序&#xff08;yzx&#xff09;&#xff1a; Pitch、 Yaw、 Roll UE編輯器中旋轉信息順序&#xf…

【文本分類】KG-HTC 知識圖譜提升分類準確率

最近看到一篇論文“KG-HTC: Integrating Knowledge Graphs into LLMs for Effective Zero-shot Hierarchical Text Classification”&#xff0c;介紹了文本分類的技巧&#xff0c;這篇文航主要利用了知識圖譜大模型的思路&#xff0c;實驗效果不錯&#xff0c;里面的一些論述也…

三大微調技術對比:Prompt/Prefix/P-Tuning

Prompt Tuning、Prefix Tuning和P - Tuning的區別 概念方面: Prompt Tuning:在輸入序列前添加可訓練的額外Token以適配下游任務,預訓練語言模型參數不變。比如在文本分類中,在句子前加特定Token如“(OPINION)”,讓模型理解是對觀點進行分類的任務。Prefix Tuning:在每層T…

14.「實用」扣子(coze)教程 | Excel文檔自動批量AI文檔生成實戰,中級開篇

隨著AI編程工具及其能力的不斷發展&#xff0c;編程將變得越來越簡單。 在這個大趨勢下&#xff0c;大師兄判斷未來的編程將真正成為像office工具一樣的辦公必備技能。每個人通過 &#xff08;專業知識/資源編程&#xff09;將自己變成一個復合型的人才&#xff0c;大大提高生…

量子-經典協同計算新路徑:NISQ 時代混合算法對后量子密碼學的適應性探索

內容來源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨浪味仙 排版丨浪味仙 行業動向&#xff1a;3700字丨10分鐘閱讀 5 月 20 日&#xff0c;由北京量子院、清華大學、數學工程與先進計算國家重點實驗室、南洋理工大學、量子信息前沿科學中心…

CentOS中安裝Docker Compose

在CentOS中安裝Docker Compose的步驟如下&#xff1a; 步驟 1&#xff1a;確保Docker已安裝 Docker Compose依賴Docker環境&#xff0c;請先安裝Docker&#xff1a; # 添加Docker官方倉庫 sudo yum install -y yum-utils sudo yum-config-manager --add-repo https://downlo…

電商小程序店鋪詳情頁:頭部無限分類與篩選功能實現

電商小程序店鋪詳情頁:頭部無限分類與篩選功能實現 一、場景需求與技術選型二、頭部無限分類導航三、篩選功能實現:Picker多列選擇組件一、場景需求與技術選型 在電商小程序生態中,店鋪詳情頁作為用戶瀏覽商品的核心流量入口,其交互效率與功能完整性直接影響商品轉化率。傳…

Graph Neural Network(GNN)

我們首先要了解什么是圖,圖是由節點和邊組成的,邊的不一樣也導致節點的不同(參考化學有機分子中的碳原子) gnn可以處理classification的問題,也就是分類的問題 也可以處理generation的問題 借一部日劇來說明,這個日劇是講主角尋找殺害他父親的兇手的,劇中的人物有姓名和特征 …