@volcengine/veplayer 1.15.1 → 1.15.2-rc.1

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.

Potentially problematic release.


This version of @volcengine/veplayer might be problematic. Click here for more details.

Files changed (245) hide show
  1. package/.changeset/config.json +11 -0
  2. package/.changeset/curvy-yaks-smoke.md +5 -0
  3. package/.changeset/neat-eyes-search.md +5 -0
  4. package/.codebase/pipelines/create-api-doc.yaml +16 -0
  5. package/.eslintignore +5 -0
  6. package/.eslintrc.json +53 -0
  7. package/.stylelintrc.js +51 -0
  8. package/CHANGELOG.md +5665 -0
  9. package/DEV_README.md +39 -0
  10. package/LICENSE +20 -0
  11. package/README_EN.md +46 -0
  12. package/build.sh +44 -0
  13. package/docg.config.js +65 -0
  14. package/env/byteplus.js +30 -0
  15. package/env/volcengine.js +50 -0
  16. package/fixtures/favicon.ico +0 -0
  17. package/fixtures/index.base.js +59 -0
  18. package/fixtures/index.html +41 -0
  19. package/fixtures/index.js +185 -0
  20. package/libd.config.js +147 -0
  21. package/localhost+2-key.pem +28 -0
  22. package/localhost+2.pem +26 -0
  23. package/lux.config.mjs +37 -0
  24. package/package.json +123 -4
  25. package/sdkhub.config.json +10 -0
  26. package/src/@types/global.d.ts +35 -0
  27. package/src/assets/common/error.svg +3 -0
  28. package/src/assets/common/errorImg.png +0 -0
  29. package/src/assets/common/errorImg.svg +12 -0
  30. package/src/assets/icons/mobile/definition.svg +3 -0
  31. package/src/assets/icons/mobile/line.svg +3 -0
  32. package/src/assets/icons/mobile/mobileDanmu.svg +1 -0
  33. package/src/assets/icons/mobile/mobileDanmuAcitive.svg +1 -0
  34. package/src/assets/icons/mobile/mobileDanmuSetting.svg +1 -0
  35. package/src/assets/icons/mobile/mobileExitFullscreen.svg +1 -0
  36. package/src/assets/icons/mobile/mobileFullscreen.svg +1 -0
  37. package/src/assets/icons/mobile/mobilePause.svg +4 -0
  38. package/src/assets/icons/mobile/mobilePlay.svg +4 -0
  39. package/src/assets/icons/mobile/mobilePlaynext.svg +1 -0
  40. package/src/assets/icons/mobile/mobileRefresh.svg +1 -0
  41. package/src/assets/icons/mobile/more.svg +3 -0
  42. package/src/assets/icons/mobile/muted.svg +22 -0
  43. package/src/assets/icons/mobile/playbackrate.svg +3 -0
  44. package/src/assets/icons/pc/danmu.svg +1 -0
  45. package/src/assets/icons/pc/danmuActive.svg +1 -0
  46. package/src/assets/icons/pc/danmuSettings.svg +1 -0
  47. package/src/assets/icons/pc/download.svg +14 -0
  48. package/src/assets/icons/pc/exitFullscreen.svg +1 -0
  49. package/src/assets/icons/pc/exitMirror.svg +10 -0
  50. package/src/assets/icons/pc/extend.svg +1 -0
  51. package/src/assets/icons/pc/fullscreen.svg +1 -0
  52. package/src/assets/icons/pc/getMirror.svg +10 -0
  53. package/src/assets/icons/pc/list.svg +20 -0
  54. package/src/assets/icons/pc/noPoster.svg +119 -0
  55. package/src/assets/icons/pc/pause.svg +1 -0
  56. package/src/assets/icons/pc/pip.svg +1 -0
  57. package/src/assets/icons/pc/pipExit.svg +1 -0
  58. package/src/assets/icons/pc/play-next-btn.svg +4 -0
  59. package/src/assets/icons/pc/play.svg +1 -0
  60. package/src/assets/icons/pc/playNext.svg +1 -0
  61. package/src/assets/icons/pc/playerLoading.svg +1 -0
  62. package/src/assets/icons/pc/refresh.svg +1 -0
  63. package/src/assets/icons/pc/replay.svg +1 -0
  64. package/src/assets/icons/pc/reset.svg +6 -0
  65. package/src/assets/icons/pc/startPlay.svg +1 -0
  66. package/src/assets/icons/pc/subtitleclose.svg +5 -0
  67. package/src/assets/icons/pc/subtitleopen.svg +3 -0
  68. package/src/assets/icons/pc/theaterEnter.svg +1 -0
  69. package/src/assets/icons/pc/theaterExit.svg +1 -0
  70. package/src/assets/icons/pc/volumeLarge.svg +1 -0
  71. package/src/assets/icons/pc/volumeMuted.svg +1 -0
  72. package/src/assets/icons/pc/volumeSmall.svg +1 -0
  73. package/src/config/defaultPreset.ts +110 -0
  74. package/src/config/playerOptionMobile.ts +166 -0
  75. package/src/config/playerOptionPc.ts +147 -0
  76. package/src/config/playerPreset.ts +242 -0
  77. package/src/constants/api.ts +13 -0
  78. package/src/constants/event.ts +577 -0
  79. package/src/constants/player.ts +84 -0
  80. package/src/constants/plugin.ts +19 -0
  81. package/src/constants/umdMap.ts +137 -0
  82. package/src/constants/umdPlugins.json +68 -0
  83. package/src/core/index.ts +7 -0
  84. package/src/core/player.ts +2713 -0
  85. package/src/core/playerData.ts +812 -0
  86. package/src/env.d.ts +47 -0
  87. package/src/index.ts +24 -0
  88. package/src/index.umd.ts +54 -0
  89. package/src/interface/adaptRange.d.ts +33 -0
  90. package/src/interface/api.ts +132 -0
  91. package/src/interface/autoBitrate.d.ts +41 -0
  92. package/src/interface/index.ts +1685 -0
  93. package/src/interface/rtm.ts +56 -0
  94. package/src/interface/sdkErrorPlugin.ts +145 -0
  95. package/src/interface/subtitle.ts +381 -0
  96. package/src/interface/video.ts +107 -0
  97. package/src/interface/xgplayer.ts +748 -0
  98. package/src/lang/constants.ts +69 -0
  99. package/src/lang/en.ts +98 -0
  100. package/src/lang/index.ts +33 -0
  101. package/src/lang/jp.ts +100 -0
  102. package/src/lang/zh-hk.ts +80 -0
  103. package/src/lang/zh.ts +79 -0
  104. package/src/license/index.ts +315 -0
  105. package/src/license/ttlicense2.js +15 -0
  106. package/src/license/ttlicense2.wasm +0 -0
  107. package/src/music/icons/back.svg +3 -0
  108. package/src/music/icons/forward.svg +3 -0
  109. package/src/music/icons/loop.svg +10 -0
  110. package/src/music/icons/order.svg +10 -0
  111. package/src/music/icons/pause-circle.svg +23 -0
  112. package/src/music/icons/play-circle.svg +22 -0
  113. package/src/music/icons/random.svg +10 -0
  114. package/src/music/icons/sloop.svg +10 -0
  115. package/src/music/index.ts +5 -0
  116. package/src/music/music.ts +550 -0
  117. package/src/music/plugins/index.less +185 -0
  118. package/src/music/plugins/index.ts +6 -0
  119. package/src/music/plugins/musicBackward.ts +82 -0
  120. package/src/music/plugins/musicCover.ts +45 -0
  121. package/src/music/plugins/musicForward.ts +82 -0
  122. package/src/music/plugins/musicMeta.ts +32 -0
  123. package/src/music/plugins/musicMode.ts +152 -0
  124. package/src/music/plugins/musicNext.ts +93 -0
  125. package/src/music/plugins/musicPrev.ts +94 -0
  126. package/src/music/preset.ts +69 -0
  127. package/src/music/xhr.ts +37 -0
  128. package/src/plugins/common/extendPluginFactory.ts +132 -0
  129. package/src/plugins/common/mobilePlayerPanel.ts +253 -0
  130. package/src/plugins/external/LiveInfoPanel.ts +340 -0
  131. package/src/plugins/external/ad/adsPlugin.ts +1 -0
  132. package/src/plugins/external/aiSubtitleIconPlugin.ts +270 -0
  133. package/src/plugins/external/aiSubtitlePlugin.ts +452 -0
  134. package/src/plugins/external/definitionDemotePlugin.ts +591 -0
  135. package/src/plugins/external/memoryPlay.ts +247 -0
  136. package/src/plugins/external/mirrorPlugin.ts +141 -0
  137. package/src/plugins/external/playList/OptionList.ts +204 -0
  138. package/src/plugins/external/playList/index.ts +743 -0
  139. package/src/plugins/external/subtitle/index.ts +672 -0
  140. package/src/plugins/external/subtitle/nativeSubTitle.ts +115 -0
  141. package/src/plugins/external/timeShiftPlugin.ts +484 -0
  142. package/src/plugins/external/watermark/dynamicWatermark.less +13 -0
  143. package/src/plugins/external/watermark/dynamicWatermark.ts +449 -0
  144. package/src/plugins/external/watermark/dynamicWatermarkPlugin.ts +185 -0
  145. package/src/plugins/inner/common/autoplayPlugin.ts +435 -0
  146. package/src/plugins/inner/common/danmu/container.ts +120 -0
  147. package/src/plugins/inner/common/danmu/index.ts +683 -0
  148. package/src/plugins/inner/common/danmu/lang.ts +139 -0
  149. package/src/plugins/inner/common/danmu/panel.ts +20 -0
  150. package/src/plugins/inner/common/danmu/slider.ts +210 -0
  151. package/src/plugins/inner/common/danmu/state.ts +118 -0
  152. package/src/plugins/inner/common/danmu/switch.ts +74 -0
  153. package/src/plugins/inner/common/definitionBasePlugin.ts +353 -0
  154. package/src/plugins/inner/common/errorPlugin.ts +544 -0
  155. package/src/plugins/inner/common/liveLogger.ts +137 -0
  156. package/src/plugins/inner/common/poster/index.less +66 -0
  157. package/src/plugins/inner/common/poster/index.ts +178 -0
  158. package/src/plugins/inner/common/refreshPlugin.ts +88 -0
  159. package/src/plugins/inner/common/rtmPlugin.ts +62 -0
  160. package/src/plugins/inner/common/toastPlugin.ts +90 -0
  161. package/src/plugins/inner/common/unmutePlugin.ts +133 -0
  162. package/src/plugins/inner/common/vodLogger.ts +80 -0
  163. package/src/plugins/inner/mobile/DefinitionMobilePlugin.ts +217 -0
  164. package/src/plugins/inner/mobile/LineMobilePlugins.ts +169 -0
  165. package/src/plugins/inner/mobile/MoreButtonPlugin.ts +176 -0
  166. package/src/plugins/inner/mobile/PlaybackRatePlugin.ts +199 -0
  167. package/src/plugins/inner/pc/definitionPlugin.ts +203 -0
  168. package/src/plugins/inner/pc/multilinePlugin.ts +93 -0
  169. package/src/sdkPlugin/abr.ts +67 -0
  170. package/src/sdkPlugin/adaptRange.ts +49 -0
  171. package/src/sdkPlugin/authToken.ts +557 -0
  172. package/src/sdkPlugin/sdkPlugin.ts +125 -0
  173. package/src/sdkPlugin/sdkPluginManager.ts +157 -0
  174. package/src/sdkPlugin/strategy.ts +47 -0
  175. package/src/strategy/index.ts +740 -0
  176. package/src/strategy/vestrategy-h265-wrapper.ts +34 -0
  177. package/src/strategy/vestrategy-preload-wrapper.ts +414 -0
  178. package/src/streamAdapters/base.ts +89 -0
  179. package/src/streamAdapters/dash.ts +230 -0
  180. package/src/streamAdapters/default.ts +53 -0
  181. package/src/streamAdapters/hls.ts +278 -0
  182. package/src/streamAdapters/index.ts +40 -0
  183. package/src/streamAdapters/mp4.ts +214 -0
  184. package/src/style/bytelive/danmu.less +293 -0
  185. package/src/style/bytelive/definitionIcon.less +80 -0
  186. package/src/style/bytelive/error.less +165 -0
  187. package/src/style/bytelive/index.less +62 -0
  188. package/src/style/bytelive/loading.less +5 -0
  189. package/src/style/bytelive/mobiePlugin.less +2 -0
  190. package/src/style/bytelive/mobile.less +76 -0
  191. package/src/style/bytelive/moreButton.less +79 -0
  192. package/src/style/bytelive/panel.less +259 -0
  193. package/src/style/bytelive/pc.less +161 -0
  194. package/src/style/bytelive/refresh.less +3 -0
  195. package/src/style/bytelive/reset.less +4 -0
  196. package/src/style/bytelive/toast.less +61 -0
  197. package/src/style/bytelive/unmute.less +65 -0
  198. package/src/style/external/LiveInfoPanel.less +41 -0
  199. package/src/style/external/aisub.less +139 -0
  200. package/src/style/external/aisubIcon.less +25 -0
  201. package/src/style/external/index.less +5 -0
  202. package/src/style/external/larkWindow.less +36 -0
  203. package/src/style/external/mirror.less +27 -0
  204. package/src/style/external/playList.less +258 -0
  205. package/src/style/external/timeShift.less +102 -0
  206. package/src/style/external/vttSubtitle.less +25 -0
  207. package/src/utils/debug.ts +62 -0
  208. package/src/utils/definition.ts +61 -0
  209. package/src/utils/escapeHtml.ts +93 -0
  210. package/src/utils/eventMiddleWare.ts +108 -0
  211. package/src/utils/index.ts +621 -0
  212. package/src/utils/intervalTimer.ts +38 -0
  213. package/src/utils/isHijackBrowser.ts +71 -0
  214. package/src/utils/proxy.ts +139 -0
  215. package/src/utils/storage.ts +34 -0
  216. package/src/utils/time.ts +19 -0
  217. package/src/utils/toast/index.less +20 -0
  218. package/src/utils/toast/index.ts +21 -0
  219. package/src/utils/token.ts +395 -0
  220. package/src/utils/u8a.ts +4 -0
  221. package/src/utils/umdLoader.ts +193 -0
  222. package/src/utils/video.ts +43 -0
  223. package/src/utils/xhr.ts +160 -0
  224. package/src/veError/error.ts +301 -0
  225. package/src/veError/index.ts +681 -0
  226. package/src/veError/playerProxy.ts +69 -0
  227. package/tsconfig.json +27 -0
  228. package/index.d.ts +0 -6874
  229. package/index.min.css +0 -1
  230. package/index.min.js +0 -2
  231. package/plugin/DashAbralgo.js +0 -2
  232. package/plugin/XGVideo.js +0 -2
  233. package/plugin/danmuMask.js +0 -2
  234. package/plugin/danmujs.js +0 -3
  235. package/plugin/dash.js +0 -2
  236. package/plugin/flv.js +0 -2
  237. package/plugin/hls.js +0 -2
  238. package/plugin/hlsEncrypt.js +0 -2
  239. package/plugin/mp4Encrypt.js +0 -2
  240. package/plugin/preloader.js +0 -2
  241. package/plugin/streamprobe.js +0 -2
  242. package/plugin/vestrategy.js +0 -1
  243. package/plugin/vestrategy_adapt_range.js +0 -1
  244. package/plugin/vestrategy_h265.js +0 -1
  245. package/plugin/vestrategy_preload.js +0 -1
