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.
@@ -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') }, true)
111
- .on('drag', () => { console.log('video container drag') }, true)
112
- .on('dragend', () => { console.log('video container dragend') }, true)
113
- .on('click', () => { console.log('video container click') }, true)
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
- const currentTime = video.currentTime;
256
- const duration = video.duration;
257
- const progress = currentTime / duration;
258
-
259
- const parentWidth = this.$container.find('.myplayer-progress').width();
260
- this.$container.find('.myplayer-subprogress').width(`${progress * parentWidth}px`);
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
- this.$container.find('.myplayer-playtime').html(formatTime(currentTime / this.durationFactor));
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
- this.$container.find('.myplayer-totaltime').html(formatTime(duration / this.durationFactor));
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
- const curOffset = Math.max(Math.min(e.offsetX, parentWidth), 0);
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 / this.durationFactor));
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
- const curOffset = Math.max(Math.min(e.offsetX, parentWidth), 0);
370
-
371
- // currentTime set 单位s, get 单位ms
372
- video.currentTime = curOffset / progress.width() * video.duration / this.durationFactor;
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
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tencent.jquery.pix.component",
3
- "version": "1.0.66-beta3",
3
+ "version": "1.0.67",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "files": [