Commit 33eec2b68fbd0c7c6a9031ac36e790cd213a25d1

Authored by xiaoxie
1 parent 2bc43f42

动态计算播放器尺寸,保持16:9比例,避免出现黑框或固定大小无法缩放

web_src/src/components/common/jessibuca.vue
1 <template> 1 <template>
2 - <div :id="containerId" :ref="containerId" style="width: 100%;height: auto; background-color: #000" @dblclick="fullscreenSwich"> 2 + <div :id="containerId" :ref="containerId" style="width: 100%;height: auto; background-color: #000"
  3 + @dblclick="fullscreenSwich">
3 <div class="buttons-box" id="buttonsBox"> 4 <div class="buttons-box" id="buttonsBox">
4 <div class="buttons-box-left"> 5 <div class="buttons-box-left">
5 <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i> 6 <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
@@ -9,10 +10,11 @@ @@ -9,10 +10,11 @@
9 <i v-if="!isNotMute" class="iconfont icon-audio-mute jessibuca-btn" @click="jessibuca.cancelMute()"></i> 10 <i v-if="!isNotMute" class="iconfont icon-audio-mute jessibuca-btn" @click="jessibuca.cancelMute()"></i>
10 </div> 11 </div>
11 <div class="buttons-box-right"> 12 <div class="buttons-box-right">
12 - <span class="jessibuca-btn">{{kBps}} kb/s</span> 13 + <span class="jessibuca-btn">{{ kBps }} kb/s</span>
13 <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>--> 14 <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
14 <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>--> 15 <!-- <i class="iconfont icon-xiangqing2 jessibuca-btn" ></i>-->
15 - <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)" style="font-size: 1rem !important"></i> 16 + <i class="iconfont icon-camera1196054easyiconnet jessibuca-btn" @click="jessibuca.screenshot('截图','png',0.5)"
  17 + style="font-size: 1rem !important"></i>
