Token导航 LogoToken导航TokenDH.com
研究检索敏感数据clawhub未标认证来源可访问clear审计提醒

tiktok-motivation-video抖音励志视频

Agent Skill

用于辅助视频生成、动画合成、脚本化剪辑或 Remotion 等视频项目开发。它适合让 Agent 组织镜头、生成素材说明、维护合成代码或排查渲染问题。使用时需要确认分辨率、时长、素材路径和导出格式;涉及外部素材、人物肖像或商业发布时,应先核对版权授权和内容审核要求。

总安装

23,028

周安装

950

GitHub Stars

2

下载量

7,524
OpenClaw

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

MIT-0

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:tiktok-motivation-video(抖音励志视频)
来源仓库:https://github.com/thuongvh2-python/tiktok-motivation-video
安装命令:
openclaw skills install tiktok-motivation-video
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 OpenClaw 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

ClawHubOpenClaw
openclaw skills install tiktok-motivation-video

简介

利用真实视频片段制作励志类短视频内容。tiktok-motivation-video 属于研究检索类 Skill,可作为该场景下的辅助能力补充。

  • 集成脚本生成、配音合成与素材搜索全流程。
  • 自动匹配背景音乐与视觉节奏增强感染力。
  • 依赖ElevenLabs等第三方语音服务接口。
  • 商用前须确认所有素材版权归属清晰合法。

SKILL.md

name
tiktok-motivation-video
description
>
compatibility
required_apis
python_packages
requests, Pillow, moviepy, pydub, numpy

TikTok Dark-Motivation Video Skill

30-90 second vertical (9:16) dark motivational video — @vuongmilano style.

Pipeline: Script (Claude) + Voice (ElevenLabs) + Real Video (Pexels API) + Text (MoviePy) + Grade (FFmpeg)

IMPORTANT: All visuals come from Pexels API (real filmed stock footage). Do NOT use FAL.ai, Replicate, or any AI image generator. Pexels only.


Step 0 - Gather Inputs

  • TOPIC: e.g. "discipline", "loneliness", "becoming your best self"
  • TONE: dark & stoic | dark & aggressive | dark & poetic (default: dark & stoic)
  • DURATION: 30 | 60 | 90 seconds (default: 60)
  • VISUAL_THEME: dark city rain | lone warrior | dark nature | minimal shadow (default: dark city rain)
  • VOICE_ID: ElevenLabs voice (default: Adam = pNInz6obpgDQGcFmaJgB)
  • LANGUAGE: English | Vietnamese | bilingual

Step 1 - Generate Script (Claude API)

System prompt produces JSON with lines, timings, AND Pexels search queries.

SYSTEM PROMPT: You are a master motivational content writer for dark aesthetic TikTok videos. Style like @vuongmilano: short, punchy, deep philosophical lines. Dark, cinematic, poetic. Speaks to the isolated, driven person who wants to level up. Rules: 8-15 lines max. Each line max 8 words. No filler. Every word hits hard. Build tension then release with power. End with one unforgettable closer. Add [PAUSE] markers for dramatic silence. Return ONLY valid JSON (no markdown fences): { "title": "...", "lines": [ {"id": 1, "text": "...", "duration_ms": 3000, "pause_after_ms": 500}, {"id": 2, "text": "[PAUSE]", "duration_ms": 1200, "pause_after_ms": 0} ], "total_duration_ms": 60000, "hashtags": ["#darkmotivation", "#discipline", "#fyp"], "pexels_search_queries": ["dark city rain night", "lone person walking", "shadow dramatic"] }

import json, requests

def generate_script(topic, tone, duration, api_key):
    r = requests.post(
        "https://api.anthropic.com/v1/messages",
        headers={"x-api-key": api_key, "anthropic-version": "2023-06-01", "content-type": "application/json"},
        json={
            "model": "claude-sonnet-4-20250514",
            "max_tokens": 1000,
            "system": SCRIPT_SYSTEM,
            "messages": [{"role": "user", "content": f"Topic: {topic}\
Tone: {tone}\
Duration: {duration}s"}]
        }
    )
    raw = r.json()["content"][0]["text"]
    return json.loads(raw.replace("```json","").replace("```","").strip())

Step 2 - Generate Voiceover (ElevenLabs)

Voice settings for dark motivation style: stability: 0.75, similarity_boost: 0.85, style: 0.30, use_speaker_boost: True model_id: eleven_multilingual_v2

Top voices: Adam pNInz6obpgDQGcFmaJgB deep, authoritative Antoni ErXwobaYiN019PkySvjV warm, intense Josh TxGEqnHWrfWFTfGW9XjX cinematic, dramatic

from pydub import AudioSegment
import io

