// 点击"下载视频"时执行:优先从页面内嵌数据 RENDER_DATA 精确提取当前视频地址, // 其次才用嗅探列表兜底。 (function () { try { var pageUrl = location.href; // 从 URL 提取视频 ID var videoId = ""; var m = pageUrl.match(/[?&]modal_id=(\d+)/); if (m) videoId = m[1]; if (!videoId) { var m0 = pageUrl.match(/[?&]aweme_id=(\d+)/); if (m0) videoId = m0[1]; } if (!videoId) { var m2 = pageUrl.match(/\/(?:video|note)\/(\d+)/); if (m2) videoId = m2[1]; } // === 方案一:从 RENDER_DATA 里精确找当前视频的播放地址 === var renderVideoUrl = ""; var renderAudioUrl = ""; try { var rd = document.getElementById("RENDER_DATA"); if (rd && rd.textContent) { var decoded = decodeURIComponent(rd.textContent); // 在 JSON 里找 aweme_id 等于 videoId 的节点,提取其 video.play_addr 或 play_addr 列表 // 用正则粗匹配,避免完整 JSON 解析的复杂性 var idx = decoded.indexOf(videoId); while (idx >= 0) { // 在这个 ID 附近找 playApi / play_addr / url_list var chunk = decoded.substring(Math.max(0, idx - 200), idx + 5000); // 找 DASH 格式的视频轨和音频轨 var vMatches = chunk.match(/https?:\/\/[^"\\]+media-video[^"\\]*/gi); var aMatches = chunk.match(/https?:\/\/[^"\\]+media-audio[^"\\]*/gi); if (vMatches && vMatches.length) { renderVideoUrl = vMatches[vMatches.length - 1]; if (aMatches && aMatches.length) { renderAudioUrl = aMatches[aMatches.length - 1]; } break; } // 找普通 mp4 直链 var mp4Matches = chunk.match(/https?:\/\/[^"\\]*\.mp4[^"\\]*/gi); if (mp4Matches && mp4Matches.length) { renderVideoUrl = mp4Matches[mp4Matches.length - 1]; break; } idx = decoded.indexOf(videoId, idx + 1); } } } catch (e) { /* RENDER_DATA 解析失败就走嗅探兜底 */ } // === 方案二:选正在播放的