diff --git a/src/main/crawler/capture-error.js b/src/main/crawler/capture-error.js index c5e4ba2..42db523 100644 --- a/src/main/crawler/capture-error.js +++ b/src/main/crawler/capture-error.js @@ -10,11 +10,17 @@ const log = debug('fideo-crawler-capture-error') */ export function captureError(fn) { return async function (...args) { + const writeLog = args[args.length - 1] + const realArgs = args.slice(0, args.length - 1) try { - return await fn.apply(this, args) + const res = await fn.apply(this, realArgs) + writeLog(`Fetch Live Res: ${JSON.stringify(res, null, 2)}`) + return res } catch (e) { const message = e.message + writeLog(`Fetch Live Error: ${message}`) + log('error:', message) // if (message.includes('timeout')) { diff --git a/src/main/crawler/index.js b/src/main/crawler/index.js index 2c93bbf..082d7f1 100644 --- a/src/main/crawler/index.js +++ b/src/main/crawler/index.js @@ -91,7 +91,7 @@ const supportPlatform = [ * @param {{ url: string, proxy?: string, cookie?: string }} info * @returns {Promise<{code: number, liveUrls?: string[]}>} */ -export async function getLiveUrls(info) { +export async function getLiveUrls(info, writeLog) { const { roomUrl, proxy, cookie } = info let host try { @@ -112,7 +112,7 @@ export async function getLiveUrls(info) { } } - const res = await getLiveUrlsFn(roomUrl, { proxy, cookie }) + const res = await getLiveUrlsFn(roomUrl, { proxy, cookie }, writeLog) log('res:', res) return res } diff --git a/src/main/ffmpeg/record.ts b/src/main/ffmpeg/record.ts index aeefe15..8680d01 100644 --- a/src/main/ffmpeg/record.ts +++ b/src/main/ffmpeg/record.ts @@ -81,7 +81,7 @@ const checkFileExist = async (filepath: string) => { }) } -async function convertFlvToMp4(sourcePath: string) { +async function convertFlvToMp4(sourcePath: string, writeLog: (content: string) => void) { if (!(await checkFileExist(sourcePath))) return const process = ffmpeg() const output = sourcePath.replace(FLV_FLAG, '.mp4') @@ -96,11 +96,16 @@ async function convertFlvToMp4(sourcePath: string) { .audioCodec('copy') .inputFormat('flv') .outputFormat('mp4') + .on('start', () => { + writeLog(`Convert Flv To Mp4 Start: ${sourcePath}`) + }) .on('end', () => { fs.unlinkSync(sourcePath) + writeLog(`Convert Flv To Mp4 Success: ${sourcePath}`) _resolve() }) .on('error', () => { + writeLog(`Convert Flv To Mp4 Error: ${sourcePath}`) _resolve() }) .save(output) @@ -108,7 +113,11 @@ async function convertFlvToMp4(sourcePath: string) { return p } -async function convert(sourcePath: string, convertToMP4 = true) { +async function convert( + sourcePath: string, + writeLog: (content: string) => void, + convertToMP4 = true +) { if (!convertToMP4) return if (!(await checkFileExist(sourcePath))) return const stats = fs.statSync(sourcePath) @@ -122,10 +131,10 @@ async function convert(sourcePath: string, convertToMP4 = true) { .map((file) => path.join(sourcePath, file)) for (const flvFile of flvFiles) { - await convertFlvToMp4(flvFile) + await convertFlvToMp4(flvFile, writeLog) } } else { - await convertFlvToMp4(sourcePath) + await convertFlvToMp4(sourcePath, writeLog) } } @@ -195,6 +204,7 @@ async function detectStreamResolution(streamConfig: IStreamConfig) { export async function recordStream( streamConfig: IStreamConfig, + writeLog: (title: string, content: string) => void, cb?: (code: number, errMsg?: string) => void ) { log('start record stream') @@ -224,6 +234,8 @@ export async function recordStream( detectResolution } = streamConfig + writeLog(title, `RecordStream Config: ${JSON.stringify(streamConfig, null, 2)}`) + detectResolution && detectStreamResolution(streamConfig) const secondSegmentTime = Number(segmentTime) * 60 @@ -239,6 +251,7 @@ export async function recordStream( } if (recordStreamFfmpegProcessMap[title] !== RECORD_DUMMY_PROCESS) { + writeLog(title, 'Record Stream is Killed') _resolve({ code: FFMPEG_ERROR_CODE.USER_KILL_PROCESS }) @@ -278,6 +291,9 @@ export async function recordStream( .audioCodec('copy') .on('start', (...args) => { log('record live start', args.join(' ')) + + writeLog(title, `Record Live Start: ${args.join(' ')}`) + _resolve({ code: SUCCESS_CODE }) @@ -290,17 +306,19 @@ export async function recordStream( const msg = args.join(' ') log('record live end: ', msg) + writeLog(title, `Record Live End: ${msg}`) killRecordStreamFfmpegProcess(title) cb?.(SUCCESS_CODE) - await convert(convertSource, convertToMP4) + await convert(convertSource, writeLog.bind(null, title), convertToMP4) cb?.(SUCCESS_CODE) }) .on('error', async (error) => { const errMsg = error.message - log('record live error: ', errMsg) + log('record live error: ', errMsg) + writeLog(title, `Record Live Error: ${errMsg}`) const isResolutionChange = resolutionChangeSet.has(title) // 清空数据 killRecordStreamFfmpegProcess(title) @@ -319,7 +337,7 @@ export async function recordStream( } cb?.(errCode, errMsg) - await convert(convertSource, convertToMP4) + await convert(convertSource, writeLog.bind(null, title), convertToMP4) cb?.(errCode, errMsg) }) .save(output + FLV_FLAG) diff --git a/src/main/index.ts b/src/main/index.ts index b846732..20c3b6a 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -41,6 +41,10 @@ import { downloadReq } from './ffmpeg' +import { writeLogWrapper } from './log/index' + +export const writeLog = writeLogWrapper(app.getPath('userData')) + async function checkUpdate() { try { const json = await fetch( @@ -152,7 +156,6 @@ function showNotification(title: string, body: string) { async function handleMakeSureDependenciesExist() { const userDataPath = app.getPath('userData') - console.log('userDataPath:', userDataPath) const [isFFmpegExist, isFfprobeExist] = await Promise.all([ checkFfmpegExist(userDataPath), checkFfprobeExist(userDataPath) @@ -216,7 +219,11 @@ app.whenReady().then(async () => { */ setRecordStreamFfmpegProcessMap(title, RECORD_DUMMY_PROCESS) - const { code: liveUrlsCode, liveUrls } = await getLiveUrls({ roomUrl, proxy, cookie }) + const { code: liveUrlsCode, liveUrls } = await getLiveUrls( + { roomUrl, proxy, cookie }, + writeLog.bind(null, title) + ) + if (liveUrlsCode !== SUCCESS_CODE) { return { code: liveUrlsCode @@ -226,6 +233,7 @@ app.whenReady().then(async () => { const { code: recordStreamCode } = await recordStream( streamConfig, + writeLog, (code: number, errMsg?: string) => { win?.webContents.send(STREAM_RECORD_END, title, code, errMsg) clearTimerWhenAllFfmpegProcessEnd() diff --git a/src/main/log/index.ts b/src/main/log/index.ts new file mode 100644 index 0000000..313ef39 --- /dev/null +++ b/src/main/log/index.ts @@ -0,0 +1,29 @@ +import fsp from 'node:fs/promises' +import path from 'node:path' +import dayjs from 'dayjs' + +export function writeLogWrapper(baseDir: string) { + const logPrefixPath = path.resolve(baseDir, 'logs') + console.log('logPrefixPath:', logPrefixPath) + return async (title: string, content: string) => { + const logPath = path.resolve(logPrefixPath, title) + return fsp + .mkdir(logPath, { recursive: true }) + .catch((e) => { + console.log(e) + }) + .then(() => { + const logFilePath = path.resolve(logPath, `${dayjs().format('YYYY-MM-DD')}.txt`) + content = `[${dayjs().format('YYYY-MM-DD HH:mm:ss')}] ${content}` + fsp + .readFile(logFilePath, 'utf8') + .then((existingContent) => { + const prefix = existingContent ? '\n' : 'Fideo LOG: \n' + return fsp.appendFile(logFilePath, `${prefix}${content}`) + }) + .catch(() => { + return fsp.writeFile(logFilePath, `Fideo LOG: \n${content}`) + }) + }) + } +}