GPT Proto
Home/Skills/video-wrapper

video-wrapper

Add variety show effects (such as styled text, info cards, character lower-thirds, and chapter titles) to interview videos. It supports 4 visual themes, first analyzing the subtitles to generate suggestions for user approval, then rendering the video.

Download for Windows

quote-callout.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=1920, height=1080">
    <title>Quote Callout</title>
    <link rel="stylesheet" href="../static/css/effects.css">
    <link id="theme-css" rel="stylesheet" href="../static/css/theme-notion.css">
    <style>
        html, body {
            width: 1920px;
            height: 1080px;
            margin: 0;
            padding: 0;
            background: transparent;
            overflow: hidden;
        }
        .container {
            position: relative;
            width: 1920px;
            height: 1080px;
        }

        .quote-callout {
            position: absolute;
            max-width: 800px;
            padding: 32px 40px;
            opacity: 0;
        }

        .quote-callout .quote-mark {
            font-size: 72px;
            line-height: 1;
            opacity: 0.3;
            margin-bottom: -20px;
        }

        .quote-callout .quote-text {
            font-size: 32px;
            line-height: 1.5;
            font-weight: 500;
        }

        .quote-callout .quote-author {
            margin-top: 16px;
            font-size: 18px;
            opacity: 0.7;
        }

        /* Theme: Notion */
        .quote-callout.theme-notion {
            background: rgba(255, 253, 247, 0.95);
            border-left: 4px solid #E16259;
            border-radius: 0 8px 8px 0;
        }
        .quote-callout.theme-notion .quote-mark {
            color: #E16259;
            font-family: Georgia, serif;
        }
        .quote-callout.theme-notion .quote-text {
            color: #37352F;
            font-family: "Georgia", "Noto Serif SC", serif;
        }
        .quote-callout.theme-notion .quote-author {
            color: #787774;
            font-family: -apple-system, "PingFang SC", sans-serif;
        }

        /* Theme: Cyberpunk */
        .quote-callout.theme-cyberpunk {
            background: rgba(13, 13, 13, 0.95);
            border: 1px solid #00F5FF;
            border-left: 4px solid #FF00FF;
        }
        .quote-callout.theme-cyberpunk .quote-mark {
            color: #00F5FF;
            text-shadow: 0 0 20px #00F5FF;
        }
        .quote-callout.theme-cyberpunk .quote-text {
            color: #FFFFFF;
            font-family: -apple-system, sans-serif;
        }
        .quote-callout.theme-cyberpunk .quote-author {
            color: #FF00FF;
            font-family: "Courier New", monospace;
        }

        /* Theme: Apple */
        .quote-callout.theme-apple {
            background: rgba(255, 255, 255, 0.85);
            border-radius: 16px;
            backdrop-filter: blur(20px);
        }
        .quote-callout.theme-apple .quote-mark {
            color: #0071E3;
        }
        .quote-callout.theme-apple .quote-text {
            color: #1D1D1F;
            font-family: -apple-system, "SF Pro Display", "PingFang SC", sans-serif;
            font-weight: 400;
        }
        .quote-callout.theme-apple .quote-author {
            color: #86868B;
            font-family: -apple-system, "SF Pro Text", sans-serif;
        }

        /* Theme: Aurora */
        .quote-callout.theme-aurora {
            background: rgba(15, 15, 35, 0.9);
            border-radius: 16px;
            border: 1px solid rgba(102, 126, 234, 0.3);
        }
        .quote-callout.theme-aurora .quote-mark {
            background: linear-gradient(135deg, #667EEA, #F093FB);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
        }
        .quote-callout.theme-aurora .quote-text {
            color: #FFFFFF;
            font-family: "Avenir Next", "PingFang SC", sans-serif;
        }
        .quote-callout.theme-aurora .quote-author {
            color: #B8B8D0;
            font-family: -apple-system, sans-serif;
        }
    </style>
</head>
<body>
    <div class="container">
        <div id="quoteCallout" class="quote-callout theme-notion">
            <div class="quote-mark">"</div>
            <div class="quote-text" id="quoteText"></div>
            <div class="quote-author" id="quoteAuthor"></div>
        </div>
    </div>

    <script src="../static/js/anime.min.js"></script>
    <script>
        let config = {
            text: "AI 的发展是一个非常平滑的指数曲线",
            author: "— Dario Amodei",
            theme: "notion",
            position: { x: 960, y: 540 },
            durationMs: 5000
        };

        let animation = null;

        function initAnimation(cfg) {
            config = cfg || config;

            const container = document.getElementById('quoteCallout');
            const textEl = document.getElementById('quoteText');
            const authorEl = document.getElementById('quoteAuthor');

            textEl.textContent = config.text;
            authorEl.textContent = config.author || '';
            authorEl.style.display = config.author ? 'block' : 'none';

            container.className = `quote-callout theme-${config.theme || 'notion'}`;
            container.style.left = `${config.position.x - 400}px`;
            container.style.top = `${config.position.y - 100}px`;

            const totalDuration = config.durationMs;
            const exitStart = totalDuration - 500;

            animation = anime.timeline({
                autoplay: false,
                easing: 'linear'
            });

            // Container slides in
            animation.add({
                targets: container,
                opacity: [0, 1],
                translateX: [-30, 0],
                duration: 600,
                easing: 'spring(1, 180, 14, 0)'
            }, 0);

            // Text appears with typewriter-like effect (simplified)
            animation.add({
                targets: textEl,
                opacity: [0.5, 1],
                duration: 400,
                easing: 'easeOutQuad'
            }, 300);

            // Author fades in
            if (config.author) {
                animation.add({
                    targets: authorEl,
                    opacity: [0, 0.7],
                    translateY: [10, 0],
                    duration: 400,
                    easing: 'easeOutQuad'
                }, 600);
            }

            // Exit
            animation.add({
                targets: container,
                opacity: [1, 0],
                translateX: [0, 30],
                duration: 400,
                easing: 'easeInQuad'
            }, exitStart);

            return animation;
        }

        function seekTo(timeMs) {
            if (animation) animation.seek(timeMs);
        }

        function getDuration() {
            return animation ? animation.duration : config.durationMs;
        }

        document.addEventListener('DOMContentLoaded', () => initAnimation(config));
    </script>
</body>
</html>