@x-edu/live-player 0.0.32 → 0.0.33

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.
Files changed (304) hide show
  1. package/.browserslistrc +10 -10
  2. package/.eslintignore +8 -8
  3. package/.eslintrc.js +26 -26
  4. package/.gem-mine +11 -11
  5. package/.postcssrc.js +6 -6
  6. package/README.md +145 -145
  7. package/babel.config.js +33 -33
  8. package/dist/XEduLivePlayer.common.js +11429 -892
  9. package/dist/XEduLivePlayerPre.common.js +11416 -879
  10. package/doc/develop.md +23 -23
  11. package/gem-mine.config.js +86 -86
  12. package/jest.config.js +9 -9
  13. package/jsconfig.json +15 -15
  14. package/mock/helper.js +8 -8
  15. package/mock/index.js +34 -34
  16. package/package.json +98 -99
  17. package/public/3rd/ali-player/alipayercomponents-1.0.8.min.js +26 -26
  18. package/public/3rd/ali-player/aliplayer-hls-min.js +27 -27
  19. package/public/3rd/ali-player/aliplayer-min.js +1 -1
  20. package/public/3rd/im-web-push/index.umd.js +14 -14
  21. package/public/JsBridge.js +1602 -1602
  22. package/public/fish/editor/themes/default/css/ueditor.css +1905 -1905
  23. package/public/fish/editor/third-party/codemirror/codemirror.css +104 -104
  24. package/public/fish/editor/third-party/codemirror/codemirror.js +3581 -3581
  25. package/public/fish/editor/third-party/zeroclipboard/ZeroClipboard.js +1255 -1255
  26. package/public/fish/editor/ueditor.all.min.js +16 -16
  27. package/public/fish/editor/ueditor.config.js +467 -467
  28. package/public/fish/icon/umd-4.1.2.js +1 -1
  29. package/public/fish/video/videoplayer.min.css +6 -6
  30. package/public/fish/video/videoplayer.min.js +31 -31
  31. package/public/fish/video/zh-CN.js +82 -82
  32. package/public/icon/demo.css +539 -539
  33. package/public/icon/demo_index.html +2189 -2189
  34. package/public/icon/iconfont.css +363 -363
  35. package/public/icon/iconfont.json +618 -618
  36. package/public/index.html +50 -50
  37. package/script/image/readme.md +77 -77
  38. package/script/postcss.js +48 -48
  39. package/src/App.jsx +24 -24
  40. package/src/asset/img/course/playing.svg +21 -21
  41. package/src/asset/img/icon-course-white.svg +3 -3
  42. package/src/asset/img/icon-course.svg +3 -3
  43. package/src/asset/img/icon-eye-white.svg +4 -4
  44. package/src/asset/img/icon-eye.svg +4 -4
  45. package/src/asset/img/icon-school-white.svg +3 -3
  46. package/src/asset/img/icon-school.svg +3 -3
  47. package/src/asset/img/loading.svg +52 -52
  48. package/src/asset/img/video-play.svg +6 -6
  49. package/src/asset/style/background.less +19 -19
  50. package/src/asset/style/banner.less +36 -36
  51. package/src/asset/style/base.less +74 -74
  52. package/src/asset/style/index.less +114 -114
  53. package/src/asset/style/reset-theme.less +141 -141
  54. package/src/asset/style/theme/index.less +55 -55
  55. package/src/asset/style/theme/party/global.less +20 -20
  56. package/src/asset/style/theme/party/override.less +57 -57
  57. package/src/asset/style/theme/test/global.less +18 -18
  58. package/src/asset/style/theme/test/override.less +45 -45
  59. package/src/asset/style/variable.less +12 -12
  60. package/src/component/AliPlayer/index.jsx +49 -49
  61. package/src/component/Avatar/index.jsx +50 -50
  62. package/src/component/Empty/index.jsx +34 -34
  63. package/src/component/Empty/index.module.less +37 -37
  64. package/src/component/IMChatroom/component/status/403.jsx +13 -13
  65. package/src/component/IMChatroom/component/status/404.jsx +13 -13
  66. package/src/component/IMChatroom/component/status/Error.jsx +23 -23
  67. package/src/component/IMChatroom/component/status/Loading.jsx +5 -5
  68. package/src/component/IMChatroom/config/app/config.js +118 -118
  69. package/src/component/IMChatroom/config/app/index.js +60 -60
  70. package/src/component/IMChatroom/config/env.js +5 -5
  71. package/src/component/IMChatroom/config/index.js +3 -3
  72. package/src/component/IMChatroom/config/request/config/base.js +124 -124
  73. package/src/component/IMChatroom/config/request/config/chatroom.js +26 -26
  74. package/src/component/IMChatroom/config/request/config/imCoreApi.js +21 -21
  75. package/src/component/IMChatroom/config/request/index.js +21 -21
  76. package/src/component/IMChatroom/config/request/proxy.js +39 -39
  77. package/src/component/IMChatroom/config/url.js +7 -7
  78. package/src/component/IMChatroom/constants/errorCode.js +9 -9
  79. package/src/component/IMChatroom/constants/index.js +84 -84
  80. package/src/component/IMChatroom/constants/origin.js +27 -27
  81. package/src/component/IMChatroom/context/chatroom.js +154 -154
  82. package/src/component/IMChatroom/context/connect.js +28 -28
  83. package/src/component/IMChatroom/i18n/en/index.json +73 -73
  84. package/src/component/IMChatroom/i18n/index.jsx +14 -14
  85. package/src/component/IMChatroom/i18n/language.js +9 -9
  86. package/src/component/IMChatroom/i18n/zh-CN/index.json +73 -73
  87. package/src/component/IMChatroom/index.jsx +49 -49
  88. package/src/component/IMChatroom/page/chat/index.jsx +27 -27
  89. package/src/component/IMChatroom/page/chat/messageEditor/index.jsx +375 -375
  90. package/src/component/IMChatroom/page/chat/messageList/index.jsx +354 -354
  91. package/src/component/IMChatroom/page/chat/stickedMessage/index.jsx +59 -59
  92. package/src/component/IMChatroom/page/chat/stickedMessage/style/index.module.less +7 -7
  93. package/src/component/IMChatroom/page/chat/style/index.module.less +51 -51
  94. package/src/component/IMChatroom/page/home/connect/index.jsx +188 -188
  95. package/src/component/IMChatroom/page/home/connect/status.jsx +124 -124
  96. package/src/component/IMChatroom/page/home/context/cmd.jsx +37 -37
  97. package/src/component/IMChatroom/page/home/context/index.jsx +67 -67
  98. package/src/component/IMChatroom/page/home/index.jsx +164 -164
  99. package/src/component/IMChatroom/page/home/notice/index.jsx +123 -123
  100. package/src/component/IMChatroom/page/home/notice/style/index.module.less +49 -49
  101. package/src/component/IMChatroom/page/home/style/index.module.less +110 -110
  102. package/src/component/IMChatroom/page/member/index.jsx +15 -15
  103. package/src/component/IMChatroom/page/member/memberCount/index.jsx +44 -44
  104. package/src/component/IMChatroom/page/member/memberList/index.jsx +121 -121
  105. package/src/component/IMChatroom/page/member/style/index.module.less +2 -2
  106. package/src/component/IMChatroom/sdk/bridge.js +39 -39
  107. package/src/component/IMChatroom/sdk/cs/constants.js +20 -20
  108. package/src/component/IMChatroom/sdk/cs/index.js +101 -101
  109. package/src/component/IMChatroom/sdk/imChatroom.js +15 -15
  110. package/src/component/IMChatroom/sdk/imcore/constants.js +128 -128
  111. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomDestroyed.js +5 -5
  112. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomInfoGetFail.js +5 -5
  113. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomKickedByAdmin.js +5 -5
  114. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomKickedBySelf.js +5 -5
  115. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomLoginFail.js +5 -5
  116. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomLoginSuccess.js +5 -5
  117. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomMemberLogin.js +5 -5
  118. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomMemberLogout.js +5 -5
  119. package/src/component/IMChatroom/sdk/imcore/emitters/connectionConnected.js +5 -5
  120. package/src/component/IMChatroom/sdk/imcore/emitters/connectionConnecting.js +5 -5
  121. package/src/component/IMChatroom/sdk/imcore/emitters/connectionDisconnect.js +5 -5
  122. package/src/component/IMChatroom/sdk/imcore/emitters/index.js +57 -57
  123. package/src/component/IMChatroom/sdk/imcore/emitters/messageReceive.js +36 -36
  124. package/src/component/IMChatroom/sdk/imcore/index.js +178 -178
  125. package/src/component/IMChatroom/sdk/imcore/interceptors/request.js +7 -7
  126. package/src/component/IMChatroom/sdk/imcore/interceptors/response.js +5 -5
  127. package/src/component/IMChatroom/sdk/imcore/plugins/getAuth.js +64 -64
  128. package/src/component/IMChatroom/sdk/imcore/plugins/getConversationId.js +20 -20
  129. package/src/component/IMChatroom/sdk/imcore/plugins/getExtInfo.js +10 -10
  130. package/src/component/IMChatroom/sdk/imcore/plugins/getLoginInfo.js +48 -48
  131. package/src/component/IMChatroom/sdk/imcore/plugins/getPlatformType.js +12 -12
  132. package/src/component/IMChatroom/sdk/imcore/plugins/index.js +22 -22
  133. package/src/component/IMChatroom/sdk/imcore/util/format.js +177 -177
  134. package/src/component/IMChatroom/sdk/imcore/util/parser.js +35 -35
  135. package/src/component/IMChatroom/sdk/oms.js +18 -18
  136. package/src/component/IMChatroom/sdk/uc.js +3 -3
  137. package/src/component/IMChatroom/subscription/channel/app.js +5 -5
  138. package/src/component/IMChatroom/subscription/channel/ctl.js +22 -22
  139. package/src/component/IMChatroom/subscription/channel/member.js +40 -40
  140. package/src/component/IMChatroom/subscription/channel/message.js +13 -13
  141. package/src/component/IMChatroom/subscription/channel/ntf.js +86 -86
  142. package/src/component/IMChatroom/subscription/channel/tel.js +5 -5
  143. package/src/component/IMChatroom/subscription/channel/websocket.js +5 -5
  144. package/src/component/IMChatroom/subscription/event.js +37 -37
  145. package/src/component/IMChatroom/subscription/index.js +19 -19
  146. package/src/component/IMChatroom/util/account.js +8 -8
  147. package/src/component/IMChatroom/util/chatroom.js +255 -255
  148. package/src/component/IMChatroom/util/jsonBigInt.js +5 -5
  149. package/src/component/IMChatroom/util/location.js +12 -12
  150. package/src/component/Icon/index.jsx +16 -16
  151. package/src/component/Icon/index.module.less +2 -2
  152. package/src/component/Pagination/LocalPagination.jsx +27 -27
  153. package/src/component/Pagination/RemotePagination.jsx +32 -32
  154. package/src/component/Pagination/index.jsx +32 -32
  155. package/src/component/Pagination/index.module.less +117 -117
  156. package/src/component/PlayerTip/index.jsx +34 -34
  157. package/src/component/VideoBase/index.jsx +242 -242
  158. package/src/component/VideoBase/style.less +65 -65
  159. package/src/component/VideoBase/utils.js +81 -81
  160. package/src/component/mixin.less +9 -9
  161. package/src/component/status/403.jsx +15 -15
  162. package/src/component/status/404/index.jsx +73 -73
  163. package/src/component/status/404/index.module.less +36 -36
  164. package/src/component/status/Error/error.module.less +13 -13
  165. package/src/component/status/Error/index.jsx +47 -47
  166. package/src/component/status/Loading/img/loading.svg +52 -52
  167. package/src/component/status/Loading/index.jsx +31 -31
  168. package/src/component/status/Loading/index.less +56 -56
  169. package/src/component/status/None/index.jsx +20 -20
  170. package/src/component/status/None/index.module.less +35 -35
  171. package/src/component/status/Status/index.jsx +26 -26
  172. package/src/component/status/Status/index.module.less +8 -8
  173. package/src/config/constant/commonUrl.js +2 -2
  174. package/src/config/constant/user.js +6 -6
  175. package/src/config/context/site-config.js +48 -48
  176. package/src/config/env/index.js +5 -5
  177. package/src/config/env/local/index.js +13 -13
  178. package/src/config/env/ncet-xedu/api.js +175 -175
  179. package/src/config/env/ncet-xedu/app.js +12 -12
  180. package/src/config/env/ncet-xedu/cs.js +8 -8
  181. package/src/config/env/ncet-xedu/index.js +14 -14
  182. package/src/config/env/ncet-xedu/push.js +5 -5
  183. package/src/config/env/preproduction/api.js +144 -144
  184. package/src/config/env/preproduction/app.js +12 -12
  185. package/src/config/env/preproduction/cs.js +8 -8
  186. package/src/config/env/preproduction/index.js +14 -14
  187. package/src/config/env/preproduction/push.js +5 -5
  188. package/src/config/env/product/api.js +113 -113
  189. package/src/config/env/product/app.js +12 -12
  190. package/src/config/env/product/cs.js +5 -5
  191. package/src/config/env/product/index.js +14 -14
  192. package/src/config/env/product/push.js +5 -5
  193. package/src/config/live.js +80 -80
  194. package/src/config/publicLive.js +53 -53
  195. package/src/config/request/assessments.js +24 -24
  196. package/src/config/request/config-center.js +8 -8
  197. package/src/config/request/helper.js +190 -166
  198. package/src/config/request/im-broadcasts.js +12 -12
  199. package/src/config/request/live-activity-gateway.js +8 -8
  200. package/src/config/request/live-activity.js +13 -13
  201. package/src/config/request/raw.js +6 -6
  202. package/src/config/request/x-cloud-web.js +13 -13
  203. package/src/config/request/x-proxy.js +34 -34
  204. package/src/demo/Detail.jsx +11 -11
  205. package/src/demo/List.jsx +68 -68
  206. package/src/demo/index.jsx +17 -17
  207. package/src/detail/LineSwitch/index.jsx +71 -71
  208. package/src/detail/LiveCountDown/index.jsx +44 -44
  209. package/src/detail/LiveCountDown/index.module.less +31 -31
  210. package/src/detail/LiveOnlineCount/img/icon.svg +15 -15
  211. package/src/detail/LiveOnlineCount/index.jsx +68 -68
  212. package/src/detail/LiveOnlineCount/index.module.less +34 -34
  213. package/src/detail/LiveOnlineCount/util.js +74 -74
  214. package/src/detail/LiveStatus/AnchorOnTheWay.jsx +88 -88
  215. package/src/detail/LiveStatus/index.jsx +202 -202
  216. package/src/detail/LiveStatus/index.module.less +192 -192
  217. package/src/detail/LiveVideo/config.js +37 -37
  218. package/src/detail/LiveVideo/index.jsx +188 -188
  219. package/src/detail/LiveVideo/index.module.less +41 -41
  220. package/src/detail/NotLoginChatroom/index.jsx +37 -37
  221. package/src/detail/NotLoginChatroom/index.module.less +46 -46
  222. package/src/detail/RecordVideo/index.jsx +150 -150
  223. package/src/detail/RecordVideo/index.module.less +31 -31
  224. package/src/detail/ReplayVideo/index.jsx +93 -93
  225. package/src/detail/ReplayVideo/index.module.less +65 -65
  226. package/src/detail/const.js +20 -20
  227. package/src/detail/hook/usePullSource.js +82 -82
  228. package/src/detail/hook/usePullState.js +51 -51
  229. package/src/detail/index.jsx +483 -482
  230. package/src/detail/index.module.less +188 -188
  231. package/src/hook/useAsync.js +84 -84
  232. package/src/hook/useGoToPage.js +83 -83
  233. package/src/hook/useInterval.js +28 -28
  234. package/src/hook/useIsMounted.js +17 -17
  235. package/src/hook/useModuleByRole.js +53 -53
  236. package/src/hook/usePageScrollable.js +52 -52
  237. package/src/hook/usePortal.js +83 -83
  238. package/src/hook/useScrollRestore/index.js +32 -32
  239. package/src/hook/useScrollRestore/scrollContext.js +20 -20
  240. package/src/hook/useTrackRef.js +11 -11
  241. package/src/hook/useWindowSize.js +28 -28
  242. package/src/hook/useZoom.js +47 -47
  243. package/src/index.js +10 -10
  244. package/src/lib/getLiveOnlineCount.js +10 -10
  245. package/src/lib/getServiceConfig.js +102 -102
  246. package/src/list/Empty/index.jsx +20 -20
  247. package/src/list/Empty/index.module.less +23 -23
  248. package/src/list/ListItem/Action/index.jsx +109 -109
  249. package/src/list/ListItem/Action/index.module.less +25 -25
  250. package/src/list/ListItem/img/dianzan.svg +4 -4
  251. package/src/list/ListItem/img/like-fill.svg +8 -8
  252. package/src/list/ListItem/img/play.svg +15 -15
  253. package/src/list/ListItem/img/view-fill.svg +8 -8
  254. package/src/list/ListItem/img/yiguankan.svg +3 -3
  255. package/src/list/ListItem/index.module.less +158 -158
  256. package/src/list/index.jsx +241 -240
  257. package/src/list/index.module.less +38 -38
  258. package/src/service/common.js +73 -73
  259. package/src/service/content-mgr.js +73 -73
  260. package/src/service/im-group.js +12 -12
  261. package/src/service/im.js +7 -7
  262. package/src/service/imBroadcasts.js +33 -33
  263. package/src/service/like.js +134 -134
  264. package/src/service/live.js +293 -293
  265. package/src/service/manageApi.js +7 -7
  266. package/src/service/managePortal.js +6 -6
  267. package/src/service/myStudyRecord.js +93 -93
  268. package/src/service/navigation.js +47 -47
  269. package/src/service/ndMeeting.js +10 -10
  270. package/src/service/ndr.js +122 -122
  271. package/src/service/news.js +93 -93
  272. package/src/service/personalCenter.js +270 -270
  273. package/src/service/qualityCourse.js +31 -31
  274. package/src/service/recommend.js +81 -81
  275. package/src/service/school.js +323 -323
  276. package/src/service/search.js +170 -170
  277. package/src/service/site-config.js +7 -7
  278. package/src/service/socialCensor.js +45 -45
  279. package/src/service/specialEdu.js +31 -31
  280. package/src/service/suggestion.js +85 -85
  281. package/src/service/syncClassroom.js +321 -321
  282. package/src/service/tCourse.js +204 -204
  283. package/src/service/tchTraining.js +37 -37
  284. package/src/service/uc.js +45 -45
  285. package/src/util/app.js +1 -1
  286. package/src/util/array.js +3 -3
  287. package/src/util/auth/func.js +57 -57
  288. package/src/util/date.js +53 -53
  289. package/src/util/env.js +9 -9
  290. package/src/util/getTimestamp.js +10 -10
  291. package/src/util/hof.js +105 -105
  292. package/src/util/live/index.js +42 -42
  293. package/src/util/liveCountUtil.js +52 -52
  294. package/src/util/netUrl.js +35 -35
  295. package/src/util/object.js +13 -13
  296. package/src/util/push/index.js +58 -58
  297. package/src/util/request.js +227 -227
  298. package/src/util/type.js +17 -17
  299. package/src/util/url.js +203 -203
  300. package/src/util/video.js +26 -26
  301. package/test/setup.js +21 -21
  302. package/test/unit/component/header/logo.spec.jsx +8 -8
  303. package/test/unit/helper.jsx +25 -25
  304. package/test/unit/util/date.spec.js +40 -40
