Skill: sjzai/qushuiyin (version 1.0.0)

--- name: video-download description: 短视频去水印下载。检测到抖音、快手、小红书、B站、微博、西瓜视频等平台链接时，自动解析并下载无水印视频，直接发送文件给用户。 --- # Video Download Skill ## 触发条件 用户消息中包含以下任意短视频平台链接时，**无需任何触发词，自动执行**： - 抖音: `v.douyin.com` / `douyin.com` - 快手: `v.kuaishou.com` / `kuaishou.com` - 小红书: `xhslink.com` / `xiaohongshu.com` - B站: `b23.tv` / `bilibili.com` - 微博: `weibo.com` - 西瓜视频: `ixigua.com` ## 执行步骤 1. 从消息中提取 URL（正则: `https?://[^\s]+`，匹配上述域名） 2. 运行脚本： ```bash python3 /root/.openclaw/skills/video-download/scripts/download.py '<url>' ``` 3. 解析输出： - 成功（`SUCCESS:`开头）→ 回复下载链接 - 失败（`FAIL:`开头）→ 回复错误原因 ## 回复格式 成功后： 1. 用 `message` 工具直接发送视频文件（`media` 参数填本地文件路径，`channel` 对应来源频道） 2. 回复文字：✅ 无水印视频已发送 如果发文件失败，则回复下载链接： > ✅ 无水印视频：http://81.70.156.92:8899/videos/xxx.mp4 失败： > ❌ 解析失败：<原因> ## 注意事项 - 不需要 Cookie，使用第三方 API 解析 - 文件保存于 `/www/wwwroot/default/videos/`，通过 nginx 8899 端口提供下载 - 支持抖音分享文字（含杂文字），自动提取 URL

path: scripts/download.py
content: #!/usr/bin/env python3
import requests
import sys
import os
import time

APP_ID = '115962'
APP_KEY = '密钥'
API_URL = 'https://qyapi.ipaybuy.cn/api/video'
SERVER_IP = '服务器ip'
VIDEO_DIR = '/www/wwwroot/default/videos'
BASE_URL = f'http://{SERVER_IP}:8899/videos'

def get_no_watermark_url(video_url: str) -> dict:
    headers = {'Content-Type': 'application/json'}
    data = {'appId': APP_ID, 'appKey': APP_KEY, 'url': video_url}
    resp = requests.post(API_URL, headers=headers, json=data, timeout=15)
    resp.raise_for_status()
    return resp.json()

def extract_download_url(result: dict) -> str | None:
    data = result.get('data') or {}
    if isinstance(data, str):
        return data if data.startswith('http') else None
    candidates = [
        data.get('url'), data.get('video_url'), data.get('video'),
        data.get('play_url'), data.get('wm_free_video_url'),
        result.get('url'), result.get('video_url'),
    ]
    for c in candidates:
        if c and isinstance(c, str) and c.startswith('http'):
            return c
    return None

def download_video(download_url: str, output_path: str) -> str:
    headers = {'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15'}
    resp = requests.get(download_url, stream=True, timeout=60, headers=headers, allow_redirects=True)
    resp.raise_for_status()
    with open(output_path, 'wb') as f:
        for chunk in resp.iter_content(chunk_size=65536):
            if chunk:
                f.write(chunk)
    return output_path

def process(video_url: str) -> dict:
    os.makedirs(VIDEO_DIR, exist_ok=True)
    result = get_no_watermark_url(video_url)
    if result.get('code') not in (200, 0):
        return {'success': False, 'error': result.get('msg', '解析失败')}
    dl_url = extract_download_url(result)
    if not dl_url:
        return {'success': False, 'error': f'未找到下载链接，API返回: {result}'}
    filename = f'video_{int(time.time())}.mp4'
    output_path = os.path.join(VIDEO_DIR, filename)
    download_video(dl_url, output_path)
    size = os.path.getsize(output_path)
    public_url = f'{BASE_URL}/{filename}'
    return {'success': True, 'path': output_path, 'size': size, 'public_url': public_url}

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print('FAIL:未提供链接')
        sys.exit(1)
    res = process(sys.argv[1])
    if res['success']:
        print(f"SUCCESS:{res['public_url']}:{res['size']}")
    else:
        print(f"FAIL:{res['error']}")
        sys.exit(1)


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)