Quellcode durchsuchen

feat: 视频 / 兼容浏览器自动播放

@dayan_hjm vor 2 Jahren
Ursprung
Commit
ef9dffe2c6

+ 10 - 0
config/webpack.common.js

@@ -103,6 +103,16 @@ module.exports = {
103 103
           },
104 104
         }],
105 105
       },
106
+      { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)$/, 
107
+        // use: 'file-loader' ,
108
+        use: [{
109
+          loader: 'file-loader',
110
+          options: {
111
+            name: 'static/[name].[ext]',
112
+            publicPath: '../../'
113
+          },
114
+        }],
115
+      },
106 116
       // babel
107 117
       {
108 118
         test: /\.jsx?$/,

+ 35 - 4
src/assets/css/styleTemplate.less

@@ -2,7 +2,7 @@
2 2
  * @Author: dayan_hjm 茶百道主题样式
3 3
  * @Date: 2022-10-27 10:56:37 
4 4
  * @Last Modified by: dayan_hjm
5
- * @Last Modified time: 2023-10-24 17:36:38
5
+ * @Last Modified time: 2023-10-25 10:41:55
6 6
  */
7 7
 
8 8
 @import url("../../themes/themes.less");
@@ -11,7 +11,7 @@
11 11
 :global {
12 12
   #app {
13 13
     height: inherit;
14
-    font-family: 'DingTalkJinBuTi',"DingTalkSans";
14
+    font-family: 'DingTalkJinBuTi', "DingTalkSans";
15 15
   }
16 16
 
17 17
   .hidetip {
@@ -314,7 +314,33 @@
314 314
   .homePage .bottom_body {
315 315
     // background-image: linear-gradient(to top, #F8FCFE, #F8FCFE, #F8FCFE);
316 316
     background: linear-gradient(51.4deg, #000308 0%, #041b40 100%);
317
-    background: url(../imgs/dataVimg/homeBgDataV.png) no-repeat 0 0 / 100% 100% #041b40;
317
+    // background: url(../imgs/dataVimg/homeBgDataV.png) no-repeat 0 0 / 100% 100% #041b40;
318
+  }
319
+
320
+  .home_box {
321
+    position: relative;
322
+    left: 0;
323
+    top: 0;
324
+    width: 100%;
325
+    height: 100%;
326
+
327
+    .video_box {
328
+      position: absolute;
329
+      left: 0;
330
+      top: 0;
331
+      width: 100%;
332
+      background: url(../imgs/dataVimg/homeBgDataV.png) no-repeat 0 0 / 100% 100% #041b40;
333
+      height: 100%;
334
+      display: flex;
335
+      align-items: center;
336
+      justify-content: center;
337
+      video{
338
+        width: 89%;
339
+        height: 83%;
340
+        padding: 1% 0 0 10%;
341
+      }
342
+    }
343
+
318 344
   }
319 345
 
320 346
   .bottom_body {
@@ -327,6 +353,11 @@
327 353
       justify-content: space-between;
328 354
       background: unset;
329 355
       flex-wrap: wrap;
356
+      position: absolute;
357
+      left: 0;
358
+      top: 0;
359
+      width: 100%;
360
+      background: unset;
330 361
 
331 362
       .topMsg_title {
332 363
         background: url(../imgs/dataVimg/tipleBg.png) no-repeat 0 0 / 100% 100%;
@@ -356,7 +387,7 @@
356 387
           .topMsg_content {
357 388
             height: calc(100% - 2em);
358 389
             line-height: 4em;
359
-    font-size: 2em;
390
+            font-size: 2em;
360 391
             color: #69FFDE;
361 392
             background: url(../imgs/dataVimg/zongChanZhi.gif) no-repeat 0 bottom / 100% 70%;
362 393
 

BIN
src/assets/imgs/dataVImg/homeVideo.mp4


BIN
src/assets/imgs/dataVImg/homeVideo2.mp4


+ 112 - 0
src/assets/imgs/dataVImg/index.html

@@ -0,0 +1,112 @@
1
+<!DOCTYPE html>
2
+<html lang="en">
3
+ 
4
+<head>
5
+  <meta charset="UTF-8">
6
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
+  <title>Document</title>
8
+  <!-- 
9
+    Chrome 浏览器的视频自动播放策略
10
+    1.始终允许静音模式下自动播放
11
+    2.在以下的情况中,带声音播放会被允许:
12
+      ①用户已经与当前的域进行了交互(也就是click,tap事件)。
13
+      ②在桌面设备上,用户的媒体参与度指数阈值已经超过,这意味着用户之前播放过有声视频。
14
+      ③用户已经将网站添加到移动设备上的主屏幕或允在桌面上安装了PWA。
15
+    3.顶部帧可以将自动播放权限委派给其iframe,来允许自动播放声音
16
+    
17
+    媒体参与度(Media Engagement)是指用户与媒体内容进行互动的程度,可以通过多个指标来衡量。这些指标主要包括观看时间、观看率、转化率、交互行为等。
18
+    可以通过:chrome://media-engagement/ 查看
19
+   -->
20
+  <style>
21
+    * {
22
+      margin: 0;
23
+      padding: 0;
24
+    }
25
+ 
26
+    body {
27
+      display: flex;
28
+      justify-content: center;
29
+    }
30
+ 
31
+    video {
32
+      width: 800px;
33
+      height: 600px;
34
+    }
35
+ 
36
+    .box {
37
+      position: relative;
38
+    }
39
+ 
40
+    .box button {
41
+      width: 80px;
42
+      height: 40px;
43
+      position: absolute;
44
+      top: 50%;
45
+      left: 50%;
46
+      border: none;
47
+      background-color: rgb(61, 196, 230);
48
+      transform: translate(-50%);
49
+      color: #fff;
50
+      border-radius: 10px;
51
+      display: none;
52
+    }
53
+ 
54
+    .box button:hover {
55
+      cursor: pointer;
56
+    }
57
+  </style>
58
+ 
59
+</head>
60
+ 
61
+<body>
62
+  <div class="box">
63
+    <video src="./homeVideo.mp4" autoplay></video>
64
+    <div class="model">
65
+      <button>开始播放</button>
66
+    </div>
67
+  </div>
68
+</body>
69
+<script>
70
+  const video = document.querySelector('video')
71
+  console.log(video.play());
72
+ 
73
+  const model = document.querySelector('.model')
74
+  const btn = document.querySelector('button')
75
+  // 第一种方法 引导用户去与页面交互实现播放
76
+  async function play() {
77
+    try {
78
+      await video.play();
79
+      //使用await的原因是因为video.play()方法返回的是一个Promise,所以在这里我们可以对他进行一些处理
80
+      model.style.display = 'none';
81
+      btn.removeEventListener('click', play);
82
+      // 如果他自动播放了就隐藏按钮,消除点击事件
83
+    } catch (err) {
84
+      model.style.display = 'block';
85
+      btn.addEventListener('click', play);
86
+      // 如果Promise返回的是error就引导用户点击按钮,在调用play方法
87
+    }
88
+  }
89
+  play();
90
+ 
91
+  //第二种方法比较主流,类似的有网页版抖音以及B站
92
+  function play() {
93
+    video.muted = true;//设置视频为静音
94
+    video.play();//调用播放方法
95
+    const ctx = new AudioContext();
96
+    const canAutoPlay = ctx.state === 'running'; //通过这个可以判断出视频能不能够自动播放 如何可以它的值就是“running” 否则为"suspended"
97
+    // 如果是不能播放我们就执行下面的逻辑,其实就是类似于第一种方法,让用户与其交互
98
+    ctx.close();
99
+    if (canAutoPlay) {
100
+      video.muted = false;
101
+      model.style.display = 'none';
102
+      btn.removeEventListener('click', play);
103
+    }
104
+    else {
105
+      model.style.display = 'block';
106
+      btn.addEventListener('click', play);
107
+    }
108
+  }
109
+  play()
110
+</script>
111
+ 
112
+</html>

BIN
src/assets/imgs/dataVImg/toplineleft.png


BIN
src/assets/imgs/dataVImg/toplineright.png


+ 156 - 74
src/pages/tqcDataVHome/view.jsx

@@ -1,8 +1,14 @@
1 1
 /*
2 2
  * @Author: dayan_hjm 
3
+ * @Date: 2023-10-25 10:32:44 
4
+ * @Last Modified by: dayan_hjm
5
+ * @Last Modified time: 2023-10-25 10:45:33
6
+ */
7
+/*
8
+ * @Author: dayan_hjm 
3 9
  * @Date: 2022-10-27 11:40:02 
4 10
  * @Last Modified by: dayan_hjm
5
- * @Last Modified time: 2023-10-24 15:14:58
11
+ * @Last Modified time: 2023-10-25 10:32:07
6 12
  */
7 13
 
8 14
 import React, { useState, useEffect, Component } from "react";
@@ -62,12 +68,67 @@ class Home extends Component {
62 68
   componentDidMount() {
63 69
     setTimeout(() => {
64 70
       $(".shu1").numScroll();
71
+      this.videoStart();
65 72
     }, 200)
66 73
     setTimeout(() => {
67 74
       //替换gif
68 75
       this.setState({ changGif: true })
69 76
     }, 2000)
70 77
   }
78
+  videoStart() {
79
+    /*     Chrome 浏览器的视频自动播放策略
80
+        1.始终允许静音模式下自动播放
81
+        2.在以下的情况中,带声音播放会被允许:
82
+          ①用户已经与当前的域进行了交互(也就是click,tap事件)。
83
+          ②在桌面设备上,用户的媒体参与度指数阈值已经超过,这意味着用户之前播放过有声视频。
84
+          ③用户已经将网站添加到移动设备上的主屏幕或允在桌面上安装了PWA。
85
+        3.顶部帧可以将自动播放权限委派给其iframe,来允许自动播放声音
86
+        
87
+        媒体参与度(Media Engagement)是指用户与媒体内容进行互动的程度,可以通过多个指标来衡量。这些指标主要包括观看时间、观看率、转化率、交互行为等。
88
+        可以通过:chrome://media-engagement/ 查看
89
+     */
90
+    const video = document.querySelector('video')
91
+    console.log(video.play());
92
+
93
+    const model = document.querySelector('.model')
94
+    const btn = document.querySelector('button')
95
+    // 第一种方法 引导用户去与页面交互实现播放
96
+    async function play() {
97
+      try {
98
+        await video.play();
99
+        //使用await的原因是因为video.play()方法返回的是一个Promise,所以在这里我们可以对他进行一些处理
100
+        model.style.display = 'none';
101
+        btn.removeEventListener('click', play);
102
+        // 如果他自动播放了就隐藏按钮,消除点击事件
103
+      } catch (err) {
104
+        model.style.display = 'block';
105
+        btn.addEventListener('click', play);
106
+        // 如果Promise返回的是error就引导用户点击按钮,在调用play方法
107
+      }
108
+    }
109
+    play();
110
+
111
+    //第二种方法比较主流,类似的有网页版抖音以及B站
112
+    function play() {
113
+      video.muted = true;//设置视频为静音
114
+      video.play();//调用播放方法
115
+      const ctx = new AudioContext();
116
+      const canAutoPlay = ctx.state === 'running'; //通过这个可以判断出视频能不能够自动播放 如何可以它的值就是“running” 否则为"suspended"
117
+      // 如果是不能播放我们就执行下面的逻辑,其实就是类似于第一种方法,让用户与其交互
118
+      ctx.close();
119
+      if (canAutoPlay) {
120
+        video.muted = false;
121
+        model.style.display = 'none';
122
+        btn.removeEventListener('click', play);
123
+      }
124
+      else {
125
+        model.style.display = 'block';
126
+        btn.addEventListener('click', play);
127
+      }
128
+    }
129
+    play()
130
+
131
+  }
71 132
 
72 133
   render() {
73 134
     const stores = this.store.state;
@@ -77,103 +138,124 @@ class Home extends Component {
77 138
 
78 139
 
79 140
     return (
80
-      <div className={[styles.home + " home cbHome"]}>
81
-        <div className="leftContent">
82
-          <div className="topMsg">
83
-            <p className="topMsg_title">总产值</p>
84
-            <div className={changGif ? "topMsg_content changBg_topMsg_content" : "topMsg_content"}>
85
-              <span className="topMsg_number" class="shu1">232425.23</span><span className="topMsg_number_2">万元</span>
141
+      <div className={"home_box"}>
142
+        {/* 视频播放器 */}
143
+        <div className={"video_box"}>
144
+          {/*         controls 属性 : 值为 controls , 启用控制按钮 , 由于在不同的浏览器中表现不同 , 一般情况下 , 不显示控制按钮 ;
145
+        autoplay 属性 : 值为 autoplay , 在 Chrome 浏览器中 禁用自动播放 , 其它浏览器不禁用自动播放 ;
146
+        如果为视频设置静音播放 , 则可以在 Chrom 浏览器中 设置 autoplay 实现自动播放 ;
147
+        muted 属性 : 值为 muted , 将视频设置为静音播放 ;
148
+        如果为视频设置静音播放 , 则可以在 Chrom 浏览器中 设置 autoplay 实现自动播放 ;
149
+        width 属性 : 值为像素值 , 设置播放器宽度 ; 播放器的宽高建议只设置一个 , 避免失真 ;
150
+        height 属性 : 值为像素值 , 设置播放器高度 ; 播放器的宽高建议只设置一个 , 避免失真 ;
151
+        loop 属性 : 值为 loop , 设置播放器循环播放 ;
152
+        poster 属性 : 值为 图片 url 路径 , 设置视频位置等待加载时的图片 ;
153
+        preload 属性 :
154
+        设置 auto , 表示 预先加载视频 ;
155
+        设置 none , 表示 不预先加载视频 ;
156
+        */}
157
+          {/* <video style={{display:!changGif ? 'block' : 'none'}} src={require("@assets/imgs/dataVImg/homeVideo.mp4").default} autoplay="autoplay"></video> */}
158
+          <video src={require("@assets/imgs/dataVImg/homeVideo2.mp4").default} autoplay="autoplay" loop="loop"></video>
159
+          
160
+        </div>
161
+        <div className={[styles.home + " home cbHome"]}>
162
+          <div className="leftContent">
163
+            <div className="topMsg">
164
+              <p className="topMsg_title">总产值</p>
165
+              <div className={changGif ? "topMsg_content changBg_topMsg_content" : "topMsg_content"}>
166
+                <span className="topMsg_number" class="shu1">232425.23</span><span className="topMsg_number_2">万元</span>
167
+              </div>
86 168
             </div>
87
-          </div>
88
-          <div className="center_box">
89
-            <p className="topMsg_title">库存金额</p>
90
-            <div className="topMsg_content">
91
-              <LeftMenoyView></LeftMenoyView>
169
+            <div className="center_box">
170
+              <p className="topMsg_title">库存金额</p>
171
+              <div className="topMsg_content">
172
+                <LeftMenoyView></LeftMenoyView>
173
+              </div>
92 174
             </div>
93
-          </div>
94
-          <div className="bottomContent bigDivPd">
95
-            <p className="topMsg_title">月度产量/发货量</p>
96
-            <div className="topMsg_content">
97
-              <MoodSendView></MoodSendView>
175
+            <div className="bottomContent bigDivPd">
176
+              <p className="topMsg_title">月度产量/发货量</p>
177
+              <div className="topMsg_content">
178
+                <MoodSendView></MoodSendView>
179
+              </div>
98 180
             </div>
99 181
           </div>
100
-        </div>
101 182
 
102
-        <div className="centerCon">
103
-        <div className="topMsg">
104
-        <div className="topMsg2">
105
-            <div className="topMsg_content">
106
-              <div className="center_li">
107
-                <div className="right_li">
108
-                  <span className="topMsg_number" class="shu1">232425</span>
109
-                  <p className="topMsg_line"></p>
110
-                  <span className="topMsg_tip">年度产量/吨</span>
111
-                </div>
112
-              </div>
113
-              <div className="center_li">
114
-                <div className="right_li">
115
-                  <span className="topMsg_number" class="shu1">32425</span>
116
-                  <p className="topMsg_line"></p>
117
-                  <span className="topMsg_tip">年度发货量/吨</span>
183
+          <div className="centerCon">
184
+            <div className="topMsg">
185
+              <div className="topMsg2">
186
+                <div className="topMsg_content">
187
+                  <div className="center_li">
188
+                    <div className="right_li">
189
+                      <span className="topMsg_number" class="shu1">232425</span>
190
+                      <p className="topMsg_line"></p>
191
+                      <span className="topMsg_tip">年度产量/吨</span>
192
+                    </div>
193
+                  </div>
194
+                  <div className="center_li">
195
+                    <div className="right_li">
196
+                      <span className="topMsg_number" class="shu1">32425</span>
197
+                      <p className="topMsg_line"></p>
198
+                      <span className="topMsg_tip">年度发货量/吨</span>
199
+                    </div>
200
+                  </div>
201
+                  <div className="center_li">
202
+                    <span className="topMsg_number" class="shu1">13456</span>
203
+                    <p className="topMsg_line"></p>
204
+                    <span className="topMsg_tip">产品库存/吨</span>
205
+                  </div>
118 206
                 </div>
119 207
               </div>
120
-              <div className="center_li">
121
-                <span className="topMsg_number" class="shu1">13456</span>
122
-                <p className="topMsg_line"></p>
123
-                <span className="topMsg_tip">产品库存/吨</span>
124
-              </div>
125
-            </div>
126 208
             </div>
209
+            <div className="bottomContent">
210
+              <p className="topMsg_title">近30天产量</p>
211
+              <div className="topMsg_content">
212
+                <BottomLineForSend></BottomLineForSend>
213
+              </div>
127 214
             </div>
128
-          <div className="bottomContent">
129
-            <p className="topMsg_title">近30天产量</p>
130
-            <div className="topMsg_content">
131
-              <BottomLineForSend></BottomLineForSend>
132
-            </div>
215
+
133 216
           </div>
134 217
 
135
-        </div>
218
+          {/* 右侧信息栏 */}
219
+          <div className="rightContent">
220
+            <div className="topMsg bigDivPd">
221
+              <p className="topMsg_title">百万工时损工率</p>
222
+              <div className={changGif ? "topMsg_content changBg_topMsg_content" : "topMsg_content"}>
223
+                <div className="topMsg_box">
224
+                  <span className="topMsg_number" class="shu1">232425.23</span><span className="topMsg_number_2">%</span>
225
+                  <p className="topMsg_number_p">谢洪</p>
226
+                </div>
227
+              </div>
228
+            </div>
136 229
 
137
-        {/* 右侧信息栏 */}
138
-        <div className="rightContent">
139
-          <div className="topMsg bigDivPd">
140
-            <p className="topMsg_title">百万工时损工率</p>
141
-            <div className={changGif ? "topMsg_content changBg_topMsg_content" : "topMsg_content"}>
142
-              <div className="topMsg_box">
143
-                <span className="topMsg_number" class="shu1">232425.23</span><span className="topMsg_number_2">%</span>
144
-                <p className="topMsg_number_p">谢洪</p>
230
+            <div className="topMsg_2">
231
+              <p className="topMsg_title">一次合格率</p>
232
+              <div className="topMsg_content">
233
+                <OneQualified></OneQualified>
145 234
               </div>
146 235
             </div>
147
-          </div>
148 236
 
149
-          <div className="topMsg_2">
150
-            <p className="topMsg_title">一次合格率</p>
151
-            <div className="topMsg_content">
152
-              <OneQualified></OneQualified>
237
+            <div className="topMsg_3">
238
+              <p className="topMsg_title">产量计划完成率</p>
239
+              <div className={changGif ? "topMsg_content changBg_topMsg_content" : "topMsg_content"}>
240
+                <div className="topMsg_box">
241
+                  <span className="topMsg_number" class="shu1">78.1</span><span className="topMsg_number_2">%</span>
242
+                  <p className="topMsg_number_p">谢洪</p>
243
+                </div>
244
+              </div>
153 245
             </div>
154
-          </div>
155 246
 
156
-          <div className="topMsg_3">
157
-            <p className="topMsg_title">产量计划完成率</p>
158
-            <div className={changGif ? "topMsg_content changBg_topMsg_content" : "topMsg_content"}>
159
-              <div className="topMsg_box">
160
-                <span className="topMsg_number" class="shu1">78.1</span><span className="topMsg_number_2">%</span>
161
-                <p className="topMsg_number_p">谢洪</p>
247
+            <div className="bottomContent bigDivPd">
248
+              <p className="topMsg_title">碳排放</p>
249
+              <div className="topMsg_content">
250
+                <RightBottomView></RightBottomView>
162 251
               </div>
163 252
             </div>
164 253
           </div>
254
+          <div className="bottom_box">
165 255
 
166
-          <div className="bottomContent bigDivPd">
167
-            <p className="topMsg_title">碳排放</p>
168
-            <div className="topMsg_content">
169
-              <RightBottomView></RightBottomView>
170
-            </div>
171 256
           </div>
172
-        </div>
173
-        <div className="bottom_box">
174 257
 
175 258
         </div>
176
-
177 259
       </div>
178 260
     )
179 261
   }