Commit 33eec2b68fbd0c7c6a9031ac36e790cd213a25d1

Authored by xiaoxie
1 parent 2bc43f42

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

web_src/src/components/common/jessibuca.vue
1 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 4 <div class="buttons-box" id="buttonsBox">
4 5 <div class="buttons-box-left">
5 6 <i v-if="!playing" class="iconfont icon-play jessibuca-btn" @click="playBtnClick"></i>
... ... @@ -9,10 +10,11 @@
9 10 <i v-if="!isNotMute" class="iconfont icon-audio-mute jessibuca-btn" @click="jessibuca.cancelMute()"></i>
10 11 </div>
11 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 14 <!-- <i class="iconfont icon-file-record1 jessibuca-btn"></i>-->
14 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 18 <i class="iconfont icon-shuaxin11 jessibuca-btn" @click="playBtnClick"></i>
17 19 <i v-if="!fullscreen" class="iconfont icon-weibiaoti10 jessibuca-btn" @click="fullscreenSwich"></i>
18 20 <i v-if="fullscreen" class="iconfont icon-weibiaoti11 jessibuca-btn" @click="fullscreenSwich"></i>
... ... @@ -23,294 +25,299 @@
23 25  
24 26 <script>
25 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 253 if (this.jessibuca) {
279 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 260 this.playing = false;
282   - this.loaded = false;
  261 + this.err = "";
283 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 291 </script>
287 292  
288 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 323 </style>
... ...