@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@x-edu/live-player",
3
- "version": "0.0.16",
3
+ "version": "0.0.18",
4
4
  "main": "dist/XEduLivePlayer.common.js",
5
5
  "scripts": {
6
6
  "start": "cross-env SDP_ENV=local gms dev",
@@ -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
- sourceSrc,
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>加载中...</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>等待开播中...</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, SUB_TYPE } from '@/config/publicLive'
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
- {isLiveLoadError && (
73
- <>
74
- <div className={style['status-load-error']}>
75
- <Icon type="exclamation-circle" className={style.icon} />
76
- <div className={style.text}>加载失败,请重试</div>
77
- </div>
78
- <button className={style['primary-btn']} onClick={onReloadLive}>重试</button>
79
- </>
80
- )}
81
- {!isLiveLoadError && isLiveException && (
82
- <AnchorOnTheWay
83
- liveInfo={liveInfo}
84
- isStreamLive={isStreamLive}
85
- hasPlayed={hasPlayed}
86
- reload={onReloadLive}
87
- />
88
- )}
89
- {!isLiveLoadError && !isLiveException && isLiveLoading && (
90
- <div className={style['status-living-loading']}>
91
- <Spin indicator={(
92
- <Icon type="loading" spin className={style.icon} />
93
- )}
94
- />
95
- <div className={style.text}>加载中...</div>
96
- </div>
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 className={style['video-poster']} style={coverBgStyle} />
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
- userInfo,
12
- liveInfo,
13
- visitTime,
14
- diffTime,
15
- onStatusChange,
16
- onPlayReplay,
17
- onVideoPlay = () => undefined,
18
- onRequestFullScreen = () => undefined
19
- }) {
20
- const isFullScreenRef = useRef(false)
21
- const [isLiveLoading, setIsLiveLoading] = useState(false)
22
- const [isLiveLoadError, setIsLiveLoadError] = useState(false)
23
- const hasPlayed = useRef(false)
24
- const player = useRef()
25
- const endTimer = useRef()
26
- const needLogin = !userInfo && liveInfo.login
27
-
28
- useEffect(() => {
29
- const isLiving = liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
30
- if (isLiving && needLogin) {
31
- const timeToEnd = dayjs(liveInfo.end_time).valueOf() - (Date.now() - diffTime)
32
- if (timeToEnd > 0) {
33
- endTimer.current = setTimeout(() => {
34
- onStatusChange(PUBLIC_LIVE_STATUS.COMPLETEED)
35
- }, timeToEnd)
36
- }
37
- }
38
-
39
- if (player.current) {
40
- player.current.controls(isLiving && !needLogin)
41
-
42
- // 显示成封面
43
- if (liveInfo.status === PUBLIC_LIVE_STATUS.COMPLETEED || liveInfo.status === PUBLIC_LIVE_STATUS.OFFLINE) {
44
- player.current.autoplay(false)
45
- player.current.load()
46
- }
47
- }
48
-
49
- return () => {
50
- clearTimeout(endTimer.current)
51
- }
52
- }, [liveInfo.status, userInfo])
53
-
54
- const handleVideoReady = (v, playerIns) => {
55
- player.current = playerIns
56
-
57
- playerIns.on('fullscreenchange', () => {
58
- const isFullScreenNow = playerIns.isFullscreen()
59
- if (isFullScreenNow) {
60
- if (!isFullScreenRef.current) {
61
- onRequestFullScreen()
62
- }
63
- isFullScreenRef.current = true
64
- } else {
65
- isFullScreenRef.current = false
66
- }
67
- })
68
- playerIns.on('waiting', () => {
69
- setIsLiveLoading(true)
70
- })
71
- playerIns.on('playing', () => {
72
- setIsLiveLoading(false)
73
- })
74
- playerIns.on('ended', () => {
75
- onStatusChange(PUBLIC_LIVE_STATUS.COMPLETEED)
76
- })
77
- playerIns.on('play', () => {
78
- const currentTime = Date.now() - diffTime
79
- const status = getRecordLiveStatus(liveInfo.status, currentTime, liveInfo.begin_time, liveInfo.end_time)
80
- onStatusChange(status)
81
- if (status === PUBLIC_LIVE_STATUS.LIVEING) {
82
- player.current.currentTime(Math.max(0, (currentTime - dayjs(liveInfo.begin_time).valueOf()) / 1000))
83
- }
84
-
85
- if (!hasPlayed.current) {
86
- onVideoPlay()
87
- }
88
- hasPlayed.current = true
89
-
90
- player.current.autoplay(false)
91
- setIsLiveLoadError(false)
92
- })
93
- playerIns.on('error', () => {
94
- setIsLiveLoadError(true)
95
- })
96
-
97
- const isLiving = liveInfo.status === PUBLIC_LIVE_STATUS.LIVEING
98
- player.current.controls(isLiving && !needLogin)
99
- if (isLiving) {
100
- const currentTime = Math.max(0, (visitTime - dayjs(liveInfo.begin_time).valueOf()) / 1000)
101
- player.current.currentTime(currentTime)
102
- }
103
- }
104
-
105
- const handleVideoReload = () => {
106
- if (player.current) {
107
- player.current.autoplay(true)
108
- player.current.load()
109
- }
110
- }
111
-
112
- const handleStatusChange = (status, params = {}) => {
113
- onStatusChange(status)
114
- if (status === PUBLIC_LIVE_STATUS.LIVEING && params.play) {
115
- player.current.play()
116
- }
117
- }
118
-
119
- const options = {
120
- sources: [{
121
- src: liveInfo.video_url,
122
- type: getType(getUrlType(liveInfo.video_url))
123
- }],
124
- poster: liveInfo.cover_pic_web_url,
125
- autoplay: false
126
- }
127
-
128
- return (
129
- <div className={style['record-video']}>
130
- <Video
131
- className="vjs-big-play-centered"
132
- options={options}
133
- onReady={handleVideoReady}
134
- />
135
- <LiveStatus
136
- userInfo={userInfo}
137
- visitTime={visitTime}
138
- diffTime={diffTime}
139
- liveInfo={liveInfo}
140
- isLiveLoading={isLiveLoading}
141
- isLiveLoadError={isLiveLoadError}
142
- onStatusChange={handleStatusChange}
143
- onPlayReplay={onPlayReplay}
144
- onReloadLive={handleVideoReload}
145
- />
146
- </div>
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
- sourceSrc,
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
- function checkSourceReadyInterval() {
17
- isSourceReady(sourceSrc)
18
- .then(
19
- () => {
20
- if (isMounted) {
21
- reload()
22
- }
23
- },
24
- () => {
25
- if (isMounted) {
26
- counterIdRef.current = setTimeout(() => {
27
- checkSourceReadyInterval()
28
- }, pullInterval)
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
- if (sourceSrc && shouldStartPull) {
36
- checkSourceReadyInterval()
54
+ clearTimeout(counterIdRef.current)
55
+ if (shouldStartPull) {
56
+ counterIdRef.current = setTimeout(() => {
57
+ checkLiveReadyInterval(0)
58
+ }, pullInterval)
37
59
  }
38
60
  return () => {
39
- if (sourceSrc && shouldStartPull) {
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 isSourceReady(url) {
47
- return axios.get(url, {
48
- timeout: pullTimeout
49
- })
79
+ async function getLiveNewStatus(liveInfo) {
80
+ const newLiveInfo = await getOpenClassLiveSimple(liveInfo)
81
+ return newLiveInfo.status
50
82
  }