Install
openclaw skills install @chugenice/movie-finder搜索并播放电影。功能包括:(1) 按类型、年份、评分筛选电影;(2) 支持中英文输入;(3) 展示电影海报、评分、剧情简介;(4) 生成可点击的 iframe 播放页面,直接在线观看。触发场景包括:搜索电影、想看电影、找最新电影、按类型/年份/评分筛选电影。
openclaw skills install @chugenice/movie-finder安装说明见同目录
INSTALL.md。
| 场景 | 示例 |
|---|---|
| 按类型找片 | "想看一部科幻电影"、"recommend a comedy"、"恐怖片推荐" |
| 按年份找片 | "2024年科幻片"、"latest action movies"、"最近有什么好看的动作片" |
| 按评分找片 | "评分最高的科幻片"、"top rated thriller movies" |
| 按片名播放 | "搜一下《盗梦空间》"、"watch Inception online"、"盗梦空间在线看" |
| 仅查信息 | "这部电影讲什么"、"盗梦空间简介" |
| 参数 | 示例 | 提取方式 |
|---|---|---|
| genre | 科幻、sci-fi、动作 | 关键词匹配(见下方类型映射表) |
| year | 2024、2025、"最新"、"最近" | 正则 20\d{2};"最新/最近" → 当年 |
| rating | "评分最高"、"top rated"、"高分" | 关键词匹配 |
| keyword | 电影名、演员名 | 剩余文本 |
| intent | 播放 / 列表 / 仅信息 | 见下方意图分类 |
| 中文 | 英文 | TMDB genre_id |
|---|---|---|
| 科幻 | sci-fi / science fiction | 878 |
| 动作 | action | 28 |
| 喜剧 | comedy | 35 |
| 恐怖 | horror | 27 |
| 爱情 | romance | 10749 |
| 动画 | animation | 16 |
| 悬疑 | mystery | 9648 |
| 惊悚 | thriller | 53 |
| 冒险 | adventure | 12 |
| 奇幻 | fantasy | 14 |
| 剧情 | drama | 18 |
| 战争 | war | 10752 |
| 纪录片 | documentary | 99 |
| 犯罪 | crime | 80 |
| 家庭 | family | 10751 |
TMDB(The Movie Database)提供完整的电影元数据。优先用 API 获取:
搜索电影(按片名/关键词):
GET https://api.themoviedb.org/3/search/movie?api_key={KEY}&query={keyword}&language=zh-CN&page=1
按类型 + 年份发现电影:
GET https://api.themoviedb.org/3/discover/movie
?api_key={KEY}
&language=zh-CN
&sort_by=popularity.desc # 或 vote_average.desc 按评分
&with_genres={genre_id} # 见类型映射表
&primary_release_year={year} # 可选
&vote_average.gte={rating} # 可选,评分筛选
&page=1
获取电影详情(含导演、演员、时长):
GET https://api.themoviedb.org/3/movie/{movie_id}?api_key={KEY}&language=zh-CN&append_to_response=credits
关键字段:
id → TMDB ID(播放源需要)imdb_id → IMDb ID(部分播放源需要)title / release_date / vote_average / runtime / overviewposter_path → 海报 URL:https://image.tmdb.org/t/p/w500{poster_path}genres[].name → 类型credits.crew 中 job=Director → 导演credits.cast[].name → 主演(取前 3-5 位)API Key:TMDB API 需要 key。若环境中无可用 key,降级到 web_search。
无 API key 时,用 web_search 获取电影信息:
{movie_name} 电影 简介 评分 年份{year}年 {genre} 电影 推荐 豆瓣 / best {genre} movies {year}豆瓣 {genre} 高分电影 / top rated {genre} movies{movie_name} site:imdb.com{movie_name} site:themoviedb.org从搜索结果中提取:片名、年份、评分、简介、海报图 URL、IMDb ID(格式 tt\d{7,8})、TMDB ID。
拿到 IMDb ID 或 TMDB ID 后,按以下格式构造嵌入播放源 URL(无需额外 API):
| 源名称 | URL 格式 | 标识类型 | 可靠性 |
|---|---|---|---|
| vidsrc | https://vidsrc.net/embed/movie/{imdb_id} | IMDb ID | ★★★★ |
| vidsrc.to | https://vidsrc.to/embed/movie/{imdb_id} | IMDb ID | ★★★★ |
| 2embed | https://www.2embed.cc/embed/{imdb_id} | IMDb ID | ★★★ |
| superembed | https://multiembed.mov/?video_id={imdb_id} | IMDb ID | ★★★ |
| vidsrc (TMDB) | https://vidsrc.net/embed/movie?tmdb={tmdb_id} | TMDB ID | ★★★ |
用 IMDb ID 优先(兼容性最好)。至少构造 2-3 个源,方便用户在播放页切换。
{movie_name} watch online free embed使用脚本 scripts/generate_movie_page.py 生成播放页(推荐),或直接用 HTML 模板。
python scripts/generate_movie_page.py \
--title "盗梦空间" \
--year "2010" \
--rating "8.8" \
--plot "一个窃取梦境秘密的盗贼接到一项相反的任务..." \
--poster "https://image.tmdb.org/t/p/w500/9gk7adHYeDvHkCSEqAvQNLV5Uge.jpg" \
--runtime "148" \
--director "克里斯托弗·诺兰" \
--cast "莱昂纳多·迪卡普里奥, 约瑟夫·高登-莱维特" \
--genres "科幻,动作,悬疑" \
--sources '[{"name":"vidsrc","url":"https://vidsrc.net/embed/movie/tt1375666"},{"name":"2embed","url":"https://www.2embed.cc/embed/tt1375666"}]' \
--output movie_inception.html
脚本特性:
如果无法调用脚本,直接将以下模板写入 movie_{hash}.html,替换 __占位符__:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>__TITLE__ - 在线观看</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { background: linear-gradient(135deg, #0f0f1a 0%, #16213e 100%); color: #fff; font-family: 'Segoe UI', Arial, sans-serif; line-height: 1.6; padding: 20px; min-height: 100vh; }
.container { max-width: 1000px; margin: 0 auto; }
.movie-info { display: flex; gap: 30px; margin-bottom: 25px; background: rgba(255,255,255,0.05); padding: 25px; border-radius: 15px; flex-wrap: wrap; }
.poster { flex: 0 0 220px; }
.poster img { width: 100%; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.5); }
.details { flex: 1; min-width: 280px; }
.details h1 { font-size: 1.9em; margin-bottom: 12px; }
.meta-row { display: flex; gap: 16px; margin-bottom: 14px; flex-wrap: wrap; align-items: center; }
.rating-badge { background: rgba(245,197,24,0.15); color: #f5c518; padding: 4px 14px; border-radius: 20px; font-weight: bold; }
.year-badge { background: rgba(255,255,255,0.1); padding: 4px 14px; border-radius: 20px; }
.genres { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 14px; }
.genre-chip { background: rgba(255,255,255,0.08); padding: 3px 12px; border-radius: 15px; font-size: 0.82em; color: #aaa; }
.plot { line-height: 1.8; color: #ccc; margin-bottom: 14px; }
.player-wrapper { position: relative; padding-top: 56.25%; background: #000; border-radius: 12px; overflow: hidden; }
.player-wrapper iframe { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: none; }
.src-btn { padding: 7px 18px; background: rgba(255,255,255,0.08); color: #aaa; border: none; border-radius: 6px; cursor: pointer; }
.src-btn.active { background: #e50914; color: #fff; }
.footer { text-align: center; margin-top: 35px; color: #666; font-size: 0.82em; }
</style>
</head>
<body>
<div class="container">
<div class="movie-info">
<div class="poster"><img src="__POSTER__" alt="__TITLE__"></div>
<div class="details">
<h1>__TITLE__</h1>
<div class="meta-row">
<span class="year-badge">__YEAR__</span>
<span class="rating-badge">★ __RATING__</span>
<span>⏱ __RUNTIME__ 分钟</span>
<span>🎬 __DIRECTOR__</span>
</div>
<div class="genres">__GENRE_TAGS__</div>
<p class="plot">__PLOT__</p>
<p style="color:#aaa;font-size:0.9em;"><strong>主演:</strong>__CAST__</p>
</div>
</div>
<div class="player-wrapper">
<iframe id="playerFrame" src="__PRIMARY_SRC__" allowfullscreen></iframe>
</div>
<div style="margin:15px 0;display:flex;gap:8px;flex-wrap:wrap;">
<button class="src-btn active" data-src="__SRC1__" onclick="switchSource(this)">源1</button>
<button class="src-btn" data-src="__SRC2__" onclick="switchSource(this)">源2</button>
</div>
<div class="footer">播放源来自第三方,仅供学习交流,请支持正版</div>
</div>
<script>
function switchSource(btn) {
document.querySelectorAll('.src-btn').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
document.getElementById('playerFrame').src = btn.dataset.src;
}
</script>
</body>
</html>
🎬 找到以下电影:
1. 《{title}》({year}) ★{rating}
{plot_short}
2. 《{title}》({year}) ★{rating}
{plot_short}
...
请回复数字选择要播放的电影,或告诉我其他需求。
movie_{hash}.html找到《{title}》({year}),但暂未找到可用播放源。
📖 电影信息:
- 评分:{rating}
- 类型:{genres}
- 简介:{plot}
💡 建议:可尝试在 YouTube 搜索 "{title} full movie",或在正规流媒体平台观看。
tt 开头),部分支持 TMDB ID。搜索元数据时优先获取这两个 IDhttps://image.tmdb.org/t/p/w500{poster_path}primary_release_date.desc 或 popularity.desc 排序discover 接口加 vote_average.gte 参数;web_search 时搜 "高分/豆瓣评分"{movie_name} watch online embed {imdb_id}