16 <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i> 18 <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>
17 <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i> 19 <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>
18 <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i> 20 <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i>
@@ -23,294 +25,299 @@ @@ -23,294 +25,299 @@
23 25
24 <script> 26 <script>
25 export default { 27 export default {
26 - name: 'jessibuca',  
27 - data() {  
28 - return {  
29 - jessibuca: null,  
30 - playing: false,  
31 - isNotMute: false,  
32 - quieting: false,  
33 - fullscreen: false,  
34 - loaded: false, // mute  
35 - speed: 0,  
36 - performance: "", // 工作情况  
37 - kBps: 0,  
38 - btnDom: null,  
39 - videoInfo: null,  
40 - volume: 1,  
41 - rotate: 0,  
42 - vod: true, // 点播  
43 - forceNoOffscreen: false,  
44 - };  
45 - },  
46 - props: ['containerId','videoUrl', 'error', 'hasAudio', 'height'],  
47 - mounted () {  
48 - window.onerror = (msg) => {  
49 - // console.error(msg)  
50 - };  
51 - let paramUrl = decodeURIComponent(this.$route.params.url)  
52 - this.$nextTick(() =>{  
53 - let dom = document.getElementById(this.containerId);  
54 - if (dom.parentNode.clientHeight == 0) {  
55 - dom.style.height = (9/16 ) * dom.clientWidth + "px"  
56 - }  
57 - dom.style.height = dom.parentNode.clientHeight + "px";  
58 - dom.style.width = dom.parentNode.clientWidth + "px";  
59 -  
60 - if (typeof (this.videoUrl) == "undefined") {  
61 - this.videoUrl = paramUrl;  
62 - }  
63 - this.btnDom = document.getElementById("buttonsBox");  
64 - console.log("初始化时的地址为: " + this.videoUrl)  
65 - this.play(this.videoUrl)  
66 - }) 28 + name: 'jessibuca',
  29 + data() {
  30 + return {
  31 + jessibuca: null,
  32 + playing: false,
  33 + isNotMute: false,
  34 + quieting: false,
  35 + fullscreen: false,
  36 + loaded: false, // mute
  37 + speed: 0,
  38 + performance: "", // 工作情况
  39 + kBps: 0,
  40 + btnDom: null,
  41 + videoInfo: null,
  42 + volume: 1,
  43 + rotate: 0,
  44 + vod: true, // 点播
  45 + forceNoOffscreen: false,
  46 + };
  47 + },
  48 + props: ['containerId', 'videoUrl', 'error', 'hasAudio', 'height'],
  49 + mounted() {
  50 + window.onerror = (msg) => {
  51 + // console.error(msg)
  52 + };
  53 + let paramUrl = decodeURIComponent(this.$route.params.url)
  54 + this.$nextTick(() => {
  55 + this.updatePlayerDomSize()
  56 + window.onresize = () => {
  57 + this.updatePlayerDomSize()
  58 + }
  59 + if (typeof (this.videoUrl) == "undefined") {
  60 + this.videoUrl = paramUrl;
  61 + }
  62 + this.btnDom = document.getElementById("buttonsBox");
  63 + console.log("初始化时的地址为: " + this.videoUrl)
  64 + this.play(this.videoUrl)
  65 + })
  66 + },
  67 + watch: {
  68 + videoUrl(newData, oldData) {
  69 + this.play(newData)
67 }, 70 },
68 - watch:{  
69 - videoUrl(newData, oldData){  
70 - this.play(newData)  
71 - },  
72 - immediate:true 71 + immediate: true
  72 + },
  73 + methods: {
  74 + updatePlayerDomSize() {
  75 + let dom = document.getElementById(this.containerId);
  76 + const width = dom.parentNode.clientWidth
  77 + dom.style.width = width + 'px';
  78 + dom.style.height = (9 / 16) * width + "px";
73 }, 79 },
74 - methods: {  
75 - create(){  
76 - let options = {};  
77 - console.log(this.$refs[this.containerId])  
78 - console.log("hasAudio " + this.hasAudio) 80 + create() {
  81 + let options = {};
  82 + console.log(this.$refs[this.containerId])
  83 + console.log("hasAudio " + this.hasAudio)
79 84
80 - this.jessibuca = new window.Jessibuca(Object.assign(  
81 - {  
82 - container: this.$refs[this.containerId],  
83 - videoBuffer: 0.2, // 最大缓冲时长,单位秒  
84 - isResize: true,  
85 - decoder:"static/js/jessibuca/decoder.js",  
86 - useMSE: false,  
87 - showBandwidth: false,  
88 - isFlv: true,  
89 - // text: "WVP-PRO",  
90 - // background: "static/images/zlm-logo.png",  
91 - loadingText: "加载中",  
92 - hasAudio: typeof (this.hasAudio) =="undefined"? true: this.hasAudio,  
93 - debug: false,  
94 - supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。  
95 - operateBtns: {  
96 - fullscreen: false,  
97 - screenshot: false,  
98 - play: false,  
99 - audio: false,  
100 - recorder: false,  
101 - },  
102 - record: "record",  
103 - vod: this.vod,  
104 - forceNoOffscreen: this.forceNoOffscreen,  
105 - isNotMute: this.isNotMute,  
106 - },  
107 - options  
108 - )); 85 + this.jessibuca = new window.Jessibuca(Object.assign(
  86 + {
  87 + container: this.$refs[this.containerId],
  88 + videoBuffer: 0.2, // 最大缓冲时长,单位秒
  89 + isResize: true,
  90 + decoder: "static/js/jessibuca/decoder.js",
  91 + useMSE: false,
  92 + showBandwidth: false,
  93 + isFlv: true,
  94 + // text: "WVP-PRO",
  95 + // background: "static/images/zlm-logo.png",
  96 + loadingText: "加载中",
  97 + hasAudio: typeof (this.hasAudio) == "undefined" ? true : this.hasAudio,
  98 + debug: false,
  99 + supportDblclickFullscreen: false, // 是否支持屏幕的双击事件,触发全屏,取消全屏事件。
  100 + operateBtns: {
  101 + fullscreen: false,
  102 + screenshot: false,
  103 + play: false,
  104 + audio: false,
  105 + recorder: false,
  106 + },
  107 + record: "record",
  108 + vod: this.vod,
  109 + forceNoOffscreen: this.forceNoOffscreen,
  110 + isNotMute: this.isNotMute,
  111 + },
  112 + options
  113 + ));
109 114
110 - let _this = this;  
111 - this.jessibuca.on("load", function () {  
112 - console.log("on load init");  
113 - }); 115 + let _this = this;
  116 + this.jessibuca.on("load", function () {
  117 + console.log("on load init");
  118 + });
114 119
115 - this.jessibuca.on("log", function (msg) {  
116 - console.log("on log", msg);  
117 - });  
118 - this.jessibuca.on("record", function (msg) {  
119 - console.log("on record:", msg);  
120 - });  
121 - this.jessibuca.on("pause", function () {  
122 - _this.playing = false;  
123 - });  
124 - this.jessibuca.on("play", function () {  
125 - _this.playing = true;  
126 - });  
127 - this.jessibuca.on("fullscreen", function (msg) {  
128 - console.log("on fullscreen", msg);  
129 - _this.fullscreen = msg  
130 - }); 120 + this.jessibuca.on("log", function (msg) {
  121 + console.log("on log", msg);
  122 + });
  123 + this.jessibuca.on("record", function (msg) {
  124 + console.log("on record:", msg);
  125 + });
  126 + this.jessibuca.on("pause", function () {
  127 + _this.playing = false;
  128 + });
  129 + this.jessibuca.on("play", function () {
  130 + _this.playing = true;
  131 + });
  132 + this.jessibuca.on("fullscreen", function (msg) {
  133 + console.log("on fullscreen", msg);
  134 + _this.fullscreen = msg
  135 + });
131 136
132 - this.jessibuca.on("mute", function (msg) {  
133 - console.log("on mute", msg);  
134 - _this.isNotMute = !msg;  
135 - });  
136 - this.jessibuca.on("audioInfo", function (msg) {  
137 - // console.log("audioInfo", msg);  
138 - }); 137 + this.jessibuca.on("mute", function (msg) {
  138 + console.log("on mute", msg);
  139 + _this.isNotMute = !msg;
  140 + });
  141 + this.jessibuca.on("audioInfo", function (msg) {
  142 + // console.log("audioInfo", msg);
  143 + });
139 144
140 - this.jessibuca.on("videoInfo", function (msg) {  
141 - // this.videoInfo = msg;  
142 - console.log("videoInfo", msg); 145 + this.jessibuca.on("videoInfo", function (msg) {
  146 + // this.videoInfo = msg;
  147 + console.log("videoInfo", msg);
143 148
144 - }); 149 + });
145 150
146 - this.jessibuca.on("bps", function (bps) {  
147 - // console.log('bps', bps); 151 + this.jessibuca.on("bps", function (bps) {
  152 + // console.log('bps', bps);
148 153
149 - });  
150 - let _ts = 0;  
151 - this.jessibuca.on("timeUpdate", function (ts) {  
152 - // console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts);  
153 - _ts = ts;  
154 - }); 154 + });
  155 + let _ts = 0;
  156 + this.jessibuca.on("timeUpdate", function (ts) {
  157 + // console.log('timeUpdate,old,new,timestamp', _ts, ts, ts - _ts);
  158 + _ts = ts;
  159 + });
155 160
156 - this.jessibuca.on("videoInfo", function (info) {  
157 - console.log("videoInfo", info);  
158 - }); 161 + this.jessibuca.on("videoInfo", function (info) {
  162 + console.log("videoInfo", info);
  163 + });
159 164
160 - this.jessibuca.on("error", function (error) {  
161 - console.log("error", error);  
162 - }); 165 + this.jessibuca.on("error", function (error) {
  166 + console.log("error", error);
  167 + });
163 168
164 - this.jessibuca.on("timeout", function () {  
165 - console.log("timeout");  
166 - }); 169 + this.jessibuca.on("timeout", function () {
  170 + console.log("timeout");
  171 + });
167 172
168 - this.jessibuca.on('start', function () {  
169 - console.log('start');  
170 - }) 173 + this.jessibuca.on('start', function () {
  174 + console.log('start');
  175 + })
171 176
172 - this.jessibuca.on("performance", function (performance) {  
173 - let show = "卡顿";  
174 - if (performance === 2) {  
175 - show = "非常流畅";  
176 - } else if (performance === 1) {  
177 - show = "流畅";  
178 - }  
179 - _this.performance = show;  
180 - });  
181 - this.jessibuca.on('buffer', function (buffer) {  
182 - // console.log('buffer', buffer);  
183 - }) 177 + this.jessibuca.on("performance", function (performance) {
  178 + let show = "卡顿";
  179 + if (performance === 2) {
  180 + show = "非常流畅";
  181 + } else if (performance === 1) {
  182 + show = "流畅";
  183 + }
  184 + _this.performance = show;
  185 + });
  186 + this.jessibuca.on('buffer', function (buffer) {
  187 + // console.log('buffer', buffer);
  188 + })
184 189
185 - this.jessibuca.on('stats', function (stats) {  
186 - // console.log('stats', stats);  
187 - }) 190 + this.jessibuca.on('stats', function (stats) {
  191 + // console.log('stats', stats);
  192 + })
188 193
189 - this.jessibuca.on('kBps', function (kBps) {  
190 - _this.kBps = Math.round(kBps);  
191 - }); 194 + this.jessibuca.on('kBps', function (kBps) {
  195 + _this.kBps = Math.round(kBps);
  196 + });
192 197
193 - // 显示时间戳 PTS  
194 - this.jessibuca.on('videoFrame', function () { 198 + // 显示时间戳 PTS
  199 + this.jessibuca.on('videoFrame', function () {
195 200
196 - }) 201 + })
197 202
198 - //  
199 - this.jessibuca.on('metadata', function () { 203 + //
  204 + this.jessibuca.on('metadata', function () {
200 205
201 - });  
202 - },  
203 - resize(){  
204 - if (this.jessibuca){  
205 - this.jessibuca.resize()  
206 - this.$nextTick(() =>{  
207 - let dom = document.getElementById(this.containerId);  
208 - if (dom.parentNode.clientHeight == 0) {  
209 - dom.style.height = (9/16 ) * dom.clientWidth + "px"  
210 - }  
211 - dom.style.height = dom.parentNode.clientHeight + "px";  
212 - dom.style.width = dom.parentNode.clientWidth + "px";  
213 - })  
214 - }  
215 - },  
216 - playBtnClick: function (event){  
217 - this.play(this.videoUrl)  
218 - },  
219 - play: function (url) {  
220 - console.log(url)  
221 - if (this.jessibuca) {  
222 - this.destroy();  
223 - }  
224 - this.create();  
225 - this.jessibuca.on("play", () => {  
226 - this.playing = true;  
227 - this.loaded = true;  
228 - this.quieting = this.jessibuca.quieting;  
229 - });  
230 - if (this.jessibuca.hasLoaded()) {  
231 - this.jessibuca.play(url);  
232 - } else {  
233 - this.jessibuca.on("load", () => {  
234 - console.log("load 播放")  
235 - this.jessibuca.play(url);  
236 - });  
237 - }  
238 - },  
239 - pause: function () {  
240 - if (this.jessibuca) {  
241 - this.jessibuca.pause();  
242 - }  
243 - this.playing = false;  
244 - this.err = "";  
245 - this.performance = "";  
246 - },  
247 - destroy: function () {  
248 - if (this.jessibuca) {  
249 - this.jessibuca.destroy();  
250 - }  
251 - if (document.getElementById("buttonsBox") == null) {  
252 - document.getElementById("container").appendChild(this.btnDom) 206 + });
  207 + },
  208 + resize() {
  209 + if (this.jessibuca) {
  210 + this.jessibuca.resize()
  211 + this.$nextTick(() => {
  212 + let dom = document.getElementById(this.containerId);
  213 + if (dom.parentNode.clientHeight == 0) {
  214 + dom.style.height = (9 / 16) * dom.clientWidth + "px"
253 } 215 }
254 - this.jessibuca = null;  
255 - this.playing = false;  
256 - this.err = "";  
257 - this.performance = "";  
258 -  
259 - },  
260 - eventcallbacK: function(type, message) {  
261 - // console.log("player 事件回调")  
262 - // console.log(type)  
263 - // console.log(message)  
264 - },  
265 - fullscreenSwich: function (){  
266 - let isFull = this.isFullscreen()  
267 - this.jessibuca.setFullscreen(!isFull)  
268 - this.fullscreen = !isFull;  
269 - },  
270 - isFullscreen: function (){  
271 - return document.fullscreenElement ||  
272 - document.msFullscreenElement ||  
273 - document.mozFullScreenElement ||  
274 - document.webkitFullscreenElement || false;  
275 - } 216 + dom.style.height = dom.parentNode.clientHeight + "px";
  217 + dom.style.width = dom.parentNode.clientWidth + "px";
  218 + })
  219 + }
  220 + },
  221 + playBtnClick: function (event) {
  222 + this.play(this.videoUrl)
  223 + },
  224 + play: function (url) {
  225 + console.log(url)
  226 + if (this.jessibuca) {
  227 + this.destroy();
  228 + }
  229 + this.create();
  230 + this.jessibuca.on("play", () => {
  231 + this.playing = true;
  232 + this.loaded = true;
  233 + this.quieting = this.jessibuca.quieting;
  234 + });
  235 + if (this.jessibuca.hasLoaded()) {
  236 + this.jessibuca.play(url);
  237 + } else {
  238 + this.jessibuca.on("load", () => {
  239 + console.log("load 播放")
  240 + this.jessibuca.play(url);
  241 + });
  242 + }
  243 + },
  244 + pause: function () {
  245 + if (this.jessibuca) {
  246 + this.jessibuca.pause();
  247 + }
  248 + this.playing = false;
  249 + this.err = "";
  250 + this.performance = "";
276 }, 251 },
277 - destroyed() { 252 + destroy: function () {
278 if (this.jessibuca) { 253 if (this.jessibuca) {
279 this.jessibuca.destroy(); 254 this.jessibuca.destroy();
280 } 255 }
  256 + if (document.getElementById("buttonsBox") == null) {
  257 + document.getElementById("container").appendChild(this.btnDom)
  258 + }
  259 + this.jessibuca = null;
281 this.playing = false; 260 this.playing = false;
282 - this.loaded = false; 261 + this.err = "";
283 this.performance = ""; 262 this.performance = "";
  263 +
  264 + },
  265 + eventcallbacK: function (type, message) {
  266 + // console.log("player 事件回调")
  267 + // console.log(type)
  268 + // console.log(message)
  269 + },
  270 + fullscreenSwich: function () {
  271 + let isFull = this.isFullscreen()
  272 + this.jessibuca.setFullscreen(!isFull)
  273 + this.fullscreen = !isFull;
284 }, 274 },
  275 + isFullscreen: function () {
  276 + return document.fullscreenElement ||
  277 + document.msFullscreenElement ||
  278 + document.mozFullScreenElement ||
  279 + document.webkitFullscreenElement || false;
  280 + }
  281 + },
  282 + destroyed() {
  283 + if (this.jessibuca) {
  284 + this.jessibuca.destroy();
  285 + }
  286 + this.playing = false;
  287 + this.loaded = false;
  288 + this.performance = "";
  289 + },
