Commit b4df1e56602fb220e07c5c90154507596ed7e7b5

Authored by xp.Huang
2 parents d64bfc62 5389b659

Merge branch 'ww' into 'main'

feat: implement play streaming video

See merge request huang/thingskit-app!71
Showing 1 changed file with 183 additions and 153 deletions
1 -<template>  
2 - <view class="camera-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view class="org-sty">  
6 - <view @click="openOrg" class="org-item">  
7 - <view class="u-flex org-contact"><text class="text">组织关系</text></view>  
8 - <view @click="openOrg" class="u-flex org-device">  
9 - <image class="device-image" src="../../../static/org.png"></image>  
10 - <text class="device-text">摄像头数:{{ cameraTotal }}</text>  
11 - </view>  
12 - </view>  
13 - <view @click="openOrg" class="org-item"><image class="image" src="../../../static/arrow-right.png"></image></view>  
14 - </view>  
15 - <view style="height: 150rpx;"></view>  
16 - <!-- 自带分页组件 -->  
17 - <mescroll-body ref="mescrollRef" :up="upOption" @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback">  
18 - <view class="camera-container">  
19 - <view class="container-item">  
20 - <view v-for="(item, index) in list" :key="index" class="item">  
21 - <video  
22 - :data-id="item.id"  
23 - :key="item.id"  
24 - :id="'video' + item.id"  
25 - class="video"  
26 - :src="item.videoUrl"  
27 - controls  
28 - :title="item.name"  
29 - x5-video-player-type="h5"  
30 - x5-video-orientation="portraint"  
31 - show-mute-btn  
32 - :poster="item.avatar"  
33 - @play="playVideo"  
34 - ></video>  
35 - <view class="bottom-text">  
36 - <text class="text">{{ item.name }}</text>  
37 - </view>  
38 - </view>  
39 - </view>  
40 - </view>  
41 - </mescroll-body>  
42 - <!-- 自带分页组件 -->  
43 - <view style="height: 60rpx;"></view>  
44 - </view>  
45 -</template>  
46 -  
47 -<script>  
48 -import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';  
49 -  
50 -export default {  
51 - mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)  
52 - data() {  
53 - return {  
54 - page: {  
55 - num: 0,  
56 - size: 10  
57 - },  
58 - downOption: {  
59 - auto: true //是否在初始化后,自动执行downCallback; 默认true  
60 - },  
61 - upOption: {  
62 - auto: false // 不自动加载  
63 - },  
64 - current: 0,  
65 - cameraTotal: 0,  
66 - list: [],  
67 - ordId: ''  
68 - };  
69 - },  
70 - onShow() {  
71 - if (this.ordId == '') {  
72 - } else {  
73 - this.loadData(1, this.ordId);  
74 - }  
75 - },  
76 - onHide() {  
77 - this.ordId = '';  
78 - this.loadData(1, null);  
79 - },  
80 - onLoad() {  
81 - // 隐藏原生的tabbar  
82 - uni.hideTabBar();  
83 - },  
84 - methods: {  
85 - /*下拉刷新的回调 */  
86 - downCallback() {  
87 - //联网加载数据  
88 - this.page.num = 1;  
89 - this.loadData(1);  
90 - },  
91 - /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */  
92 - upCallback() {  
93 - //联网加载数据  
94 - this.page.num += 1;  
95 - this.loadData(this.page.num);  
96 - },  
97 - loadData(pageNo, organizationV) {  
98 - let httpData = {  
99 - page: pageNo,  
100 - pageSize: 10,  
101 - organizationId: organizationV  
102 - };  
103 - uni.$u.http  
104 - .get('/yt/video', { params: httpData, custom: { load: false } })  
105 - .then(res => {  
106 - uni.stopPullDownRefresh();  
107 - this.mescroll.endByPage(res.items.length, res.total);  
108 - this.cameraTotal = res.total;  
109 - if (pageNo == 1) {  
110 - this.list = res.items;  
111 - } else {  
112 - this.list = this.list.concat(res.items);  
113 - }  
114 - })  
115 - .catch(e => {  
116 - //联网失败, 结束加载  
117 - this.mescroll.endErr();  
118 - });  
119 - },  
120 - hideImageUrl(item, index) {  
121 - this.current = index;  
122 - },  
123 - playVideo(e) {  
124 - /**  
125 - * 点击全屏播放当前视频,暂停其余视频  
126 - * 兼容APP和MP端  
127 - */  
128 - let currentId = 'video' + e.currentTarget.dataset.id;  
129 - this.videoContent = uni.createVideoContext(currentId, this);  
130 - this.videoContent.requestFullScreen();  
131 - // 获取视频列表  
132 - let trailer = this.list;  
133 - trailer.forEach((item, index) => {  
134 - if (item.videoUrl != null && item.videoUrl != '') {  
135 - let temp = 'video' + item.id;  
136 - if (temp != currentId) {  
137 - //暂停不是当前的视频  
138 - uni.createVideoContext(temp, this).pause();  
139 - }  
140 - }  
141 - });  
142 - },  
143 - openOrg() {  
144 - uni.navigateTo({  
145 - url: './org/org'  
146 - });  
147 - }  
148 - }  
149 -};  
150 -</script>  
151 -  
152 -<style lang="scss" scoped>  
153 -@import '../static/camera.scss'; 1 +<template>
  2 + <view class="camera-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <view class="org-sty">
  6 + <view @click="openOrg" class="org-item">
  7 + <view class="u-flex org-contact"><text class="text">组织关系</text></view>
  8 + <view @click="openOrg" class="u-flex org-device">
  9 + <image class="device-image" src="../../../static/org.png"></image>
  10 + <text class="device-text">摄像头数:{{ cameraTotal }}</text>
  11 + </view>
  12 + </view>
  13 + <view @click="openOrg" class="org-item">
  14 + <image class="image" src="../../../static/arrow-right.png"></image>
  15 + </view>
  16 + </view>
  17 + <view style="height: 150rpx;"></view>
  18 + <!-- 自带分页组件 -->
  19 + <mescroll-body ref="mescrollRef" :up="upOption" @init="mescrollInit" :down="downOption" @down="downCallback"
  20 + @up="upCallback">
  21 + <view class="camera-container">
  22 + <view class="container-item">
  23 + <view v-for="(item, index) in list" :key="item.id" class="item">
  24 + <video :data-id="item.id" :data-accessMode="item.accessMode" :key="item.id" preload="none"
  25 + :id="'video' + item.id" class="video" :src="item.videoUrl || commonVideoUrl" controls
  26 + :title="item.name" x5-video-player-type="h5" x5-video-orientation="portraint" show-mute-btn
  27 + :poster="item.avatar" @play="playVideo"></video>
  28 + <view class="bottom-text">
  29 + <text class="text">{{ item.name }}</text>
  30 + </view>
  31 + </view>
  32 + </view>
  33 + </view>
  34 + </mescroll-body>
  35 + <!-- 自带分页组件 -->
  36 + <view style="height: 60rpx;"></view>
  37 + </view>
  38 +</template>
  39 +
  40 +<script>
  41 + import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
  42 +
  43 + export default {
  44 + mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
  45 + data() {
  46 + return {
  47 + page: {
  48 + num: 0,
  49 + size: 10
  50 + },
  51 + downOption: {
  52 + auto: true //是否在初始化后,自动执行downCallback; 默认true
  53 + },
  54 + upOption: {
  55 + auto: false // 不自动加载
  56 + },
  57 + current: 0,
  58 + cameraTotal: 0,
  59 + list: [],
  60 + ordId: '',
  61 + commonVideoUrl: 'http://playertest.longtailvideo.com/adaptive/bipbop/gear4/prog_index.m3u8'
  62 + };
  63 + },
  64 + onShow() {
  65 + if (this.ordId == '') {} else {
  66 + this.loadData(1, this.ordId);
  67 + }
  68 + },
  69 + onHide() {
  70 + this.ordId = '';
  71 + this.loadData(1, null);
  72 + },
  73 + onLoad() {
  74 + // 隐藏原生的tabbar
  75 + uni.hideTabBar();
  76 + },
  77 + methods: {
  78 + /*下拉刷新的回调 */
  79 + downCallback() {
  80 + //联网加载数据
  81 + this.page.num = 1;
  82 + this.loadData(1);
  83 + },
  84 + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  85 + upCallback() {
  86 + //联网加载数据
  87 + this.page.num += 1;
  88 + this.loadData(this.page.num);
  89 + },
  90 + loadData(pageNo, organizationV) {
  91 + let httpData = {
  92 + page: pageNo,
  93 + pageSize: 10,
  94 + organizationId: organizationV
  95 + };
  96 + uni.$u.http
  97 + .get('/yt/video', {
  98 + params: httpData,
  99 + custom: {
  100 + load: false
  101 + }
  102 + })
  103 + .then(res => {
  104 + uni.stopPullDownRefresh();
  105 + this.mescroll.endByPage(res.items.length, res.total);
  106 + this.cameraTotal = res.total;
  107 + if (pageNo == 1) {
  108 + this.list = res.items;
  109 + } else {
  110 + this.list = this.list.concat(res.items);
  111 + }
  112 + })
  113 + .catch(e => {
  114 + //联网失败, 结束加载
  115 + this.mescroll.endErr();
  116 + });
  117 + },
  118 + hideImageUrl(item, index) {
  119 + this.current = index;
  120 + },
  121 + playVideo(e) {
  122 + const {
  123 + currentTarget: {
  124 + dataset: {
  125 + accessmode,
  126 + id
  127 + }
  128 + } = {}
  129 + } = e
  130 + const isExistVideoUrl = this.list.find(item => item.id == id).videoUrl
  131 + if (accessmode === 1 && !isExistVideoUrl) {
  132 + uni.$u.http.get(`/yt/video/url/${id}`)
  133 + .then(res => {
  134 + const {
  135 + data: {
  136 + url
  137 + } = {}
  138 + } = res
  139 + const index = this.list.findIndex(item => item.id === id)
  140 + if (~index && url) {
  141 + this.list.splice(index, 1, {
  142 + ...this.list[index],
  143 + videoUrl: url
  144 + })
  145 + this.$nextTick(() => {
  146 + let currentId = 'video' + id;
  147 + const videoContext = uni.createVideoContext(currentId, this);
  148 + videoContext.play()
  149 + })
  150 + }
  151 + })
  152 + }
  153 +
  154 + /**
  155 + * 点击全屏播放当前视频,暂停其余视频
  156 + * 兼容APP和MP端
  157 + */
  158 + let currentId = 'video' + id;
  159 + this.videoContent = uni.createVideoContext(currentId, this);
  160 + this.videoContent.requestFullScreen();
  161 + // 获取视频列表
  162 + let trailer = this.list;
  163 + trailer.forEach((item, index) => {
  164 + if (item.videoUrl != null && item.videoUrl != '') {
  165 + let temp = 'video' + item.id;
  166 + if (temp != currentId) {
  167 + //暂停不是当前的视频
  168 + uni.createVideoContext(temp, this).pause();
  169 + }
  170 + }
  171 + });
  172 + },
  173 + openOrg() {
  174 + uni.navigateTo({
  175 + url: './org/org'
  176 + });
  177 + }
  178 + }
  179 + };
  180 +</script>
  181 +
  182 +<style lang="scss" scoped>
  183 + @import '../static/camera.scss';
154 </style> 184 </style>