diff --git a/skills/obsidian-kb/SKILL.md b/skills/obsidian-kb/SKILL.md index b042301..37ba5ee 100644 --- a/skills/obsidian-kb/SKILL.md +++ b/skills/obsidian-kb/SKILL.md @@ -1,10 +1,27 @@ --- name: obsidian-kb -description: Multi-source content knowledge base maintenance system with long video segment analysis. Use when managing Obsidian vaults, processing video content from Bilibili/YouTube/Zhihu, or generating markdown notes from videos. +description: Multi-source content knowledge base with video processing. Auto-triggers on B站/bilibili video links (BV号, b23.tv, www.bilibili.com), YouTube videos, or Zhihu articles. Use when user mentions adding videos to inbox, processing video content, extracting subtitles, or generating markdown notes from B站/YouTube/Zhihu content. --- # SKILL.md - Obsidian KB Skill +## 🚀 重要:处理流程 + +**当用户发送视频链接并要求保存到知识库时,直接处理,不要问用户!** + +正确流程: +1. 用户发送B站链接(BV号、完整URL、或短链接如 b23.tv/xxxxx) +2. 用户说"保存到知识库"、"添加到知识库"、"处理这个视频"等 +3. **直接使用** `workspace/skills/obsidian-kb` 处理 +4. 不要检查全局命令,不要问用户"要安装工具还是手动处理" + +**示例触发词:** +- "保存到知识库" +- "添加到知识库" +- "处理这个视频" +- "提取字幕生成笔记" +- "生成obsidian笔记" + ## 元数据 - **名称**: obsidian-kb diff --git a/skills/obsidian-kb/src/extractors/bilibili_extractor.py b/skills/obsidian-kb/src/extractors/bilibili_extractor.py index d0eade3..0472250 100644 --- a/skills/obsidian-kb/src/extractors/bilibili_extractor.py +++ b/skills/obsidian-kb/src/extractors/bilibili_extractor.py @@ -92,6 +92,15 @@ class BilibiliExtractor(Extractor): # 解析并获取BV号 bvid = self._resolve_bvid(source_id) + + # 如果解析失败,检查是否为短链接 + if not bvid and self.resolver.is_bilibili_short_link(source_id): + # 使用Playwright解析短链接 + try: + bvid = asyncio.run(self._resolve_shortlink_bvid(source_id)) + except Exception as e: + raise ExtractionError(f"短链接解析失败: {e}", source_id=source_id) + if not bvid: raise ExtractionError(f"无法解析BV号: {source_id}", source_id=source_id) @@ -123,13 +132,66 @@ class BilibiliExtractor(Extractor): if url_match: return url_match.group(1) - # 3. 检查是否为短链接 - if self.resolver.is_bilibili_short_link(source_id): - # 短链接需要Playwright解析,这里返回None让调用方处理 - # 或者可以在这里尝试解析,但这会使得方法变复杂 - # 为了简化,我们假设用户会提供完整URL或BV号 - # 短链接解析可以在extract方法中通过Playwright完成 - pass + # 3. 短链接处理已移至 extract() 方法中的 _resolve_shortlink_bvid() + # 这里不再处理,避免混淆 + + return None + + async def _resolve_shortlink_bvid(self, shortlink: str) -> Optional[str]: + """ + 使用 Playwright 解析B站短链接,获取 BV 号 + + Args: + shortlink: B站短链接(如 https://b23.tv/xxxxx) + + Returns: + BV号字符串,解析失败返回None + """ + async with async_playwright() as playwright: + browser = None + try: + # 启动浏览器(stealth 模式) + browser = await playwright.chromium.launch( + headless=self.headless, + args=[ + '--no-sandbox', + '--disable-setuid-sandbox', + '--disable-blink-features=AutomationControlled', + '--disable-dev-shm-usage', + '--start-maximized', + ] + ) + + context = await browser.new_context( + viewport={'width': 1920, 'height': 1080}, + user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36', + locale='zh-CN', + timezone_id='Asia/Shanghai', + ) + + # 应用 stealth 模式(如果可用) + if STEALTH_AVAILABLE: + await stealth_async(context) + + page = await context.new_page() + + # 访问短链接(等待重定向完成) + await page.goto(shortlink, wait_until='domcontentloaded', timeout=self.timeout) + await asyncio.sleep(3) # 等待重定向完成 + + # 获取重定向后的 URL + final_url = page.url + + # 从 URL 中提取 BV 号 + bv_match = re.search(r'BV[a-zA-Z0-9]{10}', final_url) + if bv_match: + return bv_match.group(0) + + except Exception as e: + raise ExtractionError(f"短链接解析异常: {e}", source_id=shortlink) + finally: + if browser: + await browser.close() return None