285 } 290 }
286 </script> 291 </script>
287 292
288 <style> 293 <style>
289 - .buttons-box{  
290 - width: 100%;  
291 - height: 28px;  
292 - background-color: rgba(43, 51, 63, 0.7);  
293 - position: absolute;  
294 - display: -webkit-box;  
295 - display: -ms-flexbox;  
296 - display: flex;  
297 - left: 0;  
298 - bottom: 0;  
299 - user-select: none;  
300 - z-index: 10;  
301 - }  
302 - .jessibuca-btn{  
303 - width: 20px;  
304 - color: rgb(255, 255, 255);  
305 - line-height: 27px;  
306 - margin: 0px 10px;  
307 - padding: 0px 2px;  
308 - cursor: pointer;  
309 - text-align: center;  
310 - font-size: 0.8rem !important;  
311 - }  
312 - .buttons-box-right {  
313 - position: absolute;  
314 - right: 0;  
315 - } 294 +.buttons-box {
  295 + width: 100%;
  296 + height: 28px;
  297 + background-color: rgba(43, 51, 63, 0.7);
  298 + position: absolute;
  299 + display: -webkit-box;
  300 + display: -ms-flexbox;
  301 + display: flex;
  302 + left: 0;
  303 + bottom: 0;
  304 + user-select: none;
  305 + z-index: 10;
  306 +}
  307 +
  308 +.jessibuca-btn {
  309 + width: 20px;
  310 + color: rgb(255, 255, 255);
  311 + line-height: 27px;
  312 + margin: 0px 10px;
  313 + padding: 0px 2px;
  314 + cursor: pointer;
  315 + text-align: center;
  316 + font-size: 0.8rem !important;
  317 +}
  318 +
  319 +.buttons-box-right {
  320 + position: absolute;
  321 + right: 0;
  322 +}
316 </style> 323 </style>