@x-edu/live-player 0.0.16 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/XEduLivePlayer.common.js +410 -426
- package/dist/XEduLivePlayerPre.common.js +198 -214
- package/package.json +1 -1
- package/src/detail/LiveStatus/AnchorOnTheWay.jsx +18 -8
- package/src/detail/LiveStatus/index.jsx +50 -34
- package/src/detail/LiveVideo/index.jsx +2 -0
- package/src/detail/RecordVideo/index.jsx +150 -148
- package/src/detail/hook/usePullSource.js +56 -24
- package/src/detail/index.jsx +14 -32
- package/src/util/object.js +1 -1
package/package.json
CHANGED
|
@@ -4,12 +4,14 @@ import dayjs from 'dayjs'
|
|
|
4
4
|
import useInterval from '@/hook/useInterval'
|
|
5
5
|
import style from './index.module.less'
|
|
6
6
|
import usePullSource from '../hook/usePullSource'
|
|
7
|
+
import { SUB_TYPE } from '@/config/publicLive'
|
|
7
8
|
|
|
8
9
|
export default function AnchorOnTheWay({
|
|
9
10
|
liveInfo,
|
|
10
11
|
isStreamLive,
|
|
11
12
|
hasPlayed,
|
|
12
|
-
reload
|
|
13
|
+
reload,
|
|
14
|
+
onStatusChange
|
|
13
15
|
}) {
|
|
14
16
|
const [isAfterEndTime, setIsAfterEndTime] = useState(
|
|
15
17
|
dayjs().isAfter(dayjs(liveInfo.end_time))
|
|
@@ -19,18 +21,18 @@ export default function AnchorOnTheWay({
|
|
|
19
21
|
setIsAfterEndTime(dayjs().isAfter(dayjs(liveInfo.end_time)))
|
|
20
22
|
}, 1000)
|
|
21
23
|
|
|
22
|
-
const sourceSrc = liveInfo?.imInfo?.param?.url
|
|
23
|
-
const hasMultiLines = liveInfo?.imInfo?.param?.lines?.length > 1
|
|
24
|
-
|
|
25
24
|
usePullSource({
|
|
26
|
-
|
|
25
|
+
liveInfo,
|
|
27
26
|
reload,
|
|
27
|
+
onStatusChange,
|
|
28
28
|
shouldStartPull: isStreamLive
|
|
29
29
|
})
|
|
30
30
|
|
|
31
|
+
const hasMultiLines = liveInfo?.imInfo?.param?.lines?.length > 1
|
|
32
|
+
const isNDMeeting = liveInfo.sub_type === SUB_TYPE.NET_DRAGON
|
|
31
33
|
return (
|
|
32
34
|
<>
|
|
33
|
-
{isAfterEndTime
|
|
35
|
+
{isAfterEndTime && !isNDMeeting
|
|
34
36
|
? (
|
|
35
37
|
<div className={style['status-completed']}>
|
|
36
38
|
<div className={style.icon} />
|
|
@@ -45,7 +47,11 @@ export default function AnchorOnTheWay({
|
|
|
45
47
|
? (hasPlayed
|
|
46
48
|
? (
|
|
47
49
|
<>
|
|
48
|
-
<div
|
|
50
|
+
<div>
|
|
51
|
+
{isNDMeeting
|
|
52
|
+
? '主播正在赶来的路上...'
|
|
53
|
+
: '加载中...'}
|
|
54
|
+
</div>
|
|
49
55
|
{
|
|
50
56
|
hasMultiLines ? (
|
|
51
57
|
<div
|
|
@@ -64,7 +70,11 @@ export default function AnchorOnTheWay({
|
|
|
64
70
|
)
|
|
65
71
|
: (
|
|
66
72
|
<>
|
|
67
|
-
<div
|
|
73
|
+
<div>
|
|
74
|
+
{isNDMeeting
|
|
75
|
+
? '主播正在赶来的路上...'
|
|
76
|
+
: '等待开播中...'}
|
|
77
|
+
</div>
|
|
68
78
|
</>
|
|
69
79
|
)
|
|
70
80
|
)
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
+
/* eslint-disable no-nested-ternary */
|
|
1
2
|
import React, { useState } from 'react'
|
|
2
3
|
import dayjs from 'dayjs'
|
|
3
4
|
import { Icon, Spin } from 'fish'
|
|
4
|
-
import { PROVIDE_RECORD, PUBLIC_LIVE_STATUS, VIEW_REPLAY, PUBLIC_LIVE_MODE
|
|
5
|
+
import { PROVIDE_RECORD, PUBLIC_LIVE_STATUS, VIEW_REPLAY, PUBLIC_LIVE_MODE } from '@/config/publicLive'
|
|
5
6
|
import LiveCountDown from '../LiveCountDown'
|
|
6
7
|
import style from './index.module.less'
|
|
7
8
|
import AnchorOnTheWay from './AnchorOnTheWay'
|
|
8
9
|
|
|
9
10
|
function LiveStatus({
|
|
11
|
+
isStreamLive,
|
|
10
12
|
handleLogin,
|
|
11
13
|
userInfo,
|
|
12
14
|
liveInfo,
|
|
@@ -19,6 +21,9 @@ function LiveStatus({
|
|
|
19
21
|
onPlayReplay = () => undefined,
|
|
20
22
|
onReloadLive = () => undefined
|
|
21
23
|
}) {
|
|
24
|
+
// 调试代码 模拟倒计时2S
|
|
25
|
+
// const [countDownTime, setCountDownTime] = useState(2000)
|
|
26
|
+
|
|
22
27
|
const [countDownTime, setCountDownTime] = useState(dayjs(liveInfo.begin_time).valueOf() - visitTime)
|
|
23
28
|
const isNoStarted = liveInfo.status === PUBLIC_LIVE_STATUS.NOSTARTED
|
|
24
29
|
const isLiving = liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
|
|
@@ -26,7 +31,6 @@ function LiveStatus({
|
|
|
26
31
|
const isPaused = liveInfo.status === PUBLIC_LIVE_STATUS.PASUED
|
|
27
32
|
const isOffline = liveInfo.status === PUBLIC_LIVE_STATUS.OFFLINE
|
|
28
33
|
const isRecordLive = liveInfo.type === PUBLIC_LIVE_MODE.RECORDED
|
|
29
|
-
const isStreamLive = liveInfo.type === PUBLIC_LIVE_MODE.LIVING && (liveInfo.sub_type === SUB_TYPE.OUTSIDE || liveInfo.sub_type === SUB_TYPE.REBROADCAST)
|
|
30
34
|
|
|
31
35
|
// 当前时间是否在回放时间开始前, 如果没有回放开始时间, 则直接判断未回放还没生成
|
|
32
36
|
const isBeforeRecordTime = liveInfo.replay_begin_time
|
|
@@ -43,6 +47,7 @@ function LiveStatus({
|
|
|
43
47
|
|
|
44
48
|
const startLiving = () => {
|
|
45
49
|
if (isRecordLive || isStreamLive) {
|
|
50
|
+
setCountDownTime(0)
|
|
46
51
|
onStatusChange(PUBLIC_LIVE_STATUS.LIVEING, {
|
|
47
52
|
play: !mustLogin
|
|
48
53
|
})
|
|
@@ -58,51 +63,60 @@ function LiveStatus({
|
|
|
58
63
|
onPlayReplay()
|
|
59
64
|
}
|
|
60
65
|
}
|
|
61
|
-
|
|
62
|
-
if (canLiveStart && !isLiveException && !isLiveLoading && !isLiveLoadError) {
|
|
63
|
-
return null
|
|
64
|
-
}
|
|
65
|
-
|
|
66
66
|
// 播放状态
|
|
67
67
|
if (canLiveStart) {
|
|
68
|
+
if (!isLiveException && !isLiveLoading && !isLiveLoadError) {
|
|
69
|
+
return <></>
|
|
70
|
+
}
|
|
68
71
|
return (
|
|
69
72
|
<>
|
|
70
73
|
<div className={style['live-status-wrapper']}>
|
|
71
74
|
<div className={style['live-status']}>
|
|
72
|
-
{
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
<
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
75
|
+
{
|
|
76
|
+
isLiveException
|
|
77
|
+
? (
|
|
78
|
+
<AnchorOnTheWay
|
|
79
|
+
liveInfo={liveInfo}
|
|
80
|
+
isStreamLive={isStreamLive}
|
|
81
|
+
hasPlayed={hasPlayed}
|
|
82
|
+
reload={onReloadLive}
|
|
83
|
+
onStatusChange={onStatusChange}
|
|
84
|
+
/>
|
|
85
|
+
)
|
|
86
|
+
: isLiveLoadError
|
|
87
|
+
? (
|
|
88
|
+
<>
|
|
89
|
+
<div className={style['status-load-error']}>
|
|
90
|
+
<Icon type="exclamation-circle" className={style.icon} />
|
|
91
|
+
<div className={style.text}>加载失败,请重试</div>
|
|
92
|
+
</div>
|
|
93
|
+
<button className={style['primary-btn']} onClick={onReloadLive}>重试</button>
|
|
94
|
+
</>
|
|
95
|
+
)
|
|
96
|
+
: isLiveLoading
|
|
97
|
+
? (
|
|
98
|
+
<div className={style['status-living-loading']}>
|
|
99
|
+
<Spin indicator={(
|
|
100
|
+
<Icon type="loading" spin className={style.icon} />
|
|
101
|
+
)}
|
|
102
|
+
/>
|
|
103
|
+
<div className={style.text}>加载中...</div>
|
|
104
|
+
</div>
|
|
105
|
+
)
|
|
106
|
+
: (<></>)
|
|
107
|
+
}
|
|
98
108
|
</div>
|
|
99
109
|
</div>
|
|
100
110
|
{!isRecordLive && (isLiveLoadError || isLiveException) && (
|
|
101
|
-
<div
|
|
111
|
+
<div
|
|
112
|
+
className={style['video-poster']}
|
|
113
|
+
style={coverBgStyle}
|
|
114
|
+
/>
|
|
102
115
|
)}
|
|
103
116
|
</>
|
|
104
117
|
)
|
|
105
118
|
}
|
|
119
|
+
|
|
106
120
|
return (
|
|
107
121
|
<>
|
|
108
122
|
<div className={style['live-status-wrapper']}>
|
|
@@ -121,6 +135,7 @@ function LiveStatus({
|
|
|
121
135
|
isStreamLive={isStreamLive}
|
|
122
136
|
hasPlayed={hasPlayed}
|
|
123
137
|
reload={onReloadLive}
|
|
138
|
+
onStatusChange={onStatusChange}
|
|
124
139
|
/>
|
|
125
140
|
))}
|
|
126
141
|
{isLiving && (
|
|
@@ -145,6 +160,7 @@ function LiveStatus({
|
|
|
145
160
|
isStreamLive={isStreamLive}
|
|
146
161
|
hasPlayed={hasPlayed}
|
|
147
162
|
reload={onReloadLive}
|
|
163
|
+
onStatusChange={onStatusChange}
|
|
148
164
|
/>
|
|
149
165
|
)}
|
|
150
166
|
{isOffline && (
|
|
@@ -45,6 +45,7 @@ const shouldfixedLoading = window.navigator.userAgent.indexOf('iPad') > -1
|
|
|
45
45
|
|| isInWX()
|
|
46
46
|
|
|
47
47
|
export default function LiveVideo({
|
|
48
|
+
isStreamLive,
|
|
48
49
|
handleLogin,
|
|
49
50
|
userInfo,
|
|
50
51
|
liveInfo,
|
|
@@ -168,6 +169,7 @@ export default function LiveVideo({
|
|
|
168
169
|
{showAliPlayer && <AliPlayer options={options} onReady={handleVideoReady} />}
|
|
169
170
|
{supportM3u8 && (
|
|
170
171
|
<LiveStatus
|
|
172
|
+
isStreamLive={isStreamLive}
|
|
171
173
|
handleLogin={handleLogin}
|
|
172
174
|
userInfo={userInfo}
|
|
173
175
|
visitTime={visitTime}
|
|
@@ -1,148 +1,150 @@
|
|
|
1
|
-
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
-
import { Video } from 'fish'
|
|
3
|
-
import dayjs from 'dayjs'
|
|
4
|
-
import { PUBLIC_LIVE_STATUS } from '@/config/publicLive'
|
|
5
|
-
import { getUrlType, getType } from '@/util/video'
|
|
6
|
-
import { getRecordLiveStatus } from '@/util/live'
|
|
7
|
-
import LiveStatus from '../LiveStatus'
|
|
8
|
-
import style from './index.module.less'
|
|
9
|
-
|
|
10
|
-
export default function RecordVideo({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
const [
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
player.current.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
player.current.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
1
|
+
import React, { useState, useEffect, useRef } from 'react'
|
|
2
|
+
import { Video } from 'fish'
|
|
3
|
+
import dayjs from 'dayjs'
|
|
4
|
+
import { PUBLIC_LIVE_STATUS } from '@/config/publicLive'
|
|
5
|
+
import { getUrlType, getType } from '@/util/video'
|
|
6
|
+
import { getRecordLiveStatus } from '@/util/live'
|
|
7
|
+
import LiveStatus from '../LiveStatus'
|
|
8
|
+
import style from './index.module.less'
|
|
9
|
+
|
|
10
|
+
export default function RecordVideo({
|
|
11
|
+
isStreamLive,
|
|
12
|
+
userInfo,
|
|
13
|
+
liveInfo,
|
|
14
|
+
visitTime,
|
|
15
|
+
diffTime,
|
|
16
|
+
onStatusChange,
|
|
17
|
+
onPlayReplay,
|
|
18
|
+
onVideoPlay = () => undefined,
|
|
19
|
+
onRequestFullScreen = () => undefined
|
|
20
|
+
}) {
|
|
21
|
+
const isFullScreenRef = useRef(false)
|
|
22
|
+
const [isLiveLoading, setIsLiveLoading] = useState(false)
|
|
23
|
+
const [isLiveLoadError, setIsLiveLoadError] = useState(false)
|
|
24
|
+
const hasPlayed = useRef(false)
|
|
25
|
+
const player = useRef()
|
|
26
|
+
const endTimer = useRef()
|
|
27
|
+
const needLogin = !userInfo && liveInfo.login
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
const isLiving = liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
|
|
31
|
+
if (isLiving && needLogin) {
|
|
32
|
+
const timeToEnd = dayjs(liveInfo.end_time).valueOf() - (Date.now() - diffTime)
|
|
33
|
+
if (timeToEnd > 0) {
|
|
34
|
+
endTimer.current = setTimeout(() => {
|
|
35
|
+
onStatusChange(PUBLIC_LIVE_STATUS.COMPLETEED)
|
|
36
|
+
}, timeToEnd)
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (player.current) {
|
|
41
|
+
player.current.controls(isLiving && !needLogin)
|
|
42
|
+
|
|
43
|
+
// 显示成封面
|
|
44
|
+
if (liveInfo.status === PUBLIC_LIVE_STATUS.COMPLETEED || liveInfo.status === PUBLIC_LIVE_STATUS.OFFLINE) {
|
|
45
|
+
player.current.autoplay(false)
|
|
46
|
+
player.current.load()
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return () => {
|
|
51
|
+
clearTimeout(endTimer.current)
|
|
52
|
+
}
|
|
53
|
+
}, [liveInfo.status, userInfo])
|
|
54
|
+
|
|
55
|
+
const handleVideoReady = (v, playerIns) => {
|
|
56
|
+
player.current = playerIns
|
|
57
|
+
|
|
58
|
+
playerIns.on('fullscreenchange', () => {
|
|
59
|
+
const isFullScreenNow = playerIns.isFullscreen()
|
|
60
|
+
if (isFullScreenNow) {
|
|
61
|
+
if (!isFullScreenRef.current) {
|
|
62
|
+
onRequestFullScreen()
|
|
63
|
+
}
|
|
64
|
+
isFullScreenRef.current = true
|
|
65
|
+
} else {
|
|
66
|
+
isFullScreenRef.current = false
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
playerIns.on('waiting', () => {
|
|
70
|
+
setIsLiveLoading(true)
|
|
71
|
+
})
|
|
72
|
+
playerIns.on('playing', () => {
|
|
73
|
+
setIsLiveLoading(false)
|
|
74
|
+
})
|
|
75
|
+
playerIns.on('ended', () => {
|
|
76
|
+
onStatusChange(PUBLIC_LIVE_STATUS.COMPLETEED)
|
|
77
|
+
})
|
|
78
|
+
playerIns.on('play', () => {
|
|
79
|
+
const currentTime = Date.now() - diffTime
|
|
80
|
+
const status = getRecordLiveStatus(liveInfo.status, currentTime, liveInfo.begin_time, liveInfo.end_time)
|
|
81
|
+
onStatusChange(status)
|
|
82
|
+
if (status === PUBLIC_LIVE_STATUS.LIVEING) {
|
|
83
|
+
player.current.currentTime(Math.max(0, (currentTime - dayjs(liveInfo.begin_time).valueOf()) / 1000))
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (!hasPlayed.current) {
|
|
87
|
+
onVideoPlay()
|
|
88
|
+
}
|
|
89
|
+
hasPlayed.current = true
|
|
90
|
+
|
|
91
|
+
player.current.autoplay(false)
|
|
92
|
+
setIsLiveLoadError(false)
|
|
93
|
+
})
|
|
94
|
+
playerIns.on('error', () => {
|
|
95
|
+
setIsLiveLoadError(true)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
const isLiving = liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
|
|
99
|
+
player.current.controls(isLiving && !needLogin)
|
|
100
|
+
if (isLiving) {
|
|
101
|
+
const currentTime = Math.max(0, (visitTime - dayjs(liveInfo.begin_time).valueOf()) / 1000)
|
|
102
|
+
player.current.currentTime(currentTime)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const handleVideoReload = () => {
|
|
107
|
+
if (player.current) {
|
|
108
|
+
player.current.autoplay(true)
|
|
109
|
+
player.current.load()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const handleStatusChange = (status, params = {}) => {
|
|
114
|
+
onStatusChange(status)
|
|
115
|
+
if (status === PUBLIC_LIVE_STATUS.LIVEING && params.play) {
|
|
116
|
+
player.current.play()
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const options = {
|
|
121
|
+
sources: [{
|
|
122
|
+
src: liveInfo.video_url,
|
|
123
|
+
type: getType(getUrlType(liveInfo.video_url))
|
|
124
|
+
}],
|
|
125
|
+
poster: liveInfo.cover_pic_web_url,
|
|
126
|
+
autoplay: false
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
return (
|
|
130
|
+
<div className={style['record-video']}>
|
|
131
|
+
<Video
|
|
132
|
+
className="vjs-big-play-centered"
|
|
133
|
+
options={options}
|
|
134
|
+
onReady={handleVideoReady}
|
|
135
|
+
/>
|
|
136
|
+
<LiveStatus
|
|
137
|
+
isStreamLive={isStreamLive}
|
|
138
|
+
userInfo={userInfo}
|
|
139
|
+
visitTime={visitTime}
|
|
140
|
+
diffTime={diffTime}
|
|
141
|
+
liveInfo={liveInfo}
|
|
142
|
+
isLiveLoading={isLiveLoading}
|
|
143
|
+
isLiveLoadError={isLiveLoadError}
|
|
144
|
+
onStatusChange={handleStatusChange}
|
|
145
|
+
onPlayReplay={onPlayReplay}
|
|
146
|
+
onReloadLive={handleVideoReload}
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
)
|
|
150
|
+
}
|
|
@@ -1,50 +1,82 @@
|
|
|
1
1
|
import { useEffect, useRef } from 'react'
|
|
2
2
|
import axios from 'axios'
|
|
3
3
|
import useIsMounted from '@/hook/useIsMounted'
|
|
4
|
+
import { PUBLIC_LIVE_STATUS } from '@/config/publicLive'
|
|
5
|
+
import { getOpenClassLiveSimple } from '@/service/live'
|
|
4
6
|
|
|
5
7
|
const pullInterval = 10 * 1000
|
|
8
|
+
const pullStatusInterval = 30 * 1000
|
|
9
|
+
const pullMultiply = pullStatusInterval / pullInterval
|
|
10
|
+
|
|
6
11
|
const pullTimeout = 10 * 1000
|
|
7
12
|
|
|
8
13
|
export default function usePullSource({
|
|
9
|
-
|
|
14
|
+
liveInfo,
|
|
10
15
|
reload,
|
|
16
|
+
onStatusChange,
|
|
11
17
|
shouldStartPull
|
|
12
18
|
}) {
|
|
19
|
+
const sourceSrc = liveInfo?.imInfo?.param?.url
|
|
20
|
+
|| liveInfo?.imInfo?.param?.playurl?.[0]
|
|
13
21
|
const isMounted = useIsMounted()
|
|
14
22
|
const counterIdRef = useRef()
|
|
15
23
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
24
|
+
const loopIndex = useRef()
|
|
25
|
+
const getIsCurrentLop = (index) => index <= loopIndex.current
|
|
26
|
+
|
|
27
|
+
async function checkLiveReadyInterval(i = 0) {
|
|
28
|
+
loopIndex.current = i
|
|
29
|
+
let liveStatus
|
|
30
|
+
if (i % pullMultiply === 0) {
|
|
31
|
+
liveStatus = await getLiveNewStatus(liveInfo)
|
|
32
|
+
if (getIsCurrentLop(i)) {
|
|
33
|
+
onStatusChange(liveStatus)
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (liveStatus !== PUBLIC_LIVE_STATUS.COMPLETEED
|
|
37
|
+
&& sourceSrc) {
|
|
38
|
+
const isSourceReady = await checkSourceReady(sourceSrc)
|
|
39
|
+
if (getIsCurrentLop(i)) {
|
|
40
|
+
if (isSourceReady && isMounted) {
|
|
41
|
+
reload()
|
|
42
|
+
return
|
|
30
43
|
}
|
|
31
|
-
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (isMounted && getIsCurrentLop(i)) {
|
|
47
|
+
counterIdRef.current = setTimeout(() => {
|
|
48
|
+
checkLiveReadyInterval(i + 1)
|
|
49
|
+
}, pullInterval)
|
|
50
|
+
}
|
|
32
51
|
}
|
|
33
52
|
|
|
34
53
|
useEffect(() => {
|
|
35
|
-
|
|
36
|
-
|
|
54
|
+
clearTimeout(counterIdRef.current)
|
|
55
|
+
if (shouldStartPull) {
|
|
56
|
+
counterIdRef.current = setTimeout(() => {
|
|
57
|
+
checkLiveReadyInterval(0)
|
|
58
|
+
}, pullInterval)
|
|
37
59
|
}
|
|
38
60
|
return () => {
|
|
39
|
-
if (
|
|
61
|
+
if (shouldStartPull) {
|
|
40
62
|
clearTimeout(counterIdRef.current)
|
|
41
63
|
}
|
|
42
64
|
}
|
|
43
|
-
}, [sourceSrc, shouldStartPull])
|
|
65
|
+
}, [sourceSrc, liveInfo.status, shouldStartPull])
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
async function checkSourceReady(url) {
|
|
69
|
+
try {
|
|
70
|
+
await axios.get(url, {
|
|
71
|
+
timeout: pullTimeout
|
|
72
|
+
})
|
|
73
|
+
return true
|
|
74
|
+
} catch (e) {
|
|
75
|
+
return false
|
|
76
|
+
}
|
|
44
77
|
}
|
|
45
78
|
|
|
46
|
-
async function
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
})
|
|
79
|
+
async function getLiveNewStatus(liveInfo) {
|
|
80
|
+
const newLiveInfo = await getOpenClassLiveSimple(liveInfo)
|
|
81
|
+
return newLiveInfo.status
|
|
50
82
|
}
|