uniapp video网页端可以播放视频,手机端却无法播放

uniapp video网页端可以播放视频,手机端却无法播放

介绍:本文主要介绍uniapp中video标签在手机端无法播放视频的问题并且如何解决。

1.问题场景

  1. 通过后端接口获取到视频mp4 的地址,然后使用video标签放入src中直接渲染,uniapp在web浏览器打开可以正常播放视频,在app真机调试却无法播放。
  2. 后端的接口是一个文件下载 接口,直接在web浏览器上访问视频的地址,浏览器上能够正常播放
  3. 后端在本地服务器的时候,通过video标签访问视频地址,web浏览器打开可以正常播放视频,在app真机调试也可以播放视频。
  4. 后端在部署上线 后,通过video标签访问视频地址,uniapp web浏览器打开可以正常播放视频,在app真机调试却不可以播放视频。
  5. 后端在部署上线 后,直接 在web浏览器上访问视频的地址,可以正常播放。在微信 打开地址也可以正常播放,但是在手机浏览器上却无法播放。
  6. 疑惑:是不是后端部署上线 后,通过http传输 的过程中,发生了未知的问题,导致在手机浏览器uniapp上也无法正常访问视频

2.解决方案1

后端直接把mp4的文件格式,转换成flv视频格式,再返回给前端,前端可以正常访问。

这样会有问题:

  1. flv格式在web浏览器上是无法播放的。(因为flv格式已经被浏览器抛弃了)
  2. flv格式在手机浏览器和通过uniapp的video标签都可以正常播放。

3.解决方案2

通过webview在uniapp上嵌套一个H5页面,通过H5页面来进行访问。H5页面是通过浏览器来读取视频文件的,只要在web浏览器上可以播放这个视频,那么我们通过webview就一定可以播放视频。因为浏览器的内核比较强大。 下面来介绍如何使用webview,以及可能遇到的坑。

1.下载webview.js包

webview包地址: hybrid/html/uni.webview.1.5.5.js · alpha · DCloud / hello uni-app x · GitCode

如果没有以上网站过期了,就去uniapp官网找: web-view | uni-app官网 (dcloud.io)

下载这个webview包的时候,建议直接复制代码 ,自己再创建一个js文件,把代码复制进去。要把包放入static里面。 否则有可能出现以下情况:

  1. 明明下载出来的是js,怎么文件一打开全是html内容?
  2. 直接引用的时候就一直报错。
  3. 建议采用我上面的方案
  • 正确的情况

2.使用webview

vue页面

js 复制代码
<web-view 
    v-if='showWebView'
    class="web-view" 
    :webview-styles="webviewStyles"  
    :src="`/static/html/index.html?url=${webViewURL}`"
></web-view>

export default { 
    data() { 
        return { 
        showWebView: false, 
        webViewURL:'',
        webviewStyles: {
            width: '100%',
            height: '100%',	
        },
      } 
    },
    mounted() {
        this.getUrl()
    },
    methods: { 
            getUrl() { 
                //url是从后端获取到视频的地址 
                let url = 'xxx.com' 
                this.webViewURL = url 
                this.showWebView = true 
            } 
      } 
}

html页面

  1. webview.js文件要放在body里面
  2. UniAppJSBridgeReady加载完成触发的函数
  3. getEnv只是获取当前设备环境的函数,可以不使用
html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
        <script type="text/javascript" src="js/uni.webview.1.5.5.js"></script>

        <video id="video" controls src=""></video>

        <script type="text/javascript">
          document.addEventListener("UniAppJSBridgeReady", function () {
            uni.getEnv(function (res) {
                let href = window.location.href
                let url = href.split('url=')[1]
                let video = document.getElementById('video')
                video.setAttribute('src', url)
            });
          });
        </script>
  </body>
</html>

3.webview通信

  1. 上面的案例是webview最简单的使用方法
  2. 以下介绍如何进行vue页面和html页面的通信,做到在html页面有退出按钮,返回到vue页面。
  3. 在vue页面通过通信传入数据到html页面。(当然上面的案例是通过拼接地址来做到通信)

vue页面

  1. @message:网页向应用 postMessage 时,会在特定时机(后退、组件销毁、分享)触发并收到消息。
  2. @onPostMessage:网页向应用实时 postMessage
  3. 应用(vue页面)向html发信息evalJS(方法)
js 复制代码
<web-view 
    v-if='showWebView' 
    class="web-view" 
    :webview-styles="webviewStyles"
    src="/static/html/index.html"
    @message='handleWebviewMessage' 
    @onPostMessage='handleWebviewMessage'>
</web-view>
	
export default { 
    data() { 
        return { 
        showWebView: false, 
        webviewStyles: {
            width: '100%',
            height: '100%',	
        },
        stack: null,
      } 
    },
    mounted() {
        //后端视频地址
        let url = 'https:/xxx.com/file/uploads/717a743a-5516-4101-a55f-d1a542d25fe1' 
        this.showWebView = true  
        setTimeout(() => {  
        //在网页端这端代码会报错,加上下面的代码,作用:不在H5页面起作用
        //这里加定时器,是为了等待webview完全加载完成后再发信息。
        // #ifndef H5
        const pages = getCurrentPages()  
        this.stack = pages[pages.length - 1].$getAppWebview().children()[0]  
        // 发信息给html
        this.stack.evalJS(`receiveData('${url}')`)  
        // #endif
        }, 2000)
    },
   methods: {
       handleWebviewMessage(e) {
           // html返回来的数据
           console.log('数据', e);
           let show = e.detail.data[0]['show']
           this.showWebView = show
     },
   } 
}

html页面

  1. receiveData方法必须和vue页面evalJS()里面的名称对应
html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>

  <body>
        <script type="text/javascript" src="js/uni.webview.1.5.5.js"></script>

        <video id="video" controls src=""></video>
        <button id="btn">退出界面</button>

        <script type="text/javascript">
        	function receiveData(data) {
                let video = document.getElementById('video')
                video.setAttribute('src', data)
          }
        document.getElementById('btn').addEventListener('click', function() {  
            // 通知vue页面进行关闭窗口
            uni.postMessage({  
                data: {  
                    show: false,  
                }  
            })  
        })
        </script>
  </body>
</html>

可能踩坑: 下面这样都是无法传输的,都是会报错的,因为evalJS传入动态的参数只能采用我上面的例子

js 复制代码
    this.stack.evalJS(`receiveData(${url})`)  
    this.stack.evalJS("receiveData("+url+"))"
相关推荐
humors2217 分钟前
Deepseek工具:H5+Vue 项目转微信小程序报告生成工具
前端·vue.js·微信小程序·h5·工具·报告
方安乐7 分钟前
ESLint代码规范(二)
前端·javascript·代码规范
zzginfo13 分钟前
var、let、const、无申明 四种变量在赋值前,使用的情况
开发语言·前端·javascript
贺小涛17 分钟前
Vue介绍
前端·javascript·vue.js
cch891841 分钟前
React Hooks的支持
前端·javascript·react.js
鹏程十八少1 小时前
9. Android Shadow插件化如何解决资源冲突问题和实现tinker热修复资源(源码分析4)
android·前端·面试
蜡台1 小时前
vue.config.js 配置
前端·javascript·vue.js·webpack
qq_381338501 小时前
微前端架构下的状态管理与通信机制深度解析:从 qiankun 源码到性能优化实战
前端·状态模式
han_1 小时前
JavaScript设计模式(六):职责链模式实现与应用
前端·javascript·设计模式