ZhangMingZhao1 / StreamerHelper

全平台主播录制+投稿 工具/服务
MIT License
1.13k stars 175 forks source link

fix: #167 奇怪的异常退出 bug #193

Closed Xbai-hang closed 4 months ago

Xbai-hang commented 4 months ago

bug 描述

167

当 downloads 文件夹下对应主播的某个时段文件夹(例:downloads/test/2024-04-27 下午)存在时(下称文件夹),即使主播正常直播,且直播流获取正常,仍然会异常退出:[2024-04-27T15:42:09.303] [INFO] Recorder test - 下载流 test 退出,退出码: 1,目录:xxx\StreamerHelper\download\test\2024-04-27 下午

bug 定位

src/engine/message.ts line: 64-82

if (!fs.existsSync(pathWithTimeV)) {
fs.mkdirSync(pathWithTimeV)
} else if (this.isPost || uploadStatus.get(pathWithTimeV) === 1) {
// 正在上传或者已经投稿
const curTime = dayjs().format("HH-mm")
const newPath = `${pathWithTimeV} ${curTime}`
roomPathStatus.delete(this.savePath)
this.savePath = newPath
this._recorderTask.timeV = `${this._recorderTask.timeV} ${curTime}`
fs.mkdirSync(newPath)
} else {
const ps = FileHound
.create()
.ext(this.videoExt)
.path(join(this.savePath))
.findSync()
.length;
startNumber = ps - 1
}

当由于某种原因(例如获取到失效的直播流),会导致创建出这样的文件夹以及 fileStatus.json 文件而没有开始录制。等到下一次检查房间时,即使获取到正确的直播流也会导致无法录制。具体原因见下章

bug 分析

当文件夹存在时,会由于 if-else if-else 语句原因进入 else 分支,而当发生上章的情况时:

const ps = FileHound
.create()
.ext(this.videoExt)
.path(join(this.savePath))
.findSync()
.length;
startNumber = ps - 1

else 分支的代码会得到 ps = 0, startNumber=-1 ,进行此后的录制工作,从而导致了 ffmpeg 的参数异常:

[2024-04-27T15:42:06.484] [INFO] checkRoom - 正在检查直播 test https://xxx/xxx
[2024-04-27T15:42:06.801] [DEBUG] checkRoom - stream {// 无关紧要,略}
[2024-04-27T15:42:06.806] [INFO] Recorder test - 开始下载: test, 直播流: xxx
[2024-04-27T15:42:06.809] [DEBUG] Recorder test - 文件夹存在:ps=0 ===> startNumber = -1
[2024-04-27T15:42:06.809] [INFO] Recorder test - 记录相关信息到文件 test,目录:D:\Xbai-hang\Desktop\tuition\StreamerHelper\download\test\2024-04-27 下午
[2024-04-27T15:42:06.811] [INFO] Recorder test - Create fileStatus.json: {// 无关紧要,略}
[2024-04-27T15:42:08.633] [DEBUG] Recorder test - ffmpeg version n5.0.1-4-ga5ebb3d25e-20220522 Copyright (c) 2000-2022 the FFmpeg developers
[2024-04-27T15:42:09.201] [DEBUG] Recorder test - Input #0, flv, from 'xxx':
====== 👇BUG👇====== 
[(stream) segment muxer @ 0000026d6cc8e940] Value -1.000000 for parameter 'segment_start_number' out of range [0 - 2.14748e+09]
[(stream) segment muxer @ 0000026d6cc8e940] Error setting option segment_start_number to value -1.
====== 👆BUG👆====== 
Could not write header for output file #0 (incorrect codec parameters ?): Result too large
Error initializing output stream 0:1 --
Stream mapping:
Stream #0:1 -> #0:0 (copy)
Stream #0:0 -> #0:1 (copy)
[2024-04-27T15:42:09.206] [ERROR] Recorder test -     Last message repeated 1 times
[2024-04-27T15:42:09.303] [INFO] Recorder test - 下载流 test 退出,退出码: 1,目录:xxx\StreamerHelper\download\test\2024-04-27 下午
[2024-04-27T15:42:09.303] [INFO] Recorder test - 记录退出时间 test
[2024-04-27T15:42:09.304] [INFO] Recorder test - Write Content - endRecordTime {// 无关紧要,略}

bug 解决

方案1:

PR 中的解决方案,startNumber = ps - 1 > 0 ? ps - 1 : 0 好处是解决了 bug 且维持原项目逻辑无任何变化

方案2:

startNumber = ps 解决了 bug,但会改变项目逻辑,原项目逻辑: 假如文件夹下有 2个mp4文件,000.mp4001.mp4,会将本次直播流录进 001.mp4,即方案1,而方案2则会录进 002.mp4

umuoy1 commented 4 months ago

thanks