def generate_voiceover(script, voice_id, api_key, out="voice.mp3"):
    segs = []
    for line in script["lines"]:
        if line["text"] == "[PAUSE]":
            segs.append(AudioSegment.silent(duration=line["duration_ms"]))
            continue
        r = requests.post(
            f"https://api.elevenlabs.io/v1/text-to-speech/{voice_id}",
            headers={"xi-api-key": api_key, "Content-Type": "application/json"},
            json={"text": line["text"], "model_id": "eleven_multilingual_v2",
                  "voice_settings": {"stability":0.75,"similarity_boost":0.85,"style":0.30,"use_speaker_boost":True}}
        )
        segs.append(AudioSegment.from_mp3(io.BytesIO(r.content)))
        if line.get("pause_after_ms", 0) > 0:
            segs.append(AudioSegment.silent(duration=line["pause_after_ms"]))
    final = sum(segs)
    final.export(out, format="mp3")
    return out, len(final)

Step 3 - Fetch Real Video Clips (Pexels API)

Free API key at: https://www.pexels.com/api/

Default queries by theme:

THEME_QUERIES = {
    "dark city rain":  ["dark city rain night", "rain street cinematic", "dark alley bokeh", "night city slow motion"],
    "lone warrior":    ["lone person silhouette night", "person walking alone dark", "shadow warrior", "lone figure darkness"],
    "dark nature":     ["dark forest fog cinematic", "storm clouds dramatic", "night mountain silhouette", "dark ocean storm"],
    "minimal shadow":  ["shadow dark minimal", "dark room single light", "dramatic low key lighting", "black shadow person"],
}
import os

