tencent.jquery.pix.component 1.0.66-beta3 → 1.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/video/videoplayer.js +133 -20
- package/package.json +1 -1
|
@@ -68,6 +68,9 @@ VideoPlayer.prototype.init = async function() {
|
|
|
68
68
|
updatingProgress: false,
|
|
69
69
|
controlsDelayStart: 0,
|
|
70
70
|
firstPlay: true,
|
|
71
|
+
isFullScreen: false,
|
|
72
|
+
originalParent: null, // 保存原始父容器引用
|
|
73
|
+
originalNextSibling: null, // 保存原始位置的下一个兄弟节点
|
|
71
74
|
}
|
|
72
75
|
|
|
73
76
|
// 根据showProgressBar选项控制进度条显示
|
|
@@ -102,15 +105,27 @@ VideoPlayer.prototype.bindEvent = function() {
|
|
|
102
105
|
.on('canplay', 'video', () => {
|
|
103
106
|
console.log('canplay');
|
|
104
107
|
this.updateTotalTime();
|
|
108
|
+
})
|
|
109
|
+
.on('loadedmetadata', 'video', () => {
|
|
110
|
+
console.log('loadedmetadata');
|
|
111
|
+
this.updateTotalTime();
|
|
112
|
+
})
|
|
113
|
+
.on('durationchange', 'video', () => {
|
|
114
|
+
console.log('durationchange');
|
|
115
|
+
this.updateTotalTime();
|
|
116
|
+
})
|
|
117
|
+
.on('ended', 'video', () => {
|
|
118
|
+
console.log('video ended');
|
|
119
|
+
this.stop();
|
|
105
120
|
});
|
|
106
121
|
|
|
107
122
|
// 只有在显示进度条时才绑定进度条相关事件
|
|
108
123
|
if (this.options.showProgressBar) {
|
|
109
124
|
container
|
|
110
|
-
.on('dragstart', () => { console.log('video container dragstart') }
|
|
111
|
-
.on('drag', () => { console.log('video container drag') }
|
|
112
|
-
.on('dragend', () => { console.log('video container dragend') }
|
|
113
|
-
.on('click', () => { console.log('video container click') }
|
|
125
|
+
.on('dragstart', () => { console.log('video container dragstart') })
|
|
126
|
+
.on('drag', () => { console.log('video container drag') })
|
|
127
|
+
.on('dragend', () => { console.log('video container dragend') })
|
|
128
|
+
.on('click', () => { console.log('video container click') })
|
|
114
129
|
.on('dragstart', '.myplayer-progress', (e) => {
|
|
115
130
|
if (e.originalEvent) {
|
|
116
131
|
this.progressDragStart(e.originalEvent);
|
|
@@ -174,6 +189,7 @@ VideoPlayer.prototype.pause = function() {
|
|
|
174
189
|
}
|
|
175
190
|
|
|
176
191
|
VideoPlayer.prototype.stop = function() {
|
|
192
|
+
console.log('stop');
|
|
177
193
|
const video = this.$container.find('video')[0];
|
|
178
194
|
video.pause();
|
|
179
195
|
video.currentTime = 0;
|
|
@@ -233,7 +249,7 @@ VideoPlayer.prototype.hideControlsWithDelay = function() {
|
|
|
233
249
|
this.state.controlsDelayStart = Date.now();
|
|
234
250
|
setTimeout(() => {
|
|
235
251
|
const nowTime = Date.now();
|
|
236
|
-
console.debug("nowTime - this.state.controlsDelayStart", nowTime - this.state.controlsDelayStart);
|
|
252
|
+
// console.debug("nowTime - this.state.controlsDelayStart", nowTime - this.state.controlsDelayStart);
|
|
237
253
|
|
|
238
254
|
// 有时正常时间差也会小于设定的时间,所以判断时减去100ms
|
|
239
255
|
if (this.state.playing === true && nowTime - this.state.controlsDelayStart >= this.options.autoHideControlsDelayMs - 100) {
|
|
@@ -252,21 +268,38 @@ VideoPlayer.prototype.startUpdatingProgress = function() {
|
|
|
252
268
|
|
|
253
269
|
VideoPlayer.prototype.updateProgress = function() {
|
|
254
270
|
const video = this.$container.find('video')[0];
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
if (!video) return;
|
|
272
|
+
|
|
273
|
+
const currentTime = video.currentTime || 0;
|
|
274
|
+
const duration = video.duration || 0;
|
|
275
|
+
|
|
276
|
+
// 防止duration为NaN或0时计算出错
|
|
277
|
+
if (duration && !isNaN(duration) && duration > 0) {
|
|
278
|
+
const progress = currentTime / duration;
|
|
279
|
+
const parentWidth = this.$container.find('.myplayer-progress').width();
|
|
280
|
+
this.$container.find('.myplayer-subprogress').width(`${progress * parentWidth}px`);
|
|
281
|
+
//当progress为1时,将暂停按钮隐藏,播放按钮显示
|
|
282
|
+
if (progress >= 1) {
|
|
283
|
+
this.$container.find('.myplayer-btn-pause').hide();
|
|
284
|
+
this.$container.find('.myplayer-btn-play').show();
|
|
285
|
+
}
|
|
286
|
+
}
|
|
261
287
|
|
|
262
|
-
|
|
288
|
+
// 格式化当前播放时间(currentTime单位为秒)
|
|
289
|
+
this.$container.find('.myplayer-playtime').html(formatTime(currentTime));
|
|
263
290
|
}
|
|
264
291
|
|
|
265
292
|
VideoPlayer.prototype.updateTotalTime = function() {
|
|
266
293
|
const video = this.$container.find('video')[0];
|
|
294
|
+
if (!video) return;
|
|
295
|
+
|
|
267
296
|
const duration = video.duration;
|
|
268
|
-
|
|
269
|
-
|
|
297
|
+
|
|
298
|
+
// 只有当duration有效时才更新显示
|
|
299
|
+
if (duration && !isNaN(duration) && isFinite(duration) && duration > 0) {
|
|
300
|
+
// duration单位为秒
|
|
301
|
+
this.$container.find('.myplayer-totaltime').html(formatTime(duration));
|
|
302
|
+
}
|
|
270
303
|
}
|
|
271
304
|
|
|
272
305
|
VideoPlayer.prototype.toggleFullScreen = function() {
|
|
@@ -277,16 +310,22 @@ VideoPlayer.prototype.toggleFullScreen = function() {
|
|
|
277
310
|
const innerContainer = $container.find('.myplayer-container');
|
|
278
311
|
|
|
279
312
|
if (innerContainer.hasClass('myplayer-full-screen')) {
|
|
313
|
+
// 退出全屏:将容器移回原位置
|
|
314
|
+
this._moveBackToOriginal();
|
|
280
315
|
innerContainer.removeClass('myplayer-full-screen');
|
|
281
316
|
bottom.removeClass('myplayer-full-screen');
|
|
282
317
|
fullScreenBtn.show();
|
|
283
318
|
exitFullScreenBtn.hide();
|
|
319
|
+
this.state.isFullScreen = false;
|
|
284
320
|
this.options.stateChanged.call(this, 'exitFullScreen');
|
|
285
321
|
} else {
|
|
322
|
+
// 进入全屏:将容器移动到body
|
|
323
|
+
this._moveToBody();
|
|
286
324
|
innerContainer.addClass('myplayer-full-screen');
|
|
287
325
|
bottom.addClass('myplayer-full-screen');
|
|
288
326
|
fullScreenBtn.hide();
|
|
289
327
|
exitFullScreenBtn.show();
|
|
328
|
+
this.state.isFullScreen = true;
|
|
290
329
|
this.options.stateChanged.call(this, 'enterFullScreen');
|
|
291
330
|
}
|
|
292
331
|
|
|
@@ -301,22 +340,83 @@ VideoPlayer.prototype.setFullScreen = function (target = true) {
|
|
|
301
340
|
const innerContainer = $container.find('.myplayer-container');
|
|
302
341
|
|
|
303
342
|
if (!target && innerContainer.hasClass('myplayer-full-screen')) {
|
|
343
|
+
// 退出全屏:将容器移回原位置
|
|
344
|
+
this._moveBackToOriginal();
|
|
304
345
|
innerContainer.removeClass('myplayer-full-screen');
|
|
305
346
|
bottom.removeClass('myplayer-full-screen');
|
|
306
347
|
fullScreenBtn.show();
|
|
307
348
|
exitFullScreenBtn.hide();
|
|
349
|
+
this.state.isFullScreen = false;
|
|
308
350
|
this.options.stateChanged.call(this, 'exitFullScreen');
|
|
309
351
|
} else if (target && !innerContainer.hasClass('myplayer-full-screen')) {
|
|
352
|
+
// 进入全屏:将容器移动到body
|
|
353
|
+
this._moveToBody();
|
|
310
354
|
innerContainer.addClass('myplayer-full-screen');
|
|
311
355
|
bottom.addClass('myplayer-full-screen');
|
|
312
356
|
fullScreenBtn.hide();
|
|
313
357
|
exitFullScreenBtn.show();
|
|
358
|
+
this.state.isFullScreen = true;
|
|
314
359
|
this.options.stateChanged.call(this, 'enterFullScreen');
|
|
315
360
|
}
|
|
316
361
|
|
|
317
362
|
this.hideControlsWithDelay();
|
|
318
363
|
}
|
|
319
364
|
|
|
365
|
+
/**
|
|
366
|
+
* 将容器移动到body(进入全屏时调用)
|
|
367
|
+
* @private
|
|
368
|
+
*/
|
|
369
|
+
VideoPlayer.prototype._moveToBody = function() {
|
|
370
|
+
const containerEl = this.$container[0];
|
|
371
|
+
|
|
372
|
+
// 保存原始位置信息(仅在第一次移动时保存)
|
|
373
|
+
if (!this.state.originalParent) {
|
|
374
|
+
this.state.originalParent = containerEl.parentNode;
|
|
375
|
+
this.state.originalNextSibling = containerEl.nextSibling;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// 从原容器解绑
|
|
379
|
+
this.$container.off();
|
|
380
|
+
// 从body解绑所有相关事件
|
|
381
|
+
$(document.body).off('click.myplayer');
|
|
382
|
+
$(document.body).off('canplay.myplayer');
|
|
383
|
+
$(document.body).off('dragstart.myplayer');
|
|
384
|
+
$(document.body).off('drag.myplayer');
|
|
385
|
+
$(document.body).off('dragend.myplayer');
|
|
386
|
+
|
|
387
|
+
// 移动到body
|
|
388
|
+
document.body.appendChild(containerEl);
|
|
389
|
+
|
|
390
|
+
// 重新绑定事件
|
|
391
|
+
this.bindEvent();
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* 将容器移回原位置(退出全屏时调用)
|
|
396
|
+
* @private
|
|
397
|
+
*/
|
|
398
|
+
VideoPlayer.prototype._moveBackToOriginal = function() {
|
|
399
|
+
const containerEl = this.$container[0];
|
|
400
|
+
|
|
401
|
+
// 如果没有保存原始位置,说明还没移动过,直接返回
|
|
402
|
+
if (!this.state.originalParent) {
|
|
403
|
+
return;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// 解绑事件
|
|
407
|
+
this.$container.off();
|
|
408
|
+
|
|
409
|
+
// 移回原位置
|
|
410
|
+
if (this.state.originalNextSibling) {
|
|
411
|
+
this.state.originalParent.insertBefore(containerEl, this.state.originalNextSibling);
|
|
412
|
+
} else {
|
|
413
|
+
this.state.originalParent.appendChild(containerEl);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// 重新绑定事件
|
|
417
|
+
this.bindEvent();
|
|
418
|
+
}
|
|
419
|
+
|
|
320
420
|
/**
|
|
321
421
|
* 进度条拖动开始
|
|
322
422
|
* @param {MouseEvent} e
|
|
@@ -347,10 +447,14 @@ VideoPlayer.prototype.progressDrag = function(e) {
|
|
|
347
447
|
const video = $container.find('video')[0];
|
|
348
448
|
|
|
349
449
|
const parentWidth = progress.width();
|
|
350
|
-
|
|
450
|
+
// 使用getBoundingClientRect计算准确的点击位置
|
|
451
|
+
const rect = progress[0].getBoundingClientRect();
|
|
452
|
+
const clientX = e.clientX !== undefined ? e.clientX : (e.touches ? e.touches[0].clientX : 0);
|
|
453
|
+
const curOffset = Math.max(Math.min(clientX - rect.left, parentWidth), 0);
|
|
454
|
+
|
|
351
455
|
subprogress.width(`${curOffset}px`);
|
|
352
456
|
const adjustedPlayTime = curOffset / parentWidth * video.duration;
|
|
353
|
-
$container.find('.myplayer-playtime').html(formatTime(adjustedPlayTime
|
|
457
|
+
$container.find('.myplayer-playtime').html(formatTime(adjustedPlayTime));
|
|
354
458
|
}
|
|
355
459
|
|
|
356
460
|
/**
|
|
@@ -366,10 +470,19 @@ VideoPlayer.prototype.progressDragEnd = function(e) {
|
|
|
366
470
|
const video = $container.find('video')[0];
|
|
367
471
|
const progress = $container.find('.myplayer-progress');
|
|
368
472
|
const parentWidth = progress.width();
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
473
|
+
|
|
474
|
+
// 使用getBoundingClientRect计算准确的点击位置
|
|
475
|
+
const rect = progress[0].getBoundingClientRect();
|
|
476
|
+
const clientX = e.clientX !== undefined ? e.clientX : (e.touches ? e.touches[0].clientX : 0);
|
|
477
|
+
const curOffset = Math.max(Math.min(clientX - rect.left, parentWidth), 0);
|
|
478
|
+
|
|
479
|
+
// 计算目标播放时间(单位:秒)
|
|
480
|
+
const targetTime = (curOffset / parentWidth) * video.duration;
|
|
481
|
+
|
|
482
|
+
// 确保duration有效再设置currentTime
|
|
483
|
+
if (video.duration && !isNaN(video.duration) && video.duration > 0) {
|
|
484
|
+
video.currentTime = targetTime;
|
|
485
|
+
}
|
|
373
486
|
|
|
374
487
|
this.play();
|
|
375
488
|
|