@@ -1,482 +1,483 @@
1
- /* eslint-disable camelcase */
2
- import React, { useState, useEffect } from 'react'
3
- import { Icon } from 'fish'
4
- import dayjs from 'dayjs'
5
- import classNames from 'classnames'
6
- // import Empty from '@/component/Empty'
7
- import {
8
- getOpenClassLive
9
- // getServerTime
10
- } from '@/service/live'
11
- import { getIMLiveInfo, getGuestIMLiveInfo } from '@/service/imBroadcasts'
12
- import Loading from '@/component/status/Loading'
13
- import {
14
- PUBLIC_LIVE_STATUS, PUBLIC_LIVE_MODE, SUB_TYPE
15
- } from '@/config/publicLive'
16
- import { getUrlQuery } from '@/util/url'
17
- import { getRecordLiveStatus } from '@/util/live'
18
- import { isEmpty } from '@/util/object'
19
- // import IMChatroom from '@/component/IMChatroom'
20
- import RecordVideo from './RecordVideo'
21
- import LiveVideo from './LiveVideo'
22
- import LineSwitch from './LineSwitch'
23
- import ReplayVideo from './ReplayVideo'
24
- import style from './index.module.less'
25
- import LiveOnlineCount from './LiveOnlineCount'
26
- import { LOGIN_STATUS } from '@/config/constant/user'
27
- import { USER_IDENTITY_NAME } from '@/config/live'
28
- // import NotLoginChatroom from './NotLoginChatroom'
29
- import netUrl from '@/util/netUrl'
30
- import { ShortUrlMap } from './const'
31
- import { setUC } from '@/util/auth/func'
32
- import config from '@/config/env'
33
-
34
- const TrackPageName = 'edu_Platform_publiclive_detail_page'
35
-
36
- export default function PublicLiveDetail({
37
- containerClassName,
38
- className,
39
- infoClassName,
40
- playerClassName,
41
- descriptionClassName,
42
- errorCover, // 当直播不存在或者错误时候的封面展示
43
- errorText,
44
- replay: propRelay,
45
- liveId: propLiveId,
46
- sdpAppId: propSdpAppId,
47
- uc,
48
- loginInfo = {},
49
- handleLogin,
50
- onOnlineCountChange = () => {},
51
- onStateChange = () => {},
52
- onReportProgress = () => {},
53
- onReportTeacherTrain = () => {},
54
- onSendSensors = () => {}
55
- }) {
56
- setUC(uc, loginInfo?.userInfo)
57
- if (propSdpAppId) {
58
- config.app.appid = propSdpAppId
59
- }
60
-
61
- const { replay, live_id } = getUrlQuery()
62
- const matchId = propLiveId || live_id
63
- const replayMode = propRelay || replay
64
- const liveId = ShortUrlMap[matchId] || matchId
65
-
66
- const [liveInfo, setLiveInfo] = useState()
67
- const [visitTime, setVisitTime] = useState()
68
- const [diffTime, setDiffTime] = useState()
69
- const [isReplayMode, setIsReplayMode] = useState(!!replayMode)
70
- const [isExist, setIsExist] = useState(true)
71
- const [lineChanging, setLineChanging] = useState(false) // 线路切换中标识
72
-
73
- const {
74
- userInfo,
75
- userRole,
76
- loginStatus
77
- } = loginInfo
78
- const isLiveToReplay = !replay
79
- const isStreamLive = liveInfo
80
- && liveInfo.type === PUBLIC_LIVE_MODE.LIVING
81
-
82
- const handleStatusChange = async (status) => {
83
- const newLiveInfo = {
84
- ...liveInfo,
85
- status
86
- }
87
- setLiveInfo(newLiveInfo)
88
- onStateChange(newLiveInfo)
89
- const isRecordLive = liveInfo.type === PUBLIC_LIVE_MODE.RECORDED
90
- if (!isRecordLive
91
- && [
92
- PUBLIC_LIVE_STATUS.NOSTARTED,
93
- PUBLIC_LIVE_STATUS.LIVEING,
94
- PUBLIC_LIVE_STATUS.PASUED
95
- ].includes(status)
96
- && isEmpty(liveInfo.imInfo)
97
- ) {
98
- const {
99
- sub_type: subType,
100
- bid,
101
- room_id: roomId
102
- } = liveInfo
103
- let imLiveInfoResp = {}
104
- // 如果类型为外部推流, 则去请求新的直播详情接口
105
- if (subType === SUB_TYPE.OUTSIDE || subType === SUB_TYPE.REBROADCAST) {
106
- imLiveInfoResp = await getGuestIMLiveInfo(bid)
107
- .catch(() => ({}))
108
-
109
- // 默认使用lines[0] 作为直播源
110
- imLiveInfoResp = {
111
- ...imLiveInfoResp,
112
- param: {
113
- ...imLiveInfoResp.param,
114
- ...imLiveInfoResp.param?.lines?.[0]
115
- }
116
- }
117
- } else {
118
- imLiveInfoResp = await getIMLiveInfo(roomId)
119
- .catch(() => ({}))
120
- }
121
- setLiveInfo({
122
- ...liveInfo,
123
- status,
124
- imInfo: imLiveInfoResp
125
- })
126
- }
127
- }
128
-
129
- const handleSelectChange = (lineSource) => {
130
- setLineChanging(true)
131
- setTimeout(() => {
132
- setLiveInfo({
133
- ...liveInfo,
134
- imInfo: {
135
- ...liveInfo.imInfo,
136
- param: {
137
- ...liveInfo.imInfo.param,
138
- ...lineSource
139
- }
140
- }
141
- })
142
- setLineChanging(false)
143
- }, 0)
144
- }
145
-
146
- useEffect(() => {
147
- const init = async () => {
148
- const [data, error] = await getOpenClassLive(liveId)
149
- .then((v) => [v], (err) => [null, err])
150
- if (error) {
151
- const { response } = error
152
- if (response.status === 404 || response.status === 400) {
153
- setIsExist(false)
154
- }
155
- return
156
- }
157
-
158
- // 调试代码 模拟直播倒计时结束
159
- // data.status = PUBLIC_LIVE_STATUS.NOSTARTED
160
-
161
- const isRecordLive = data.type === PUBLIC_LIVE_MODE.RECORDED
162
- const isNoStarted = data.status === PUBLIC_LIVE_STATUS.NOSTARTED
163
- const isCompleted = data.status === PUBLIC_LIVE_STATUS.COMPLETEED
164
- const isOffline = data.status === PUBLIC_LIVE_STATUS.OFFLINE
165
-
166
- // 录播未完成或未下架,直播未开始时需要服务器时间
167
- let serverTime
168
- if ((isRecordLive && (!isCompleted || !isOffline)) || (!isRecordLive && !isReplayMode && isNoStarted)) {
169
- // const response = await getServerTime()
170
- serverTime = data.serverTime
171
- setDiffTime(data.diffTime)
172
- setVisitTime(serverTime)
173
- }
174
- // 录播计算状态
175
- if (isRecordLive) {
176
- const status = getRecordLiveStatus(data.status, serverTime, data.begin_time, data.end_time)
177
- data.status = status
178
- }
179
- if (!isRecordLive) {
180
- const {
181
- sub_type: subType,
182
- bid,
183
- room_id: roomId
184
- } = data
185
- let imLiveInfoResp = {}
186
- // 如果类型为外部推流, 则去请求新的直播详情接口
187
- if (subType === SUB_TYPE.OUTSIDE || subType === SUB_TYPE.REBROADCAST) {
188
- // if (subType === SUB_TYPE.OUTSIDE) {
189
- imLiveInfoResp = await getGuestIMLiveInfo(bid)
190
- .catch(() => ({}))
191
- // 默认使用lines[0] 作为直播源
192
- imLiveInfoResp = {
193
- ...imLiveInfoResp,
194
- param: {
195
- ...imLiveInfoResp.param,
196
- ...imLiveInfoResp.param?.lines?.[0]
197
- }
198
- }
199
- } else if (data.status === PUBLIC_LIVE_STATUS.LIVEING) {
200
- imLiveInfoResp = await getIMLiveInfo(roomId)
201
- .catch(() => ({}))
202
- }
203
- data.imInfo = imLiveInfoResp
204
- }
205
- // 如果是转播或者是推流 直接播放(用于调试模式)
206
- const { preview } = getUrlQuery() // 后台点预览会加这个参数
207
- const generateInfo = preview ? Object.assign(data, {
208
- status: 1
209
- }) : data
210
- setLiveInfo(generateInfo)
211
- }
212
- init()
213
- }, [])
214
-
215
- useEffect(() => {
216
- if (userInfo) {
217
- onReportProgress()
218
- }
219
- }, [userInfo])
220
-
221
- useEffect(() => {
222
- if (loginStatus !== LOGIN_STATUS.WAIT && liveInfo) {
223
- onSendSensors({
224
- pageName: TrackPageName,
225
- eventName: 'edu_Platform_publiclive_detail_page',
226
- params: {
227
- publiclive_id: liveInfo.live_id,
228
- publiclive_name: liveInfo.live_name,
229
- // 1-直播, 2-录播
230
- publiclive_type: liveInfo.type === 1 ? '实时直播' : '录播直播',
231
- identity: userRole
232
- ? USER_IDENTITY_NAME[userRole]
233
- : '游客'
234
- }
235
- })
236
- }
237
- }, [!!userRole, !!liveInfo, loginStatus])
238
-
239
- if (!isExist) {
240
- return (
241
- <div
242
- className={classNames(
243
- style['public-live-detail-wrapper'],
244
- style['live-empty'],
245
- containerClassName
246
- )}
247
- style={{
248
- backgroundImage: `url(${errorCover})`
249
- }}
250
- >
251
- <div className={style['empty-marker']} />
252
- <div className={style['empty-content']}>
253
- {/* eslint-disable-next-line max-len */}
254
- <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAALOSURBVHgB7VqLbeMwDGVugctt4BEygje4bFBv0G5y2SC5Rc4jpBNEneDaLtBXCVIA16asL50U8AMEA7ZF6pG0PqSJVqxYIYkNCQHAVl8a3Xa6/dTt1+Dxs25v5rrZbN7o3qHJtLoddDsjHmfXp6V7gvGMbo+JZHxQuj3QraEHsXeDqQ11E4JaaaNbD3kcjS5aAlrRDmEvmefmu+lgjbAd9N86GXv3ToysHUlCK3hA2MItJcIRPQVky4RmgFSPCiED693TYuScRX14osowMnV79eirE5bOimqG2JEEMKNX1YgOQjj2b0GupxLAzmqxkCJnPgMuLPeUC4+1TPyfFib3xOhSGCwjKcK6uYHfgFzP6EqfuMB7qxm9sxg52O9tjHOqkDZ2sAuT43S1KQIOjIBdosLq5DwGP6QIGB9BVESfpcipkfy4cITdpGZZZQly4KMpPDt63P2bIiFNDvxsHd5mwR4n0jt+lSFGDvzs2I3f+8H05Ui8UAJ0gqbTl7/Mo64COS75MwlFjtgEOZkkKXKeseQRKxhER3KemwVHbGIR5OzJHGqTix1LFDFiXJ2CyuQa5t5kLeOIPTP3WipERXINc++dQkDBAh2D0qUAuQu065y8pUpBCTnkbqlcZ84qLVVEDjnwSaWkTXD0saUEqeRQemxxQrgiQ0OVEUsO/FbqQqkAn2coyw75dQXJed5JT6DCzo6KEVY9QUo0Tw62TFXurYEybqdvUmEiRQLE5TDzvTVS1jNCFYTKO1gqQQvpVDOvc47cpZpe+LOx5p5EUeLRQ+oDtT8DzKe7j6hXRupnSHUkAYRz+ccci8JuCObC778YqcEgUkq1e/f+uFTbOCPFlGovkC7VDgbXIG1qzoEJvX9Yqrg+ImisrlAXhpDxUn6Z6M4IXj1kZsSiE3t1IP+Xoz+ofCyS/knMfPTX6xWvZI/yJgXx8i1+EluxYsUEn1PRdSb/XhDOAAAAAElFTkSuQmCC" alt="" />
255
- <p>{errorText || '内容已失效'}</p>
256
- </div>
257
-
258
- </div>
259
- )
260
- }
261
-
262
- if (!liveInfo) {
263
- return <Loading />
264
- }
265
-
266
- const isRecordLive = liveInfo.type === PUBLIC_LIVE_MODE.RECORDED
267
- const beginTime = dayjs(liveInfo.begin_time)
268
-
269
- const handlePlayReplay = (needReport) => {
270
- if (needReport) {
271
- onSendSensors({
272
- pageName: TrackPageName,
273
- eventName: 'edu_Platform_publiclive_detail_replay_click',
274
- params: {
275
- publiclive_id: liveInfo.live_id,
276
- publiclive_name: liveInfo.live_name,
277
- // 1-直播, 2-录播
278
- publiclive_type: liveInfo.type === 1 ? '实时直播' : '录播直播'
279
- }
280
- })
281
- }
282
-
283
- setIsReplayMode(true)
284
- }
285
-
286
- const handleRequestFullScreen = () => {
287
- onSendSensors({
288
- pageName: TrackPageName,
289
- eventName: 'edu_Platform_publiclive_detail_fullscreen_click'
290
- })
291
- }
292
-
293
- const handleVideoPlay = (needReport) => {
294
- if (needReport) {
295
- onSendSensors({
296
- pageName: TrackPageName,
297
- eventName: 'edu_Platform_publiclive_detail_play_click',
298
- params: {
299
- publiclive_id: liveInfo.live_id,
300
- publiclive_name: liveInfo.live_name,
301
- // 1-直播, 2-录播
302
- publiclive_type: liveInfo.type === 1 ? '实时直播' : '录播直播'
303
- }
304
- })
305
- }
306
- if (userInfo) {
307
- // 登录且播放后上报
308
- onReportTeacherTrain(userInfo?.user_id, liveId)
309
- }
310
- }
311
-
312
- return (
313
- <>
314
- <div
315
- className={classNames(
316
- style['public-live-detail-wrapper'],
317
- containerClassName
318
- )}
319
- >
320
- <div
321
- className={classNames(
322
- className, style['live-panel']
323
- )}
324
- >
325
- <div className={infoClassName}>
326
-
327
- <div className={style['live-title']}>
328
- <div className={style['live-name']}>
329
- {liveInfo.live_name}
330
- </div>
331
- {
332
- // eslint-disable-next-line no-nested-ternary
333
- liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
334
- ? (
335
- <LiveOnlineCount
336
- className={style['live-online-count']}
337
- resId={liveId}
338
- onOnlineCountChange={onOnlineCountChange}
339
- />
340
- )
341
- : (
342
- liveInfo.status === PUBLIC_LIVE_STATUS.COMPLETEED
343
- ? (<div className={style['live-end']}>已结束</div>)
344
- : (<></>)
345
- )
346
- }
347
- </div>
348
- <div className={style['live-info']}>
349
- {/*
350
- 暂时隐藏主播
351
- <div className={classNames(style['live-user'], {
352
- [style['empty-user']]: !liveInfo.lecture_user_id && !liveInfo.lecture_user_name
353
- })}
354
- >
355
- <Avatar className={style.avatar} src={getAvatarURL(liveInfo.lecture_user_id)} />
356
- <span title={liveInfo.lecture_user_name}>{liveInfo.lecture_user_name}</span>
357
- </div> */
358
- }
359
- <div className={style['live-time']}>
360
- <Icon
361
- className={style['icon-time']}
362
- type="clock-circle"
363
- />
364
- <span>
365
- {`${beginTime.format(beginTime.isSame(dayjs(), 'day') ? '[今天] HH:mm' : 'YYYY-MM-DD HH:mm')} 开始`}
366
- </span>
367
- </div>
368
- </div>
369
- </div>
370
- <div
371
- className={classNames(style['live-video-wrapper'], playerClassName)}
372
- >
373
- <div className={style['live-wrap']}>
374
- {
375
- // eslint-disable-next-line no-nested-ternary
376
- isReplayMode
377
- ? (
378
- <ReplayVideo
379
- handleLogin={handleLogin}
380
- liveInfo={liveInfo}
381
- autoplay={isLiveToReplay}
382
- onVideoPlay={() => {
383
- handleVideoPlay(false)
384
- }}
385
- onRequestFullScreen={handleRequestFullScreen}
386
- />
387
- )
388
- : isRecordLive
389
- ? (
390
- <RecordVideo
391
- isStreamLive={isStreamLive}
392
- userInfo={userInfo}
393
- liveInfo={liveInfo}
394
- visitTime={visitTime}
395
- diffTime={diffTime}
396
- onStatusChange={handleStatusChange}
397
- onPlayReplay={() => {
398
- handlePlayReplay(true)
399
- }}
400
- onVideoPlay={() => {
401
- handleVideoPlay(true)
402
- }}
403
- onRequestFullScreen={handleRequestFullScreen}
404
- />
405
- )
406
- : (
407
- <LiveVideo
408
- isStreamLive={isStreamLive}
409
- handleLogin={handleLogin}
410
- userInfo={userInfo}
411
- liveInfo={liveInfo}
412
- visitTime={visitTime}
413
- lineChanging={lineChanging}
414
- onStatusChange={handleStatusChange}
415
- onPlayReplay={() => {
416
- handlePlayReplay(true)
417
- }}
418
- onVideoPlay={() => {
419
- handleVideoPlay(true)
420
- }}
421
- onRequestFullScreen={handleRequestFullScreen}
422
- />
423
- )
424
- }
425
- {/* {
426
- liveInfo?.chat_type && (
427
- <div className={style['chatroom-wrap']}>
428
- <div className={style['chatroom-title']}>
429
- 讨论区
430
- </div>
431
- {
432
- userInfo ? (
433
- <>
434
- <div className={style['chatroom-top-hint']}>
435
- 系统提示:倡导建康的直播环境,若发布违法、违规、低俗等不良消息,我们会对违规内容及帐号进行封禁处理。
436
- </div>
437
- <IMChatroom
438
- roomId={liveInfo.chat_room_id}
439
- disableEditor={!liveInfo.chat_enabled}
440
- />
441
- </>
442
- ) : (
443
- <NotLoginChatroom
444
- handleLogin={handleLogin}
445
- />
446
- )
447
- }
448
- </div>
449
- )
450
- } */}
451
- </div>
452
- {
453
- !isReplayMode && !isRecordLive
454
- && liveInfo.sub_type !== SUB_TYPE.NET_DRAGON
455
- && liveInfo.status !== PUBLIC_LIVE_STATUS.COMPLETEED
456
- && (
457
- <LineSwitch
458
- className={style['live-line-switch']}
459
- liveInfo={liveInfo}
460
- onChange={handleSelectChange}
461
- />
462
- )
463
- }
464
- </div>
465
- </div>
466
- <div
467
- className={classNames(
468
- style['live-description-panel'],
469
- descriptionClassName
470
- )}
471
- >
472
- <div className={style['desc-title']}>开播介绍</div>
473
- <div className={style['desc-content']}>
474
- {!liveInfo.desc_pic_web_url ? '暂无介绍' : (
475
- <img className={style['desc-content-img']} src={netUrl(liveInfo.desc_pic_web_url)} alt="" />
476
- )}
477
- </div>
478
- </div>
479
- </div>
480
- </>
481
- )
482
- }
1
+ /* eslint-disable camelcase */
2
+ import React, { useState, useEffect } from 'react'
3
+ import { Icon } from 'fish'
4
+ import dayjs from 'dayjs'
5
+ import classNames from 'classnames'
6
+ // import Empty from '@/component/Empty'
7
+ import {
8
+ getOpenClassLive
9
+ // getServerTime
10
+ } from '@/service/live'
11
+ import { getIMLiveInfo, getGuestIMLiveInfo } from '@/service/imBroadcasts'
12
+ import Loading from '@/component/status/Loading'
13
+ import {
14
+ PUBLIC_LIVE_STATUS, PUBLIC_LIVE_MODE, SUB_TYPE
15
+ } from '@/config/publicLive'
16
+ import { getUrlQuery } from '@/util/url'
17
+ import { getRecordLiveStatus } from '@/util/live'
18
+ import { isEmpty } from '@/util/object'
19
+ // import IMChatroom from '@/component/IMChatroom'
20
+ import RecordVideo from './RecordVideo'
21
+ import LiveVideo from './LiveVideo'
22
+ import LineSwitch from './LineSwitch'
23
+ import ReplayVideo from './ReplayVideo'
24
+ import style from './index.module.less'
25
+ import LiveOnlineCount from './LiveOnlineCount'
26
+ import { LOGIN_STATUS } from '@/config/constant/user'
27
+ import { USER_IDENTITY_NAME } from '@/config/live'
28
+ // import NotLoginChatroom from './NotLoginChatroom'
29
+ import netUrl from '@/util/netUrl'
30
+ import { ShortUrlMap } from './const'
31
+ import { setUC } from '@/util/auth/func'
32
+ import config from '@/config/env'
33
+
34
+ const TrackPageName = 'edu_Platform_publiclive_detail_page'
35
+
36
+ export default function PublicLiveDetail({
37
+ containerClassName,
38
+ className,
39
+ infoClassName,
40
+ playerClassName,
41
+ descriptionClassName,
42
+ errorCover, // 当直播不存在或者错误时候的封面展示
43
+ errorText,
44
+ replay: propRelay,
45
+ liveId: propLiveId,
46
+ sdpAppId: propSdpAppId,
47
+ uc,
48
+ loginInfo = {},
49
+ handleLogin,
50
+ onOnlineCountChange = () => {},
51
+ onStateChange = () => {},
52
+ onReportProgress = () => {},
53
+ onReportTeacherTrain = () => {},
54
+ onSendSensors = () => {}
55
+ }) {
56
+ setUC(uc, loginInfo?.userInfo)
57
+ if (propSdpAppId) {
58
+ config.app.appid = propSdpAppId
59
+ window._propSdpAppId = propSdpAppId
60
+ }
61
+
62
+ const { replay, live_id } = getUrlQuery()
63
+ const matchId = propLiveId || live_id
64
+ const replayMode = propRelay || replay
65
+ const liveId = ShortUrlMap[matchId] || matchId
66
+
67
+ const [liveInfo, setLiveInfo] = useState()
68
+ const [visitTime, setVisitTime] = useState()
69
+ const [diffTime, setDiffTime] = useState()
70
+ const [isReplayMode, setIsReplayMode] = useState(!!replayMode)
71
+ const [isExist, setIsExist] = useState(true)
72
+ const [lineChanging, setLineChanging] = useState(false) // 线路切换中标识
73
+
74
+ const {
75
+ userInfo,
76
+ userRole,
77
+ loginStatus
78
+ } = loginInfo
79
+ const isLiveToReplay = !replay
80
+ const isStreamLive = liveInfo
81
+ && liveInfo.type === PUBLIC_LIVE_MODE.LIVING
82
+
83
+ const handleStatusChange = async (status) => {
84
+ const newLiveInfo = {
85
+ ...liveInfo,
86
+ status
87
+ }
88
+ setLiveInfo(newLiveInfo)
89
+ onStateChange(newLiveInfo)
90
+ const isRecordLive = liveInfo.type === PUBLIC_LIVE_MODE.RECORDED
91
+ if (!isRecordLive
92
+ && [
93
+ PUBLIC_LIVE_STATUS.NOSTARTED,
94
+ PUBLIC_LIVE_STATUS.LIVEING,
95
+ PUBLIC_LIVE_STATUS.PASUED
96
+ ].includes(status)
97
+ && isEmpty(liveInfo.imInfo)
98
+ ) {
99
+ const {
100
+ sub_type: subType,
101
+ bid,
102
+ room_id: roomId
103
+ } = liveInfo
104
+ let imLiveInfoResp = {}
105
+ // 如果类型为外部推流, 则去请求新的直播详情接口
106
+ if (subType === SUB_TYPE.OUTSIDE || subType === SUB_TYPE.REBROADCAST) {
107
+ imLiveInfoResp = await getGuestIMLiveInfo(bid)
108
+ .catch(() => ({}))
109
+
110
+ // 默认使用lines[0] 作为直播源
111
+ imLiveInfoResp = {
112
+ ...imLiveInfoResp,
113
+ param: {
114
+ ...imLiveInfoResp.param,
115
+ ...imLiveInfoResp.param?.lines?.[0]
116
+ }
117
+ }
118
+ } else {
119
+ imLiveInfoResp = await getIMLiveInfo(roomId)
120
+ .catch(() => ({}))
121
+ }
122
+ setLiveInfo({
123
+ ...liveInfo,
124
+ status,
125
+ imInfo: imLiveInfoResp
126
+ })
127
+ }
128
+ }
129
+
130
+ const handleSelectChange = (lineSource) => {
131
+ setLineChanging(true)
132
+ setTimeout(() => {
133
+ setLiveInfo({
134
+ ...liveInfo,
135
+ imInfo: {
136
+ ...liveInfo.imInfo,
137
+ param: {
138
+ ...liveInfo.imInfo.param,
139
+ ...lineSource
140
+ }
141
+ }
142
+ })
143
+ setLineChanging(false)
144
+ }, 0)
145
+ }
146
+
147
+ useEffect(() => {
148
+ const init = async () => {
149
+ const [data, error] = await getOpenClassLive(liveId)
150
+ .then((v) => [v], (err) => [null, err])
151
+ if (error) {
152
+ const { response } = error
153
+ if (response.status === 404 || response.status === 400) {
154
+ setIsExist(false)
155
+ }
156
+ return
157
+ }
158
+
159
+ // 调试代码 模拟直播倒计时结束
160
+ // data.status = PUBLIC_LIVE_STATUS.NOSTARTED
161
+
162
+ const isRecordLive = data.type === PUBLIC_LIVE_MODE.RECORDED
163
+ const isNoStarted = data.status === PUBLIC_LIVE_STATUS.NOSTARTED
164
+ const isCompleted = data.status === PUBLIC_LIVE_STATUS.COMPLETEED
165
+ const isOffline = data.status === PUBLIC_LIVE_STATUS.OFFLINE
166
+
167
+ // 录播未完成或未下架,直播未开始时需要服务器时间
168
+ let serverTime
169
+ if ((isRecordLive && (!isCompleted || !isOffline)) || (!isRecordLive && !isReplayMode && isNoStarted)) {
170
+ // const response = await getServerTime()
171
+ serverTime = data.serverTime
172
+ setDiffTime(data.diffTime)
173
+ setVisitTime(serverTime)
174
+ }
175
+ // 录播计算状态
176
+ if (isRecordLive) {
177
+ const status = getRecordLiveStatus(data.status, serverTime, data.begin_time, data.end_time)
178
+ data.status = status
179
+ }
180
+ if (!isRecordLive) {
181
+ const {
182
+ sub_type: subType,
183
+ bid,
184
+ room_id: roomId
185
+ } = data
186
+ let imLiveInfoResp = {}
187
+ // 如果类型为外部推流, 则去请求新的直播详情接口
188
+ if (subType === SUB_TYPE.OUTSIDE || subType === SUB_TYPE.REBROADCAST) {
189
+ // if (subType === SUB_TYPE.OUTSIDE) {
190
+ imLiveInfoResp = await getGuestIMLiveInfo(bid)
191
+ .catch(() => ({}))
192
+ // 默认使用lines[0] 作为直播源
193
+ imLiveInfoResp = {
194
+ ...imLiveInfoResp,
195
+ param: {
196
+ ...imLiveInfoResp.param,
197
+ ...imLiveInfoResp.param?.lines?.[0]
198
+ }
199
+ }
200
+ } else if (data.status === PUBLIC_LIVE_STATUS.LIVEING) {
201
+ imLiveInfoResp = await getIMLiveInfo(roomId)
202
+ .catch(() => ({}))
203
+ }
204
+ data.imInfo = imLiveInfoResp
205
+ }
206
+ // 如果是转播或者是推流 直接播放(用于调试模式)
207
+ const { preview } = getUrlQuery() // 后台点预览会加这个参数
208
+ const generateInfo = preview ? Object.assign(data, {
209
+ status: 1
210
+ }) : data
211
+ setLiveInfo(generateInfo)
212
+ }
213
+ init()
214
+ }, [])
215
+
216
+ useEffect(() => {
217
+ if (userInfo) {
218
+ onReportProgress()
219
+ }
220
+ }, [userInfo])
221
+
222
+ useEffect(() => {
223
+ if (loginStatus !== LOGIN_STATUS.WAIT && liveInfo) {
224
+ onSendSensors({
225
+ pageName: TrackPageName,
226
+ eventName: 'edu_Platform_publiclive_detail_page',
227
+ params: {
228
+ publiclive_id: liveInfo.live_id,
229
+ publiclive_name: liveInfo.live_name,
230
+ // 1-直播, 2-录播
231
+ publiclive_type: liveInfo.type === 1 ? '实时直播' : '录播直播',
232
+ identity: userRole
233
+ ? USER_IDENTITY_NAME[userRole]
234
+ : '游客'
235
+ }
236
+ })
237
+ }
238
+ }, [!!userRole, !!liveInfo, loginStatus])
239
+
240
+ if (!isExist) {
241
+ return (
242
+ <div
243
+ className={classNames(
244
+ style['public-live-detail-wrapper'],
245
+ style['live-empty'],
246
+ containerClassName
247
+ )}
248
+ style={{
249
+ backgroundImage: `url(${errorCover})`
250
+ }}
251
+ >
252
+ <div className={style['empty-marker']} />
253
+ <div className={style['empty-content']}>
254
+ {/* eslint-disable-next-line max-len */}
255
+ <img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAA2CAYAAACMRWrdAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAALOSURBVHgB7VqLbeMwDGVugctt4BEygje4bFBv0G5y2SC5Rc4jpBNEneDaLtBXCVIA16asL50U8AMEA7ZF6pG0PqSJVqxYIYkNCQHAVl8a3Xa6/dTt1+Dxs25v5rrZbN7o3qHJtLoddDsjHmfXp6V7gvGMbo+JZHxQuj3QraEHsXeDqQ11E4JaaaNbD3kcjS5aAlrRDmEvmefmu+lgjbAd9N86GXv3ToysHUlCK3hA2MItJcIRPQVky4RmgFSPCiED693TYuScRX14osowMnV79eirE5bOimqG2JEEMKNX1YgOQjj2b0GupxLAzmqxkCJnPgMuLPeUC4+1TPyfFib3xOhSGCwjKcK6uYHfgFzP6EqfuMB7qxm9sxg52O9tjHOqkDZ2sAuT43S1KQIOjIBdosLq5DwGP6QIGB9BVESfpcipkfy4cITdpGZZZQly4KMpPDt63P2bIiFNDvxsHd5mwR4n0jt+lSFGDvzs2I3f+8H05Ui8UAJ0gqbTl7/Mo64COS75MwlFjtgEOZkkKXKeseQRKxhER3KemwVHbGIR5OzJHGqTix1LFDFiXJ2CyuQa5t5kLeOIPTP3WipERXINc++dQkDBAh2D0qUAuQu065y8pUpBCTnkbqlcZ84qLVVEDjnwSaWkTXD0saUEqeRQemxxQrgiQ0OVEUsO/FbqQqkAn2coyw75dQXJed5JT6DCzo6KEVY9QUo0Tw62TFXurYEybqdvUmEiRQLE5TDzvTVS1jNCFYTKO1gqQQvpVDOvc47cpZpe+LOx5p5EUeLRQ+oDtT8DzKe7j6hXRupnSHUkAYRz+ccci8JuCObC778YqcEgUkq1e/f+uFTbOCPFlGovkC7VDgbXIG1qzoEJvX9Yqrg+ImisrlAXhpDxUn6Z6M4IXj1kZsSiE3t1IP+Xoz+ofCyS/knMfPTX6xWvZI/yJgXx8i1+EluxYsUEn1PRdSb/XhDOAAAAAElFTkSuQmCC" alt="" />
256
+ <p>{errorText || '内容已失效'}</p>
257
+ </div>
258
+
259
+ </div>
260
+ )
261
+ }
262
+
263
+ if (!liveInfo) {
264
+ return <Loading />
265
+ }
266
+
267
+ const isRecordLive = liveInfo.type === PUBLIC_LIVE_MODE.RECORDED
268
+ const beginTime = dayjs(liveInfo.begin_time)
269
+
270
+ const handlePlayReplay = (needReport) => {
271
+ if (needReport) {
272
+ onSendSensors({
273
+ pageName: TrackPageName,
274
+ eventName: 'edu_Platform_publiclive_detail_replay_click',
275
+ params: {
276
+ publiclive_id: liveInfo.live_id,
277
+ publiclive_name: liveInfo.live_name,
278
+ // 1-直播, 2-录播
279
+ publiclive_type: liveInfo.type === 1 ? '实时直播' : '录播直播'
280
+ }
281
+ })
282
+ }
283
+
284
+ setIsReplayMode(true)
285
+ }
286
+
287
+ const handleRequestFullScreen = () => {
288
+ onSendSensors({
289
+ pageName: TrackPageName,
290
+ eventName: 'edu_Platform_publiclive_detail_fullscreen_click'
291
+ })
292
+ }
293
+
294
+ const handleVideoPlay = (needReport) => {
295
+ if (needReport) {
296
+ onSendSensors({
297
+ pageName: TrackPageName,
298
+ eventName: 'edu_Platform_publiclive_detail_play_click',
299
+ params: {
300
+ publiclive_id: liveInfo.live_id,
301
+ publiclive_name: liveInfo.live_name,
302
+ // 1-直播, 2-录播
303
+ publiclive_type: liveInfo.type === 1 ? '实时直播' : '录播直播'
304
+ }
305
+ })
306
+ }
307
+ if (userInfo) {
308
+ // 登录且播放后上报
309
+ onReportTeacherTrain(userInfo?.user_id, liveId)
310
+ }
311
+ }
312
+
313
+ return (
314
+ <>
315
+ <div
316
+ className={classNames(
317
+ style['public-live-detail-wrapper'],
318
+ containerClassName
319
+ )}
320
+ >
321
+ <div
322
+ className={classNames(
323
+ className, style['live-panel']
324
+ )}
325
+ >
326
+ <div className={infoClassName}>
327
+
328
+ <div className={style['live-title']}>
329
+ <div className={style['live-name']}>
330
+ {liveInfo.live_name}
331
+ </div>
332
+ {
333
+ // eslint-disable-next-line no-nested-ternary
334
+ liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
335
+ ? (
336
+ <LiveOnlineCount
337
+ className={style['live-online-count']}
338
+ resId={liveId}
339
+ onOnlineCountChange={onOnlineCountChange}
340
+ />
341
+ )
342
+ : (
343
+ liveInfo.status === PUBLIC_LIVE_STATUS.COMPLETEED
344
+ ? (<div className={style['live-end']}>已结束</div>)
345
+ : (<></>)
346
+ )
347
+ }
348
+ </div>
349
+ <div className={style['live-info']}>
350
+ {/*
351
+ 暂时隐藏主播
352
+ <div className={classNames(style['live-user'], {
353
+ [style['empty-user']]: !liveInfo.lecture_user_id && !liveInfo.lecture_user_name
354
+ })}
355
+ >
356
+ <Avatar className={style.avatar} src={getAvatarURL(liveInfo.lecture_user_id)} />
357
+ <span title={liveInfo.lecture_user_name}>{liveInfo.lecture_user_name}</span>
358
+ </div> */
359
+ }
360
+ <div className={style['live-time']}>
361
+ <Icon
362
+ className={style['icon-time']}
363
+ type="clock-circle"
364
+ />
365
+ <span>
366
+ {`${beginTime.format(beginTime.isSame(dayjs(), 'day') ? '[今天] HH:mm' : 'YYYY-MM-DD HH:mm')} 开始`}
367
+ </span>
368
+ </div>
369
+ </div>
370
+ </div>
371
+ <div
372
+ className={classNames(style['live-video-wrapper'], playerClassName)}
373
+ >
374
+ <div className={style['live-wrap']}>
375
+ {
376
+ // eslint-disable-next-line no-nested-ternary
377
+ isReplayMode
378
+ ? (
379
+ <ReplayVideo
380
+ handleLogin={handleLogin}
381
+ liveInfo={liveInfo}
382
+ autoplay={isLiveToReplay}
383
+ onVideoPlay={() => {
384
+ handleVideoPlay(false)
385
+ }}
386
+ onRequestFullScreen={handleRequestFullScreen}
387
+ />
388
+ )
389
+ : isRecordLive
390
+ ? (
391
+ <RecordVideo
392
+ isStreamLive={isStreamLive}
393
+ userInfo={userInfo}
394
+ liveInfo={liveInfo}
395
+ visitTime={visitTime}
396
+ diffTime={diffTime}
397
+ onStatusChange={handleStatusChange}
398
+ onPlayReplay={() => {
399
+ handlePlayReplay(true)
400
+ }}
401
+ onVideoPlay={() => {
402
+ handleVideoPlay(true)
403
+ }}
404
+ onRequestFullScreen={handleRequestFullScreen}
405
+ />
406
+ )
407
+ : (
408
+ <LiveVideo
409
+ isStreamLive={isStreamLive}
410
+ handleLogin={handleLogin}
411
+ userInfo={userInfo}
412
+ liveInfo={liveInfo}
413
+ visitTime={visitTime}
414
+ lineChanging={lineChanging}
415
+ onStatusChange={handleStatusChange}
416
+ onPlayReplay={() => {
417
+ handlePlayReplay(true)
418
+ }}
419
+ onVideoPlay={() => {
420
+ handleVideoPlay(true)
421
+ }}
422
+ onRequestFullScreen={handleRequestFullScreen}
423
+ />
424
+ )
425
+ }
426
+ {/* {
427
+ liveInfo?.chat_type && (
428
+ <div className={style['chatroom-wrap']}>
429
+ <div className={style['chatroom-title']}>
430
+ 讨论区
431
+ </div>
432
+ {
433
+ userInfo ? (
434
+ <>
435
+ <div className={style['chatroom-top-hint']}>
436
+ 系统提示:倡导建康的直播环境,若发布违法、违规、低俗等不良消息,我们会对违规内容及帐号进行封禁处理。
437
+ </div>
438
+ <IMChatroom
439
+ roomId={liveInfo.chat_room_id}
440
+ disableEditor={!liveInfo.chat_enabled}
441
+ />
442
+ </>
443
+ ) : (
444
+ <NotLoginChatroom
445
+ handleLogin={handleLogin}
446
+ />
447
+ )
448
+ }
449
+ </div>
450
+ )
451
+ } */}
452
+ </div>
453
+ {
454
+ !isReplayMode && !isRecordLive
455
+ && liveInfo.sub_type !== SUB_TYPE.NET_DRAGON
456
+ && liveInfo.status !== PUBLIC_LIVE_STATUS.COMPLETEED
457
+ && (
458
+ <LineSwitch
459
+ className={style['live-line-switch']}
460
+ liveInfo={liveInfo}
461
+ onChange={handleSelectChange}
462
+ />
463
+ )
464
+ }
465
+ </div>
466
+ </div>
467
+ <div
468
+ className={classNames(
469
+ style['live-description-panel'],
470
+ descriptionClassName
471
+ )}
472
+ >
473
+ <div className={style['desc-title']}>开播介绍</div>
474
+ <div className={style['desc-content']}>
475
+ {!liveInfo.desc_pic_web_url ? '暂无介绍' : (
476
+ <img className={style['desc-content-img']} src={netUrl(liveInfo.desc_pic_web_url)} alt="" />
477
+ )}
478
+ </div>
479
+ </div>
480
+ </div>
481
+ </>
482
+ )
483
+ }