@x-edu/live-player 0.0.21 → 0.0.23

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 (299) 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/doc/develop.md +23 -23
  9. package/gem-mine.config.js +86 -86
  10. package/jest.config.js +9 -9
  11. package/jsconfig.json +15 -15
  12. package/mock/helper.js +8 -8
  13. package/mock/index.js +34 -34
  14. package/package.json +99 -99
  15. package/public/3rd/ali-player/alipayercomponents-1.0.8.min.js +26 -26
  16. package/public/3rd/ali-player/aliplayer-hls-min.js +27 -27
  17. package/public/3rd/ali-player/aliplayer-min.js +1 -1
  18. package/public/3rd/im-web-push/index.umd.js +14 -14
  19. package/public/JsBridge.js +1602 -1602
  20. package/public/fish/editor/themes/default/css/ueditor.css +1905 -1905
  21. package/public/fish/editor/third-party/codemirror/codemirror.css +104 -104
  22. package/public/fish/editor/third-party/codemirror/codemirror.js +3581 -3581
  23. package/public/fish/editor/third-party/zeroclipboard/ZeroClipboard.js +1255 -1255
  24. package/public/fish/editor/ueditor.all.min.js +16 -16
  25. package/public/fish/editor/ueditor.config.js +467 -467
  26. package/public/fish/icon/umd-4.1.2.js +1 -1
  27. package/public/fish/video/videoplayer.min.css +6 -6
  28. package/public/fish/video/videoplayer.min.js +31 -31
  29. package/public/fish/video/zh-CN.js +82 -82
  30. package/public/icon/demo.css +539 -539
  31. package/public/icon/demo_index.html +2189 -2189
  32. package/public/icon/iconfont.css +363 -363
  33. package/public/icon/iconfont.json +618 -618
  34. package/public/index.html +50 -50
  35. package/script/image/readme.md +77 -77
  36. package/script/postcss.js +48 -48
  37. package/src/App.jsx +24 -24
  38. package/src/asset/img/course/playing.svg +21 -21
  39. package/src/asset/img/icon-course-white.svg +3 -3
  40. package/src/asset/img/icon-course.svg +3 -3
  41. package/src/asset/img/icon-eye-white.svg +4 -4
  42. package/src/asset/img/icon-eye.svg +4 -4
  43. package/src/asset/img/icon-school-white.svg +3 -3
  44. package/src/asset/img/icon-school.svg +3 -3
  45. package/src/asset/img/loading.svg +52 -52
  46. package/src/asset/img/video-play.svg +6 -6
  47. package/src/asset/style/background.less +19 -19
  48. package/src/asset/style/banner.less +36 -36
  49. package/src/asset/style/base.less +74 -74
  50. package/src/asset/style/index.less +114 -114
  51. package/src/asset/style/reset-theme.less +141 -141
  52. package/src/asset/style/theme/index.less +55 -55
  53. package/src/asset/style/theme/party/global.less +20 -20
  54. package/src/asset/style/theme/party/override.less +57 -57
  55. package/src/asset/style/theme/test/global.less +18 -18
  56. package/src/asset/style/theme/test/override.less +45 -45
  57. package/src/asset/style/variable.less +12 -12
  58. package/src/component/AliPlayer/index.jsx +49 -49
  59. package/src/component/Avatar/index.jsx +50 -50
  60. package/src/component/Empty/index.jsx +34 -34
  61. package/src/component/Empty/index.module.less +37 -37
  62. package/src/component/IMChatroom/component/status/403.jsx +13 -13
  63. package/src/component/IMChatroom/component/status/404.jsx +13 -13
  64. package/src/component/IMChatroom/component/status/Error.jsx +23 -23
  65. package/src/component/IMChatroom/component/status/Loading.jsx +5 -5
  66. package/src/component/IMChatroom/config/app/config.js +118 -118
  67. package/src/component/IMChatroom/config/app/index.js +60 -60
  68. package/src/component/IMChatroom/config/env.js +5 -5
  69. package/src/component/IMChatroom/config/index.js +3 -3
  70. package/src/component/IMChatroom/config/request/config/base.js +124 -124
  71. package/src/component/IMChatroom/config/request/config/chatroom.js +26 -26
  72. package/src/component/IMChatroom/config/request/config/imCoreApi.js +21 -21
  73. package/src/component/IMChatroom/config/request/index.js +21 -21
  74. package/src/component/IMChatroom/config/request/proxy.js +39 -39
  75. package/src/component/IMChatroom/config/url.js +7 -7
  76. package/src/component/IMChatroom/constants/errorCode.js +9 -9
  77. package/src/component/IMChatroom/constants/index.js +84 -84
  78. package/src/component/IMChatroom/constants/origin.js +27 -27
  79. package/src/component/IMChatroom/context/chatroom.js +154 -154
  80. package/src/component/IMChatroom/context/connect.js +28 -28
  81. package/src/component/IMChatroom/i18n/en/index.json +73 -73
  82. package/src/component/IMChatroom/i18n/index.jsx +14 -14
  83. package/src/component/IMChatroom/i18n/language.js +9 -9
  84. package/src/component/IMChatroom/i18n/zh-CN/index.json +73 -73
  85. package/src/component/IMChatroom/index.jsx +49 -49
  86. package/src/component/IMChatroom/page/chat/index.jsx +27 -27
  87. package/src/component/IMChatroom/page/chat/messageEditor/index.jsx +375 -375
  88. package/src/component/IMChatroom/page/chat/messageList/index.jsx +354 -354
  89. package/src/component/IMChatroom/page/chat/stickedMessage/index.jsx +59 -59
  90. package/src/component/IMChatroom/page/chat/stickedMessage/style/index.module.less +7 -7
  91. package/src/component/IMChatroom/page/chat/style/index.module.less +51 -51
  92. package/src/component/IMChatroom/page/home/connect/index.jsx +188 -188
  93. package/src/component/IMChatroom/page/home/connect/status.jsx +124 -124
  94. package/src/component/IMChatroom/page/home/context/cmd.jsx +37 -37
  95. package/src/component/IMChatroom/page/home/context/index.jsx +67 -67
  96. package/src/component/IMChatroom/page/home/index.jsx +164 -164
  97. package/src/component/IMChatroom/page/home/notice/index.jsx +123 -123
  98. package/src/component/IMChatroom/page/home/notice/style/index.module.less +49 -49
  99. package/src/component/IMChatroom/page/home/style/index.module.less +110 -110
  100. package/src/component/IMChatroom/page/member/index.jsx +15 -15
  101. package/src/component/IMChatroom/page/member/memberCount/index.jsx +44 -44
  102. package/src/component/IMChatroom/page/member/memberList/index.jsx +121 -121
  103. package/src/component/IMChatroom/page/member/style/index.module.less +2 -2
  104. package/src/component/IMChatroom/sdk/bridge.js +39 -39
  105. package/src/component/IMChatroom/sdk/cs/constants.js +20 -20
  106. package/src/component/IMChatroom/sdk/cs/index.js +101 -101
  107. package/src/component/IMChatroom/sdk/imChatroom.js +15 -15
  108. package/src/component/IMChatroom/sdk/imcore/constants.js +128 -128
  109. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomDestroyed.js +5 -5
  110. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomInfoGetFail.js +5 -5
  111. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomKickedByAdmin.js +5 -5
  112. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomKickedBySelf.js +5 -5
  113. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomLoginFail.js +5 -5
  114. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomLoginSuccess.js +5 -5
  115. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomMemberLogin.js +5 -5
  116. package/src/component/IMChatroom/sdk/imcore/emitters/chatroomMemberLogout.js +5 -5
  117. package/src/component/IMChatroom/sdk/imcore/emitters/connectionConnected.js +5 -5
  118. package/src/component/IMChatroom/sdk/imcore/emitters/connectionConnecting.js +5 -5
  119. package/src/component/IMChatroom/sdk/imcore/emitters/connectionDisconnect.js +5 -5
  120. package/src/component/IMChatroom/sdk/imcore/emitters/index.js +57 -57
  121. package/src/component/IMChatroom/sdk/imcore/emitters/messageReceive.js +36 -36
  122. package/src/component/IMChatroom/sdk/imcore/index.js +178 -178
  123. package/src/component/IMChatroom/sdk/imcore/interceptors/request.js +7 -7
  124. package/src/component/IMChatroom/sdk/imcore/interceptors/response.js +5 -5
  125. package/src/component/IMChatroom/sdk/imcore/plugins/getAuth.js +64 -64
  126. package/src/component/IMChatroom/sdk/imcore/plugins/getConversationId.js +20 -20
  127. package/src/component/IMChatroom/sdk/imcore/plugins/getExtInfo.js +10 -10
  128. package/src/component/IMChatroom/sdk/imcore/plugins/getLoginInfo.js +48 -48
  129. package/src/component/IMChatroom/sdk/imcore/plugins/getPlatformType.js +12 -12
  130. package/src/component/IMChatroom/sdk/imcore/plugins/index.js +22 -22
  131. package/src/component/IMChatroom/sdk/imcore/util/format.js +177 -177
  132. package/src/component/IMChatroom/sdk/imcore/util/parser.js +35 -35
  133. package/src/component/IMChatroom/sdk/oms.js +18 -18
  134. package/src/component/IMChatroom/sdk/uc.js +3 -3
  135. package/src/component/IMChatroom/subscription/channel/app.js +5 -5
  136. package/src/component/IMChatroom/subscription/channel/ctl.js +22 -22
  137. package/src/component/IMChatroom/subscription/channel/member.js +40 -40
  138. package/src/component/IMChatroom/subscription/channel/message.js +13 -13
  139. package/src/component/IMChatroom/subscription/channel/ntf.js +86 -86
  140. package/src/component/IMChatroom/subscription/channel/tel.js +5 -5
  141. package/src/component/IMChatroom/subscription/channel/websocket.js +5 -5
  142. package/src/component/IMChatroom/subscription/event.js +37 -37
  143. package/src/component/IMChatroom/subscription/index.js +19 -19
  144. package/src/component/IMChatroom/util/account.js +8 -8
  145. package/src/component/IMChatroom/util/chatroom.js +255 -255
  146. package/src/component/IMChatroom/util/jsonBigInt.js +5 -5
  147. package/src/component/IMChatroom/util/location.js +12 -12
  148. package/src/component/Icon/index.jsx +16 -16
  149. package/src/component/Icon/index.module.less +2 -2
  150. package/src/component/Pagination/LocalPagination.jsx +27 -27
  151. package/src/component/Pagination/RemotePagination.jsx +32 -32
  152. package/src/component/Pagination/index.jsx +32 -31
  153. package/src/component/Pagination/index.module.less +117 -110
  154. package/src/component/PlayerTip/index.jsx +34 -34
  155. package/src/component/VideoBase/index.jsx +242 -242
  156. package/src/component/VideoBase/style.less +65 -65
  157. package/src/component/VideoBase/utils.js +81 -81
  158. package/src/component/mixin.less +9 -9
  159. package/src/component/status/403.jsx +15 -15
  160. package/src/component/status/404/index.jsx +73 -73
  161. package/src/component/status/404/index.module.less +36 -36
  162. package/src/component/status/Error/error.module.less +13 -13
  163. package/src/component/status/Error/index.jsx +47 -47
  164. package/src/component/status/Loading/img/loading.svg +52 -52
  165. package/src/component/status/Loading/index.jsx +31 -31
  166. package/src/component/status/Loading/index.less +56 -56
  167. package/src/component/status/None/index.jsx +20 -20
  168. package/src/component/status/None/index.module.less +35 -35
  169. package/src/component/status/Status/index.jsx +26 -26
  170. package/src/component/status/Status/index.module.less +8 -8
  171. package/src/config/constant/commonUrl.js +2 -2
  172. package/src/config/constant/user.js +6 -6
  173. package/src/config/context/site-config.js +48 -48
  174. package/src/config/env/index.js +5 -5
  175. package/src/config/env/local/index.js +13 -13
  176. package/src/config/env/ncet-xedu/api.js +175 -175
  177. package/src/config/env/ncet-xedu/app.js +12 -12
  178. package/src/config/env/ncet-xedu/cs.js +8 -8
  179. package/src/config/env/ncet-xedu/index.js +14 -14
  180. package/src/config/env/ncet-xedu/push.js +5 -5
  181. package/src/config/env/preproduction/api.js +144 -144
  182. package/src/config/env/preproduction/app.js +12 -12
  183. package/src/config/env/preproduction/cs.js +8 -8
  184. package/src/config/env/preproduction/index.js +14 -14
  185. package/src/config/env/preproduction/push.js +5 -5
  186. package/src/config/env/product/api.js +113 -113
  187. package/src/config/env/product/app.js +12 -12
  188. package/src/config/env/product/cs.js +5 -5
  189. package/src/config/env/product/index.js +14 -14
  190. package/src/config/env/product/push.js +5 -5
  191. package/src/config/live.js +80 -80
  192. package/src/config/publicLive.js +53 -53
  193. package/src/config/request/assessments.js +24 -24
  194. package/src/config/request/config-center.js +8 -8
  195. package/src/config/request/helper.js +166 -166
  196. package/src/config/request/im-broadcasts.js +12 -12
  197. package/src/config/request/live-activity-gateway.js +8 -8
  198. package/src/config/request/live-activity.js +13 -13
  199. package/src/config/request/raw.js +6 -6
  200. package/src/config/request/x-cloud-web.js +13 -13
  201. package/src/config/request/x-proxy.js +34 -34
  202. package/src/demo/Detail.jsx +11 -11
  203. package/src/demo/List.jsx +66 -64
  204. package/src/demo/index.jsx +17 -17
  205. package/src/detail/LineSwitch/index.jsx +71 -71
  206. package/src/detail/LiveCountDown/index.jsx +44 -44
  207. package/src/detail/LiveCountDown/index.module.less +31 -31
  208. package/src/detail/LiveOnlineCount/img/icon.svg +15 -15
  209. package/src/detail/LiveOnlineCount/index.jsx +68 -68
  210. package/src/detail/LiveOnlineCount/index.module.less +34 -34
  211. package/src/detail/LiveOnlineCount/util.js +74 -74
  212. package/src/detail/LiveStatus/AnchorOnTheWay.jsx +88 -88
  213. package/src/detail/LiveStatus/index.jsx +202 -202
  214. package/src/detail/LiveStatus/index.module.less +192 -192
  215. package/src/detail/LiveVideo/config.js +37 -37
  216. package/src/detail/LiveVideo/index.jsx +188 -188
  217. package/src/detail/LiveVideo/index.module.less +41 -41
  218. package/src/detail/NotLoginChatroom/index.jsx +37 -37
  219. package/src/detail/NotLoginChatroom/index.module.less +46 -46
  220. package/src/detail/RecordVideo/index.jsx +150 -150
  221. package/src/detail/RecordVideo/index.module.less +31 -31
  222. package/src/detail/ReplayVideo/index.jsx +93 -93
  223. package/src/detail/ReplayVideo/index.module.less +65 -65
  224. package/src/detail/const.js +20 -20
  225. package/src/detail/hook/usePullSource.js +82 -82
  226. package/src/detail/hook/usePullState.js +51 -51
  227. package/src/detail/index.jsx +482 -482
  228. package/src/detail/index.module.less +188 -188
  229. package/src/hook/useAsync.js +84 -84
  230. package/src/hook/useGoToPage.js +83 -83
  231. package/src/hook/useInterval.js +28 -28
  232. package/src/hook/useIsMounted.js +17 -17
  233. package/src/hook/useModuleByRole.js +53 -53
  234. package/src/hook/usePageScrollable.js +52 -52
  235. package/src/hook/usePortal.js +83 -83
  236. package/src/hook/useScrollRestore/index.js +32 -32
  237. package/src/hook/useScrollRestore/scrollContext.js +20 -20
  238. package/src/hook/useTrackRef.js +11 -11
  239. package/src/hook/useWindowSize.js +28 -28
  240. package/src/hook/useZoom.js +47 -47
  241. package/src/index.js +10 -10
  242. package/src/lib/getLiveOnlineCount.js +10 -10
  243. package/src/lib/getServiceConfig.js +102 -102
  244. package/src/list/Empty/index.jsx +20 -20
  245. package/src/list/Empty/index.module.less +23 -23
  246. package/src/list/ListItem/Action/index.jsx +100 -98
  247. package/src/list/ListItem/Action/index.module.less +19 -21
  248. package/src/list/ListItem/img/play.svg +15 -15
  249. package/src/list/ListItem/img/video.svg +3 -0
  250. package/src/list/ListItem/index.jsx +46 -28
  251. package/src/list/ListItem/index.module.less +152 -146
  252. package/src/list/index.module.less +35 -35
  253. package/src/service/common.js +73 -73
  254. package/src/service/content-mgr.js +73 -73
  255. package/src/service/im-group.js +12 -12
  256. package/src/service/im.js +7 -7
  257. package/src/service/imBroadcasts.js +33 -33
  258. package/src/service/like.js +134 -134
  259. package/src/service/manageApi.js +7 -7
  260. package/src/service/managePortal.js +6 -6
  261. package/src/service/myStudyRecord.js +93 -93
  262. package/src/service/navigation.js +47 -47
  263. package/src/service/ndMeeting.js +10 -10
  264. package/src/service/ndr.js +122 -122
  265. package/src/service/news.js +93 -93
  266. package/src/service/personalCenter.js +270 -270
  267. package/src/service/qualityCourse.js +31 -31
  268. package/src/service/recommend.js +81 -81
  269. package/src/service/school.js +323 -323
  270. package/src/service/search.js +170 -170
  271. package/src/service/site-config.js +7 -7
  272. package/src/service/socialCensor.js +45 -45
  273. package/src/service/specialEdu.js +31 -31
  274. package/src/service/suggestion.js +85 -85
  275. package/src/service/syncClassroom.js +321 -321
  276. package/src/service/tCourse.js +204 -204
  277. package/src/service/tchTraining.js +37 -37
  278. package/src/service/uc.js +45 -45
  279. package/src/util/app.js +1 -1
  280. package/src/util/array.js +3 -3
  281. package/src/util/auth/func.js +57 -57
  282. package/src/util/date.js +53 -53
  283. package/src/util/env.js +9 -9
  284. package/src/util/getTimestamp.js +10 -10
  285. package/src/util/hof.js +105 -105
  286. package/src/util/live/index.js +42 -42
  287. package/src/util/netUrl.js +35 -35
  288. package/src/util/object.js +13 -13
  289. package/src/util/push/index.js +58 -58
  290. package/src/util/request.js +227 -227
  291. package/src/util/type.js +17 -17
  292. package/src/util/url.js +203 -203
  293. package/src/util/video.js +26 -26
  294. package/test/setup.js +21 -21
  295. package/test/unit/component/header/logo.spec.jsx +8 -8
  296. package/test/unit/helper.jsx +25 -25
  297. package/test/unit/util/date.spec.js +40 -40
  298. package/dist/XEduLivePlayer.common.js +0 -72605
  299. package/dist/XEduLivePlayerPre.common.js +0 -72625
@@ -1,482 +1,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
- }
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
+ }
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
+ }