def fetch_video_clips(theme, duration, pexels_key, output_dir="clips", script=None):
    os.makedirs(output_dir, exist_ok=True)

    # Use Claude-generated queries if available, else use theme defaults
    queries = (script or {}).get("pexels_search_queries") or THEME_QUERIES.get(theme, THEME_QUERIES["dark city rain"])
    needed = max(3, duration // 15)
    collected = []

    for query in queries:
        if len(collected) >= needed:
            break
        print(f"  Pexels: searching '{query}'")
        r = requests.get(
            "https://api.pexels.com/videos/search",
            headers={"Authorization": pexels_key},
            params={"query": query, "per_page": 5, "orientation": "portrait", "size": "medium"}
        )
        for video in r.json().get("videos", []):
            if len(collected) >= needed:
                break
            # Pick best MP4 file >= 720px wide
            files = sorted(video.get("video_files", []), key=lambda f: f.get("width", 0), reverse=True)
            url = next((f["link"] for f in files if f.get("width",0)>=720 and "mp4" in f.get("file_type","")), None)
            if not url:
                continue
            path = os.path.join(output_dir, f"clip_{len(collected):02d}.mp4")
            with open(path, "wb") as f:
                for chunk in requests.get(url, stream=True, timeout=60).iter_content(8192):
                    f.write(chunk)
            collected.append({
                "path": path,
                "duration": video.get("duration", 10),
                "photographer": video.get("user", {}).get("name", "Pexels")
            })
            print(f"  Downloaded clip {len(collected)}/{needed}")

    if not collected:
        raise RuntimeError("No clips fetched. Check PEXELS_API_KEY.")
    return collected

Pexels notes:

  • Free: 200 req/hour, 20,000/month
  • orientation=portrait returns vertical-friendly clips
  • Attribution required in TikTok caption: "Video footage via Pexels"
  • Best keywords: dark, night, shadow, rain, fog, cinematic, dramatic, silhouette, alone

Step 4 - Compose Video (MoviePy)

Crop all clips to 1080x1920 vertical. Layer dark overlay. Sync text to voice timing.

Font: Download Bebas Neue from fonts.google.com -> save as fonts/BebasNeue-Regular.ttf

from moviepy.editor import (
    VideoFileClip, AudioFileClip, ColorClip, TextClip,
    concatenate_videoclips, CompositeVideoClip, CompositeAudioClip
)

def crop_to_vertical(clip, w=1080, h=1920):
    clip = clip.resize(height=h)
    if clip.w < w:
        clip = clip.resize(width=w)
    return clip.crop(x_center=clip.w/2, width=w).resize((w, h))

def compose_video(clips_info, audio_path, script, out="output.mp4", bg_music_path=None):
    audio = AudioFileClip(audio_path)
    total_dur = audio.duration

    # Assemble background from Pexels clips
    pool = clips_info * 4
    parts, remaining = [], total_dur
    for info in pool:
        if remaining <= 0: break
        try:
            c = crop_to_vertical(VideoFileClip(info["path"], audio=False))
            dur = min(c.duration - 0.3, remaining)
            if dur <= 0: continue
            parts.append(c.subclip(0, dur))
            remaining -= dur
        except: continue
    if not parts:
        raise RuntimeError("No clips could be loaded")
    bg = concatenate_videoclips(parts, method="compose").set_duration(total_dur)

    # Dark overlay - essential for mood
    dark = ColorClip((1080,1920), color=(0,0,0)).set_opacity(0.55).set_duration(total_dur)

    # Text synced to script timing
    texts = []
    t = 0.0
    for line in script["lines"]:
        if line["text"] == "[PAUSE]":
            t += line["duration_ms"] / 1000
            continue
        dur = line["duration_ms"] / 1000
        try:
            clip = TextClip(line["text"], fontsize=78, font="fonts/BebasNeue-Regular.ttf",
                            color="white", stroke_color="black", stroke_width=3,
                            size=(900, None), method="caption")
        except:
            clip = TextClip(line["text"], fontsize=78, color="white",
                            stroke_color="black", stroke_width=3, size=(900,None), method="caption")
        texts.append(clip.set_duration(dur).crossfadein(0.25).crossfadeout(0.25).set_start(t).set_position("center"))
        t += dur + line.get("pause_after_ms", 0) / 1000

    if bg_music_path and os.path.exists(bg_music_path):
        mus = AudioFileClip(bg_music_path).volumex(0.08).set_duration(total_dur)
        final_audio = CompositeAudioClip([audio, mus])
    else:
        final_audio = audio

    CompositeVideoClip([bg, dark] + texts).set_audio(final_audio).write_videofile(
        out, fps=30, codec="libx264", audio_codec="aac", bitrate="8000k", threads=4, preset="fast"
    )
    return out

Step 5 - Color Grade (FFmpeg)

ffmpeg -y -i output.mp4 \
  -vf "curves=blue='0/0.05 1/1.1',eq=contrast=1.15:brightness=-0.04:saturation=0.60,vignette=PI/4,noise=alls=6:allf=t+u" \
  -c:v libx264 -crf 17 -c:a copy final_video.mp4

Filters: blue tint shadow + darker contrast + vignette edges + film grain


Master Pipeline

import os, subprocess

def create_motivation_video(
    topic, tone="dark & stoic", duration=60,
    visual_theme="dark city rain", voice_id="pNInz6obpgDQGcFmaJgB",
    output="motivation_video.mp4", bg_music_path=None
):
    ak = os.getenv("ANTHROPIC_API_KEY")
    ek = os.getenv("ELEVENLABS_API_KEY")
    pk = os.getenv("PEXELS_API_KEY")

    print("[1/5] Script..."); script = generate_script(topic, tone, duration, ak)
    print("[2/5] Voice...");  audio, _ = generate_voiceover(script, voice_id, ek)
    print("[3/5] Pexels..."); clips = fetch_video_clips(visual_theme, duration, pk, script=script)
    print("[4/5] Compose..."); raw = compose_video(clips, audio, script, "raw.mp4", bg_music_path)
    print("[5/5] Grade...")
    subprocess.run([
        "ffmpeg","-y","-i",raw,"-vf",
        "curves=blue='0/0.05 1/1.1',eq=contrast=1.15:brightness=-0.04:saturation=0.60,vignette=PI/4",
        "-c:v","libx264","-crf","17","-c:a","copy", output
    ], check=True)
    print(f"\
Done: {output}")
    print(f"Tags: {' '.join(script['hashtags'])}")
    print("Caption: Video footage via Pexels")
    return output, script

Setup

pip install requests Pillow moviepy pydub numpy
# macOS: brew install ffmpeg
# Ubuntu: apt install ffmpeg -y
# Font: fonts.google.com/specimen/Bebas+Neue -> fonts/BebasNeue-Regular.ttf

# .env
ANTHROPIC_API_KEY=sk-ant-...
ELEVENLABS_API_KEY=...
PEXELS_API_KEY=...       # free at pexels.com/api

CLI

python scripts/pipeline_full.py --topic "discipline" --duration 60 --theme "dark city rain"

Troubleshooting

No Pexels results -> Broaden queries; verify API key Landscape clips -> crop_to_vertical() handles automatically Text desynced -> Check timing uses /1000 (ms to seconds) Voice monotone -> Lower stability 0.5, raise style 0.5 Font error -> Use full absolute path to .ttf file FFmpeg missing -> brew install ffmpeg or apt install ffmpeg

Best Pexels Keywords for Dark Motivation

Discipline: dark city rain, shadow silhouette night, person walking alone Loneliness: lone figure fog, empty dark room, solitude night Rising up: mountain storm clearing, dark dawn sky, fog path Villain arc: dramatic low key shadow, dark smoke motion, moody portrait Hustle: night city timelapse, urban rain bokeh, dark street light

References

references/pexels_search_guide.md - Full query list by mood references/elevenlabs_voices.md - Voice catalog scripts/pipeline_full.py - Complete runnable script

适合场景

01

OpenClaw 用户查找和安装 Skill 时

02

用户想查找某类 Agent Skill 时

03

需要根据任务场景推荐可安装能力包时

04

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

OpenClaw

91.15%
按下载量换算6,858

安全审计

VirusTotal

可疑

ClawScan

可疑

Static analysis

未展示

权限和风险

敏感数据

该 Skill 可能接触密钥、Token、环境变量或敏感配置,应进入高风险复核队列,默认不自动发布。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。来源安全扫描存在 warning/failed 结果,不能写成本站确认安全。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills