fix: fix no auto recording for live streaming that has no flv streams

fix #183
This commit is contained in:
acgnhik 2023-10-07 11:27:45 +08:00
parent 457a974ab7
commit 79372d23ce
2 changed files with 34 additions and 21 deletions

View File

@ -239,15 +239,9 @@ class Live:
# the timestamp on the server at the moment in seconds
return await self._webapi.get_timestamp()
async def get_live_stream_url(
self,
qn: QualityNumber = 10000,
*,
api_platform: ApiPlatform = 'web',
stream_format: StreamFormat = 'flv',
stream_codec: StreamCodec = 'avc',
select_alternative: bool = False,
) -> str:
async def get_live_streams(
self, qn: QualityNumber = 10000, api_platform: ApiPlatform = 'web'
) -> List[Any]:
if api_platform == 'web':
paly_infos = await self._webapi.get_room_play_infos(self._room_id, qn)
else:
@ -257,13 +251,28 @@ class Live:
self._check_room_play_info(info)
streams = jsonpath(paly_infos, '$[*].playurl_info.playurl.stream[*]')
return streams
async def get_live_stream_url(
self,
qn: QualityNumber = 10000,
*,
api_platform: ApiPlatform = 'web',
stream_format: StreamFormat = 'flv',
stream_codec: StreamCodec = 'avc',
select_alternative: bool = False,
) -> str:
streams = await self.get_live_streams(qn, api_platform=api_platform)
if not streams:
raise NoStreamAvailable(stream_format, stream_codec, qn)
formats = jsonpath(
streams, f'$[*].format[?(@.format_name == "{stream_format}")]'
)
if not formats:
raise NoStreamFormatAvailable(stream_format, stream_codec, qn)
codecs = jsonpath(formats, f'$[*].codec[?(@.codec_name == "{stream_codec}")]')
if not codecs:
raise NoStreamCodecAvailable(stream_format, stream_codec, qn)

View File

@ -83,6 +83,9 @@ class LiveMonitor(EventEmitter[LiveEventListener], DanmakuListener, SwitchableMi
def _start_checking(self) -> None:
self._checking_task = asyncio.create_task(self._check_if_stream_available())
self._checking_task.add_done_callback(exception_callback)
asyncio.get_running_loop().call_later(
1800, lambda: asyncio.create_task(self._stop_checking())
)
logger.debug('Started checking if stream available')
async def _stop_checking(self) -> None:
@ -147,19 +150,16 @@ class LiveMonitor(EventEmitter[LiveEventListener], DanmakuListener, SwitchableMi
self._status_count = 0
self._stream_available = False
await self._emit('live_ended', self._live)
await self._stop_checking()
else:
self._status_count += 1
if self._status_count == 1:
assert self._previous_status != LiveStatus.LIVE
self._start_checking()
await self._emit('live_began', self._live)
self._start_checking()
elif self._status_count == 2:
assert self._previous_status == LiveStatus.LIVE
if not self._stream_available:
self._stream_available = True
await self._stop_checking()
await self._emit('live_stream_available', self._live)
elif self._status_count > 2:
assert self._previous_status == LiveStatus.LIVE
await self._emit('live_stream_reset', self._live)
@ -181,11 +181,15 @@ class LiveMonitor(EventEmitter[LiveEventListener], DanmakuListener, SwitchableMi
@aio_task_with_room_id
async def _check_if_stream_available(self) -> None:
while not self._stream_available:
while True:
try:
await self._live.get_live_stream_url()
except Exception:
await asyncio.sleep(1)
else:
self._stream_available = True
await self._emit('live_stream_available', self._live)
streams = await self._live.get_live_streams()
if streams:
logger.debug('live stream available')
self._stream_available = True
await self._emit('live_stream_available', self._live)
break
except Exception as e:
logger.warning(f'Failed to get live streams: {repr(e)}')
await asyncio.sleep(1)