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+"))"
相关推荐
醉の虾15 分钟前
Vue3 使用v-for 渲染列表数据后更新
前端·javascript·vue.js
张小小大智慧24 分钟前
TypeScript 的发展与基本语法
前端·javascript·typescript
hummhumm33 分钟前
第 22 章 - Go语言 测试与基准测试
java·大数据·开发语言·前端·python·golang·log4j
asleep7011 小时前
第8章利用CSS制作导航菜单
前端·css
hummhumm1 小时前
第 28 章 - Go语言 Web 开发入门
java·开发语言·前端·python·sql·golang·前端框架
幼儿园的小霸王1 小时前
通过socket设置版本更新提示
前端·vue.js·webpack·typescript·前端框架·anti-design-vue
疯狂的沙粒1 小时前
对 TypeScript 中高级类型的理解?应该在哪些方面可以更好的使用!
前端·javascript·typescript
gqkmiss2 小时前
Chrome 浏览器 131 版本开发者工具(DevTools)更新内容
前端·chrome·浏览器·chrome devtools
Summer不秃2 小时前
Flutter之使用mqtt进行连接和信息传输的使用案例
前端·flutter
旭日猎鹰2 小时前
Flutter踩坑记录(二)-- GestureDetector+Expanded点击无效果
前端·javascript·flutter