{"record":{"id":"f64ea4ccb6f82f84","repo":"jackwener/OpenCLI","slug":"douyin-transcode-for-video-videoid","errorCode":null,"errorMessage":"Douyin transcode for video ${videoId}","messagePattern":"Douyin transcode for video (.+?)","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"clis/douyin/_shared/transcode.js","lineNumber":31,"sourceCode":"/**\n * Lower-level poll function that accepts an injected fetch function.\n * Exported for testability.\n */\nexport async function pollTranscodeWithFetch(fetchFn, page, videoId, timeoutMs = DEFAULT_TIMEOUT_MS) {\n    const url = `${TRANSCODE_URL_BASE}?video_id=${encodeURIComponent(videoId)}&aid=1128`;\n    const deadline = Date.now() + timeoutMs;\n    while (Date.now() < deadline) {\n        const result = (await fetchFn(page, 'GET', url));\n        if (result.encode === 2) {\n            return result;\n        }\n        // Wait before next poll, but don't exceed the deadline\n        const remaining = deadline - Date.now();\n        if (remaining <= 0)\n            break;\n        await new Promise(resolve => setTimeout(resolve, Math.min(POLL_INTERVAL_MS, remaining)));\n    }\n    throw new TimeoutError(`Douyin transcode for video ${videoId}`, Math.round(timeoutMs / 1000));\n}\n/**\n * Poll Douyin's transcode status endpoint until the video is fully transcoded\n * (encode=2) or the timeout expires.\n *\n * @param page - Browser page for making credentialed API calls\n * @param videoId - The video_id returned from the confirm upload step\n * @param timeoutMs - Maximum wait time in ms (default: 300 000 = 5 minutes)\n * @returns TranscodeResult including duration, fps, dimensions, and poster info\n * @throws TimeoutError if transcode does not complete within timeoutMs\n */\nexport async function pollTranscode(page, videoId, timeoutMs) {\n    return pollTranscodeWithFetch(browserFetch, page, videoId, timeoutMs);\n}\n","sourceCodeStart":13,"sourceCodeEnd":46,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/_shared/transcode.js#L13-L46","documentation":"pollTranscodeWithFetch polls Douyin's transcode status endpoint until encode=2 or the deadline passes; on timeout it throws this TimeoutError naming the videoId, meaning the video never finished transcoding within timeoutMs.","triggerScenarios":"pollTranscodeWithFetch(videoId, ...) called via pollTranscode loops past the deadline because the video is stuck in transcoding (encode never becomes 2) or polling requests keep failing silently.","commonSituations":"Very large/long videos exceeding the default timeout; Douyin backend congestion; invalid videoId so status never reaches done; authenticated polling requests rejected so status stays unknown.","solutions":["Increase the timeoutMs parameter and retry polling","Verify videoId is correct and check the video's status manually on creator.douyin.com","Re-check auth/cookies if status calls are failing so real progress is visible","Re-upload the video if the transcode job is permanently stuck server-side"],"exampleFix":"// before\nawait pollTranscode(page, videoId); // default timeout\n// after\nawait pollTranscode(page, videoId, { timeoutMs: 10 * 60 * 1000 });","handlingStrategy":"retry","validationCode":"if (!Number.isInteger(videoId) && !/^\\d+$/.test(String(videoId))) {\n  throw new Error(`invalid videoId: ${videoId}`);\n}","typeGuard":"function isValidVideoId(v) {\n  return typeof v === 'string' && /^\\d+$/.test(v);\n}","tryCatchPattern":"import { TimeoutError } from './_shared/transcode.js';\ntry { await pollTranscode(page, videoId); }\ncatch (e) {\n  if (e instanceof TimeoutError) {\n    console.warn(`transcode still pending for ${videoId}; extending deadline`);\n    await pollTranscode(page, videoId, { timeoutMs: 15 * 60 * 1000 });\n  } else throw e;\n}","preventionTips":["Set timeouts proportional to video duration/size","Confirm the videoId exists via the platform UI before polling","Log each poll's status payload to distinguish stuck vs failing polls","Surface TimeoutError separately from hard failures in your pipeline"],"tags":["timeout","polling","transcode","douyin"],"backgroundTag":"operation-timed-out","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}