@@ -0,0 +1,66 @@
1
+ .xgplayer {
2
+ .xgplayer-poster {
3
+ display: block;
4
+ opacity: 1;
5
+ visibility: visible;
6
+ position: absolute;
7
+ left: 0;
8
+ top: 0;
9
+ width: 100%;
10
+ height: 100%;
11
+ background-position: center center;
12
+ background-size: 100% auto;
13
+ background-repeat: no-repeat;
14
+ transition: opacity 0.3s ease, visibility 0.3s ease;
15
+ pointer-events: none;
16
+
17
+ &.hide {
18
+ opacity: 0;
19
+ visibility: hidden;
20
+ }
21
+
22
+ &.active {
23
+ background-color: transparent;
24
+ }
25
+ }
26
+ }
27
+
28
+ .xgplayer.xgplayer-playing {
29
+ .xgplayer-poster {
30
+ // display: none;
31
+ opacity: 0;
32
+ visibility: hidden;
33
+ }
34
+
35
+ .xg-not-hidden {
36
+ opacity: 1;
37
+ visibility: visible;
38
+ }
39
+ }
40
+
41
+ .xgplayer {
42
+ &.xgplayer-is-enter,
43
+ &.xgplayer-playing {
44
+ .xgplayer-poster.xg-showplay {
45
+ opacity: 1;
46
+ visibility: visible;
47
+ }
48
+ }
49
+ }
50
+
51
+ .xgplayer {
52
+ &.xgplayer-nostart,
53
+ &.xgplayer-ended,
54
+ &.not-allow-autoplay {
55
+ .xgplayer-poster {
56
+ // display: block;
57
+ opacity: 1;
58
+ visibility: visible;
59
+
60
+ &.hide {
61
+ opacity: 0;
62
+ visibility: hidden;
63
+ }
64
+ }
65
+ }
66
+ }
@@ -0,0 +1,178 @@
1
+ /**
2
+ * @author bytedance
3
+ * @Description 重写xgplayer的poster,为后续接入imageX、定制poster功能做准备
4
+ * @date 2024/5/8 17:18
5
+ */
6
+ import { Plugin, Events, Util } from 'xgplayer';
7
+ import './index.less';
8
+
9
+ /** {zh}
10
+ * @list Options
11
+ * @brief 封面配置
12
+ * @kind property
13
+ */
14
+ export interface IPoster {
15
+ /** {zh}
16
+ * @brief 封面图 URL 地址。
17
+ * @default -
18
+ */
19
+ poster: string;
20
+ /** {zh}
21
+ * @brief 是否在播放结束之后显示封面图。
22
+ * @default true
23
+ */
24
+ isEndedShow?: boolean;
25
+ /** {zh}
26
+ * @brief 是否播放后才隐藏封面图。
27
+ * - `true`:播放后隐藏,即timeupdate事件触发后才隐藏。
28
+ * - `false`:在 `play` 事件触发后隐藏封面图,在iOS端play事件到实际播放会有一段时间间隔,在这段时间里播放器显示黑屏。
29
+ * @default false
30
+ */
31
+ hideCanplay?: boolean;
32
+ /** {zh}
33
+ * @brief 是否一直显示封面图,常用于播放音频的场景
34
+ * @default false
35
+ */
36
+ notHidden?: boolean;
37
+ /** {zh}
38
+ * @brief 封面图填充方式。取值如下:
39
+ * - `fixWidth`:宽度方向填充,不会被拉伸压缩。
40
+ * - `fixHeight`:高度方向填充,不会被拉伸压缩。
41
+ * - `cover`:完全覆盖容器,多余部分会被裁剪。
42
+ * - `contain`:尽可能的缩放图像填充容器并保持图像的宽高比例,图像不会被裁剪压缩。。
43
+ */
44
+ fillMode?: 'fixWidth' | 'fixHeight' | 'cover' | 'contain';
45
+ }
46
+
47
+ class Poster extends Plugin {
48
+ static get pluginName() {
49
+ return 'poster';
50
+ }
51
+
52
+ static get defaultConfig(): IPoster {
53
+ return {
54
+ isEndedShow: true, // 是否在播放结束之后显示
55
+ hideCanplay: false, // 设置为true时,播放后才隐藏,在视频地址更新后会重新显示poster。默认为false,即在play事件触发后隐藏poster
56
+ notHidden: false, // 是否一直显示
57
+ poster: '', // 封面图地址
58
+ fillMode: 'fixWidth', // 封面图填充方式,fixWidth / fixHeight / cover / contain
59
+ };
60
+ }
61
+
62
+ set isEndedShow(value) {
63
+ this.config.isEndedShow = value;
64
+ }
65
+
66
+ get isEndedShow() {
67
+ return this.config.isEndedShow;
68
+ }
69
+
70
+ hide() {
71
+ Util.addClass(this.root, 'hide');
72
+ }
73
+
74
+ show() {
75
+ Util.removeClass(this.root, 'hide');
76
+ return '';
77
+ }
78
+
79
+ beforeCreate(args) {
80
+ if (typeof args.player.config.poster === 'string') {
81
+ args.config.poster = args.player.config.poster;
82
+ }
83
+ }
84
+
85
+ afterCreate() {
86
+ this.on(Events.ENDED, () => {
87
+ if (this.isEndedShow) {
88
+ Util.removeClass(this.root, 'hide');
89
+ }
90
+ });
91
+
92
+ if (this.config.hideCanplay) {
93
+ this.once(Events.TIME_UPDATE, () => {
94
+ this.onTimeUpdate();
95
+ });
96
+ this.on(Events.URL_CHANGE, () => {
97
+ Util.removeClass(this.root, 'hide');
98
+ Util.addClass(this.root, 'xg-showplay');
99
+ this.once(Events.TIME_UPDATE, () => {
100
+ this.onTimeUpdate();
101
+ });
102
+ });
103
+ } else {
104
+ this.on(Events.PLAY, () => {
105
+ Util.addClass(this.root, 'hide');
106
+ });
107
+ }
108
+ }
109
+
110
+ onTimeUpdate() {
111
+ if (!this.player.currentTime) {
112
+ this.once(Events.TIME_UPDATE, () => {
113
+ this.onTimeUpdate();
114
+ });
115
+ } else {
116
+ Util.removeClass(this.root, 'xg-showplay');
117
+ }
118
+ }
119
+
120
+ update(poster) {
121
+ if (!poster) {
122
+ return;
123
+ }
124
+ this.config.poster = poster;
125
+ this.root.style.backgroundImage = `url(${poster})`;
126
+ }
127
+
128
+ setConfig(config: string | IPoster) {
129
+ if (typeof config === 'string') {
130
+ this.config.poster = config;
131
+ } else if (typeof config === 'object') {
132
+ Object.keys(this.config).forEach(key => {
133
+ if (Object.keys(config).includes(key)) {
134
+ this.config[key] = config[key];
135
+ }
136
+ });
137
+ }
138
+ this.update(this.config.poster);
139
+ }
140
+
141
+ getBgSize(mode) {
142
+ let _bg = '';
143
+ switch (mode) {
144
+ case 'cover':
145
+ _bg = 'cover';
146
+ break;
147
+ case 'contain':
148
+ _bg = 'contain';
149
+ break;
150
+ case 'fixHeight':
151
+ _bg = 'auto 100%';
152
+ break;
153
+ case 'fixWidth':
154
+ _bg = '100% auto';
155
+ break;
156
+ default:
157
+ _bg = '';
158
+ }
159
+ return _bg ? `background-size: ${_bg};` : '';
160
+ }
161
+
162
+ render() {
163
+ const { poster, hideCanplay, fillMode, notHidden } = this.config;
164
+ const _bg = this.getBgSize(fillMode);
165
+ const style = poster ? `background-image:url(${poster});${_bg}` : _bg;
166
+ const className = notHidden
167
+ ? 'xg-not-hidden'
168
+ : hideCanplay
169
+ ? 'xg-showplay'
170
+ : '';
171
+ return `<xg-poster class="xgplayer-poster ${className} ${
172
+ poster ? 'active' : ''
173
+ }" style="${style}">
174
+ </xg-poster>`;
175
+ }
176
+ }
177
+
178
+ export default Poster;
@@ -0,0 +1,88 @@
1
+ import { Plugin, Sniffer } from 'xgplayer';
2
+ import RefreshIcon from '../../../assets/icons/pc/refresh.svg';
3
+ import debounce from 'lodash-es/debounce';
4
+ import { PluginEvents } from '@/constants/event';
5
+
6
+ const { POSITIONS } = Plugin;
7
+
8
+ export default class RefreshPlugin extends Plugin {
9
+ static get pluginName() {
10
+ return 'refresh';
11
+ }
12
+
13
+ static get defaultConfig() {
14
+ return {
15
+ position: POSITIONS.CONTROLS_LEFT,
16
+ index: 1,
17
+ };
18
+ }
19
+
20
+ afterCreate() {
21
+ this.appendChild('.xgplayer-icon', (this.icons as any).refresh);
22
+ this.initEvents();
23
+ }
24
+
25
+ registerIcons() {
26
+ return {
27
+ refresh: {
28
+ icon: RefreshIcon,
29
+ class: 'xgplayer-refresh-svg',
30
+ },
31
+ };
32
+ }
33
+
34
+ registerLanguageTexts() {
35
+ return {
36
+ refresh: {
37
+ jp: 'リフレッシュ',
38
+ en: 'Refresh',
39
+ zh: '刷新',
40
+ 'zh-hk': '刷新',
41
+ },
42
+ };
43
+ }
44
+
45
+ initEvents() {
46
+ this.handleRefresh = debounce(this.handleRefresh.bind(this), 200);
47
+ const event = Sniffer.device === 'mobile' ? 'touchend' : 'click';
48
+ this.bind(event, this.handleRefresh);
49
+ this.show();
50
+ }
51
+
52
+ handleRefresh(e: any) {
53
+ const { player } = this;
54
+ if (!player) return;
55
+ e.preventDefault();
56
+ e.stopPropagation();
57
+
58
+ player.addClass('xgplayer-is-enter');
59
+ player.pause();
60
+ player.emit(PluginEvents.REFRESH_CLICK);
61
+
62
+ setTimeout(() => {
63
+ if (player) {
64
+ player.retry();
65
+ }
66
+ player.once('canplay', () => {
67
+ // player.play();
68
+ player.removeClass('xgplayer-is-enter');
69
+ });
70
+ });
71
+ }
72
+
73
+ destroy() {
74
+ this.unbind(['touchend', 'click'], this.handleRefresh);
75
+ }
76
+
77
+ render() {
78
+ return `
79
+ <xg-icon class="xgplayer-refresh">
80
+ <div class="xgplayer-icon">
81
+ </div>
82
+ <div class="xg-tips" lang-key="refresh">${
83
+ (this.langText as any).refresh
84
+ }</div>
85
+ </xg-icon>
86
+ `;
87
+ }
88
+ }
@@ -0,0 +1,62 @@
1
+ import RtsPlayer from '@byted/xgplayer-rts';
2
+ import { IBasePluginOptions } from 'xgplayer/es/plugin/basePlugin';
3
+ import { Sniffer } from 'xgplayer';
4
+ import { isMSESupport } from '@/utils';
5
+ import assign from 'lodash-es/assign';
6
+
7
+ declare global {
8
+ interface Window {
9
+ FlvPlayer?: any;
10
+ HlsPlayer?: any;
11
+ }
12
+ }
13
+
14
+ // 判断降级到 HLS 是否用 MSE
15
+ // 1. pc 端用 MSE
16
+ // 2. 手机端 enableHlsMSE 为 true 且当前设备支持 MSE,用 MSE
17
+ // 3. 手机端其他情况不用 MSE
18
+ function enableFallbackHlsMSE(config) {
19
+ if (Sniffer.device !== 'mobile') {
20
+ return true;
21
+ }
22
+ return config?.enableHlsMSE && isMSESupport();
23
+ }
24
+
25
+ export default class RtmPlugin extends RtsPlayer {
26
+ static get pluginName() {
27
+ return 'rtm';
28
+ }
29
+
30
+ beforeCreate(args: IBasePluginOptions): void {
31
+ const { backupStreamType } = args.player.config.rtm || {};
32
+ const playerMap = {
33
+ flv: window.FlvPlayer,
34
+ hls: window.HlsPlayer,
35
+ };
36
+
37
+ let backupConstruct;
38
+
39
+ // 如果降级到 HLS, 需要判断当前是否用 MSE
40
+ if (
41
+ backupStreamType === 'hls' &&
42
+ enableFallbackHlsMSE(args.player.config)
43
+ ) {
44
+ backupConstruct = playerMap.hls;
45
+ }
46
+
47
+ if (backupStreamType === 'flv') {
48
+ backupConstruct = playerMap.flv;
49
+ }
50
+
51
+ args.player.config.rts = assign({}, args.player.config.rtm, {
52
+ backupConstruct,
53
+ });
54
+ }
55
+
56
+ afterCreate() {
57
+ const { player } = this;
58
+ player.on('degrade', () => {
59
+ player.unRegisterPlugin('rtm');
60
+ });
61
+ }
62
+ }
@@ -0,0 +1,90 @@
1
+ import { Plugin, Util } from 'xgplayer';
2
+
3
+ class ToastPlugin extends Plugin {
4
+ // 插件的名称,将作为插件实例的唯一key值
5
+ static get pluginName() {
6
+ return 'sdkToastPlugin';
7
+ }
8
+
9
+ static get defaultConfig() {
10
+ return {
11
+ index: 5,
12
+ };
13
+ }
14
+
15
+ constructor(args) {
16
+ super(args);
17
+ }
18
+
19
+ private toastNumber = 0;
20
+ private toastMaps: { [key: number]: HTMLElement } = {};
21
+
22
+ beforePlayerInit() {
23
+ // 播放器调用start初始化播放源之前的逻辑
24
+ }
25
+
26
+ afterPlayerInit() {
27
+ // 播放器调用start初始化播放源之后的逻辑
28
+ // this.add('111', 100000, true);
29
+ }
30
+
31
+ afterCreate() {
32
+ //
33
+ }
34
+
35
+ destroy() {
36
+ //
37
+ }
38
+
39
+ add(content: string | HTMLElement, duration = 2000, isNeedCloseBt = false) {
40
+ const id = this.toastNumber + 1;
41
+ this.toastNumber = id;
42
+
43
+ const toast = this.renderToast(content, isNeedCloseBt, id);
44
+ this.root.appendChild(toast);
45
+
46
+ this.toastMaps[id] = toast;
47
+ if (duration) {
48
+ setTimeout(() => {
49
+ this.remove(id);
50
+ }, duration);
51
+ }
52
+
53
+ return id;
54
+ }
55
+
56
+ remove(id: number) {
57
+ const toast = this.toastMaps[id];
58
+ if (toast) {
59
+ if (this.root.contains(toast)) {
60
+ this.root.removeChild(toast);
61
+ }
62
+ delete this.toastMaps[id];
63
+ }
64
+ }
65
+
66
+ renderToast(content: string | HTMLElement, isNeedCloseBt, id) {
67
+ const $toast = Util.createDom('div', '', undefined, 'toast-container');
68
+ const $txt: HTMLElement = Util.checkIsObject(content)
69
+ ? (content as HTMLElement)
70
+ : Util.createDom('div', content as string, undefined, 'toast-txt');
71
+ $toast.appendChild($txt);
72
+
73
+ if (isNeedCloseBt) {
74
+ const $close = Util.createDom('span', '×', undefined, 'toast-close-bt');
75
+
76
+ $close.addEventListener('click', () => {
77
+ this.remove(id);
78
+ });
79
+ $toast.appendChild($close);
80
+ }
81
+
82
+ return $toast;
83
+ }
84
+
85
+ render() {
86
+ return '<xg-sdk-toast class="xgplayer-sdk-toast"></xg-sdk-toast>';
87
+ }
88
+ }
89
+
90
+ export default ToastPlugin;
@@ -0,0 +1,133 @@
1
+ import { PluginEvents } from '@/constants/event';
2
+ import { isRtm, VE_DEBUG } from '@/utils';
3
+ import { Plugin, Sniffer, Util } from 'xgplayer';
4
+
5
+ export default class UnmutePlugin extends Plugin {
6
+ // 插件的名称,将作为插件实例的唯一key值
7
+ static get pluginName() {
8
+ return 'sdkUnmutePlugin';
9
+ }
10
+
11
+ static get defaultConfig() {
12
+ return {
13
+ // 挂载在controls的右侧,如果不指定则默认挂载在播放器根节点上
14
+ position: Plugin.POSITIONS.ROOT,
15
+ };
16
+ }
17
+
18
+ public state = {
19
+ isSupportAutoplay: true,
20
+ showUnmuteBt: false,
21
+ };
22
+
23
+ constructor(args: any) {
24
+ super(args);
25
+ }
26
+
27
+ afterCreate() {
28
+ if (this.player.autoplay && this.player.config.autoplayMuted) {
29
+ this.initEvents();
30
+ }
31
+ }
32
+
33
+ registerLanguageTexts() {
34
+ return {
35
+ unmute: {
36
+ jp: 'ミュートを解除する',
37
+ en: 'Click to unmute',
38
+ zh: '点击取消静音',
39
+ 'zh-hk': '點擊取消靜音',
40
+ },
41
+ };
42
+ }
43
+
44
+ updateLang() {
45
+ this.renderUnmuteBt();
46
+ }
47
+
48
+ initEvents() {
49
+ this.player.once(
50
+ 'autoplay_was_prevented',
51
+ this.handleAutoplayPrevented.bind(this),
52
+ );
53
+ this.player.once('autoplay_started', this.handleAutoplayStart.bind(this));
54
+ this.player.once('volumechange', this.handleVolumechange.bind(this));
55
+ }
56
+
57
+ handleAutoplayPrevented() {
58
+ VE_DEBUG.warn('mute autoplay fail');
59
+ this.state.isSupportAutoplay = false;
60
+ this.player.muted = false;
61
+ }
62
+
63
+ handleAutoplayStart() {
64
+ // 如果之前有不支持自动启播的时候抛出,再次点击播放失败不必展示按钮
65
+ if (!this.state.isSupportAutoplay) {
66
+ this.player.muted = false;
67
+ return;
68
+ }
69
+
70
+ this.state.showUnmuteBt = true;
71
+ this.renderUnmuteBt();
72
+ }
73
+
74
+ handleVolumechange() {
75
+ this.state.showUnmuteBt = false;
76
+ this.renderUnmuteBt();
77
+ if (this.player.paused && this.player.readyState >= 1) {
78
+ this.player.play();
79
+ }
80
+ }
81
+
82
+ renderUnmuteBt() {
83
+ const $unmuteContianer: any = this.root;
84
+ if (!$unmuteContianer) {
85
+ return;
86
+ }
87
+ $unmuteContianer.innerHTML = '';
88
+ if (this.state.showUnmuteBt) {
89
+ const cancelUnmuteText = (this.langText as any).unmute;
90
+ const btn = Util.createDom(
91
+ 'div',
92
+ cancelUnmuteText,
93
+ undefined,
94
+ 'xgplayer-unmute-bt',
95
+ );
96
+ $unmuteContianer.appendChild(btn);
97
+ this.bind('.xgplayer-unmute-bt', 'click', this.cancelUnmute.bind(this));
98
+ }
99
+ }
100
+
101
+ cancelUnmute() {
102
+ this.player.muted = false;
103
+ this.state.showUnmuteBt = false;
104
+ this.renderUnmuteBt();
105
+ // hack 处理鸿蒙播放RTM取消静音后没有声音问题,需要重新设置一遍音量
106
+ if (
107
+ Sniffer.device === 'mobile' &&
108
+ typeof this.player?.config?.url === 'string' &&
109
+ isRtm(this.player?.config?.url)
110
+ ) {
111
+ if (this.player.volume > 0.5) {
112
+ this.player.volume = this.player.volume - 0.1;
113
+ } else {
114
+ this.player.volume = this.player.volume + 0.1;
115
+ }
116
+ }
117
+ this.player.emit(PluginEvents.CANCEL_UNMUTE);
118
+ }
119
+
120
+ destroy() {
121
+ // 播放器销毁的时候一些逻辑
122
+ this.player.off(
123
+ 'autoplay_was_prevented',
124
+ this.handleAutoplayPrevented.bind(this),
125
+ );
126
+ this.player.off('autoplay_started', this.handleAutoplayStart.bind(this));
127
+ this.player.off('volumechange', this.handleVolumechange.bind(this));
128
+ }
129
+
130
+ render() {
131
+ return '<div class="xgplayer-unmute"></div>';
132
+ }
133
+ }
@@ -0,0 +1,80 @@
1
+ // @ts-ignore
2
+ import { Collector } from '#/es/index-base.min.js';
3
+ import VodLogger from '@byted/xgplayer-app-logger/es/logger.js';
4
+ import { REPORT_EVENTS } from '@byted/xgplayer-app-logger/es/constant.js';
5
+ import {
6
+ getCurUserRegionConfig,
7
+ getDrmType,
8
+ VE_DEBUG,
9
+ isMSE,
10
+ getCurrentPlayerSumNum,
11
+ } from '@/utils';
12
+ import { Util } from 'xgplayer';
13
+
14
+ const defaultTeaId = getCurUserRegionConfig()?.__LOG_TEA_ID__;
15
+
16
+ VodLogger.TEA_ID = defaultTeaId;
17
+ VodLogger.Collector = Collector;
18
+
19
+ const xgVodLogger = function (args) {
20
+ if (args && args.player) {
21
+ const onReportLog = async (evtName, params) => {
22
+ const player = args.player;
23
+ VE_DEBUG.log('onReportLog', evtName, { ...params });
24
+ params.player_sum_num = getCurrentPlayerSumNum(player);
25
+ params.is_mse = isMSE(player);
26
+ params.drm_encrypt_type = getDrmType(player) || '';
27
+ params.initial_url = Util.isBlob(params.initial_url)
28
+ ? player.config.url || params.initial_url
29
+ : params.initial_url;
30
+ if (
31
+ evtName === REPORT_EVENTS.ONE_PLAY ||
32
+ evtName === REPORT_EVENTS.ONE_ERROR
33
+ ) {
34
+ // one_play和one_error补充veError信息
35
+ const veError = player?.veError;
36
+ if (params.errc !== 0 && veError) {
37
+ // 有错误时才设置,不然veError可能是上次播放的错误
38
+ params.ve_error_code = veError?.veErrorCode || 0;
39
+ params.ve_error_type = veError?.veErrorType || '';
40
+ params.ve_error_message = veError?.veErrorMessage || '';
41
+ // 上报扩展信息
42
+ params.ve_error_ext = JSON.stringify(veError?.ext || '');
43
+ } else {
44
+ params.ve_error_code = 0;
45
+ params.ve_error_type = '';
46
+ params.ve_error_message = '';
47
+ params.ve_error_ext = '';
48
+ }
49
+ if (import.meta.env.__PLATFORM__ !== 'byteplus') {
50
+ params.licenseStatus = player?.licenseLogInfo?.licenseStatus || '';
51
+ params.licenseType = player?.licenseLogInfo?.licenseType || '';
52
+ }
53
+ }
54
+ VE_DEBUG.log('onReportLog after change', evtName, { ...params });
55
+ };
56
+
57
+ const config = Object.assign(
58
+ {
59
+ onReportLog,
60
+ },
61
+ args.player.config.vodLogOpts || {},
62
+ );
63
+ args.player.vodLogger = new VodLogger(args.player, config);
64
+ args.player.plugins.xgVodLogger = args.player.vodLogger;
65
+ } else {
66
+ this.vodLogger = new VodLogger(this, this.config.vodLogOpts || {});
67
+ }
68
+ };
69
+ xgVodLogger.pluginName = '__xgVodLogger';
70
+ xgVodLogger.playerConfig = {};
71
+ xgVodLogger.Collector = Collector;
72
+ xgVodLogger.setABSdkVersion = value => {
73
+ VodLogger.AB_SDK_VERSION = value;
74
+ };
75
+
76
+ export function setTeaId(id: number) {
77
+ VodLogger.TEA_ID = id;
78
+ }
79
+
80
+ export default xgVodLogger;