在 AIGC 技术全面落地的当下,「文字生成内容」早已从图片延伸到视频领域,只需简单的自然语言描述,就能快速生成专属的视觉影像。本文将以AI 动物视频生成器为例,从需求拆解、技术选型、核心开发到交互设计,完整拆解如何基于 Coze(扣子)工作流 + Flask 框架,快速搭建一款「输入动物描述,一键生成专属视频」的轻量化 Web 应用,实现从文字到视频的无缝转化,让自然语言创作视觉内容变得触手可及。
一、项目背景与核心需求
动物主题的视觉内容在科普、教育、自媒体创作等场景中需求极高,但传统的视频制作需要专业的拍摄、剪辑能力,门槛高、耗时久。我们希望打造一款轻量化的 AI 视频生成工具,让普通用户无需任何专业技能,只需通过自然语言描述想要看到的动物场景(如 "大熊猫在竹林吃竹子""雄鹰在雪山翱翔"),就能快速生成对应的高清视频,同时兼顾操作简洁性 、体验流畅性 与功能实用性。
基于实际使用场景,我们确定了核心技术与产品目标:
- 后端实现与 Coze 工作流的高效对接,封装视频生成 API,做好异常处理与跨域支持;
- 前端打造沉浸式的交互界面,实现「输入 - 生成 - 预览」的全流程可视化,适配电脑、手机等多设备;
- 提供示例描述快速复用功能,降低用户输入门槛,提升操作效率;
- 实现全流程状态管理,包含加载、成功、错误、空状态等,让用户清晰感知操作进度;
- 采用「配置与代码解耦」的设计,保证应用的可移植性与安全性,便于后续部署与扩展。
二、技术栈选型:轻量组合,高效落地
本项目采用前后端一体化 开发模式,无需复杂的分布式架构,核心技术栈围绕「低门槛、高效率、易部署」原则选型,单人即可完成从开发到上线的全流程,是 AIGC 轻量应用落地的典型技术组合:
后端技术栈
- Flask:轻量级 Python Web 框架,核心代码简洁、扩展灵活,既能快速封装 RESTful API,又能直接托管静态 HTML 页面,实现前后端一体化部署,无需单独配置静态资源服务器;
- Coze Python SDK:Coze 官方提供的开发工具包,封装了与工作流交互的所有细节,无需手动构造 HTTP 请求、处理接口认证,大幅简化 AIGC 能力的调用流程;
- python-dotenv:环境变量管理工具,将 API 令牌、工作流 ID 等敏感配置从代码中解耦,避免硬编码导致的信息泄露,同时便于开发 / 线上环境的配置切换;
- flask-cors:解决前端跨域请求问题,适配本地开发与线上部署的跨域场景,无需复杂的 Nginx 配置;
- json/os:Python 内置模块,实现数据解析与系统环境变量读取,无额外依赖,简化项目结构。
前端技术栈
- 原生 HTML/CSS/JavaScript:无任何前端框架依赖,降低开发与部署成本,适合轻量应用的快速迭代,同时保证页面的轻量性与加载速度;
- CSS3:实现渐变背景、卡片阴影、圆角、响应式布局、加载动画等视觉效果,打造现代、沉浸式的界面风格,提升用户体验;
- 原生 DOM 操作:实现输入、提交、视频预览、状态切换等核心交互,无需引入额外的前端库,代码更简洁、易维护;
- HTML5 Video:原生视频播放组件,支持视频的在线预览、播放控制,适配主流浏览器,兼容性强。
运行与依赖环境
- 开发语言:Python 3.8+
- 运行环境:主流浏览器(Chrome/Firefox/Edge/Safari)、任意支持 Python 的服务器(本地 / 云服务器)
- 第三方依赖:Coze 平台账号(获取 API 令牌与工作流 ID)、Python 第三方包(flask/cozepy 等)
三、核心架构设计:极简前后端协同逻辑
本项目采用无数据库、无中间件的极简架构,核心分为「后端服务层」与「前端交互层」,两层通过 HTTP POST 接口实现数据交互,整体流程清晰、耦合度低,既便于开发调试,又能快速部署上线。
整体架构分层
AI动物视频生成器
├─ 后端服务层(Flask):API封装 + Coze对接 + 前端页面托管
│ ├─ 静态资源托管:通过send_file返回index.html前端页面,实现前后端一体化
│ ├─ 核心API:/generate-video(POST),接收前端描述,返回视频URL
│ ├─ Coze工作流调用:封装create_video函数,实现视频生成的核心逻辑
│ ├─ 配置管理:通过dotenv从.env文件读取敏感配置,代码与配置解耦
│ └─ 异常处理:捕获接口调用、数据解析中的异常,返回友好的处理结果
└─ 前端交互层(原生HTML/CSS/JS):用户交互 + 状态展示 + 视频预览
├─ 输入层:文本域输入 + 示例描述快速填充,降低用户输入门槛
├─ 状态层:加载中、生成成功、生成失败、空状态等全流程可视化
├─ 预览层:HTML5 Video原生组件,实现视频的在线播放与控制
├─ 交互层:按钮状态管理、回车提交(可扩展)、结果信息展示
└─ 布局层:响应式flex布局,适配电脑、平板、手机等多设备
核心执行流程
- 用户在前端文本域输入动物场景描述,或点击示例快速填充,点击「生成动物视频」按钮;
- 前端做非空校验,禁用提交按钮并显示加载状态,通过 fetch 发送 POST 请求到后端
/generate-video接口,携带用户输入的描述参数; - 后端接口接收请求,提取并校验参数,调用封装的
create_video函数初始化 Coze 客户端; - 后端通过 Coze SDK 调用视频生成工作流,传入用户描述参数,执行视频生成逻辑;
- 后端解析 Coze 工作流返回结果,提取视频 URL,以 JSON 格式返回给前端;若过程中出现异常,返回空的视频 URL;
- 前端接收后端响应,关闭加载状态并恢复按钮功能:
- 若生成成功:隐藏占位符,显示视频播放组件并加载视频,同时展示成功提示与描述信息;
- 若生成失败:显示错误提示,告知用户具体问题;
- 用户可通过 HTML5 Video 组件的原生控制栏,对生成的视频进行播放、暂停、全屏等操作。
四、核心功能开发:关键代码解析与设计思路
接下来我们从后端核心逻辑 、前端交互设计 、关键细节优化三个维度,拆解项目的核心开发环节,解读代码的设计思路与技术要点,让你不仅能复用代码,更能理解背后的设计逻辑。
4.1 后端开发:简洁可靠的 API 封装与 Coze 对接
后端核心代码仅百行左右,却实现了配置管理、跨域支持、API 封装、AIGC 对接、异常处理全功能,遵循「极简设计」与「健壮性」兼顾的原则,让核心逻辑清晰易懂。
4.1.1 环境初始化与配置加载
python
import os
import json
from dotenv import load_dotenv
from cozepy import Coze, TokenAuth, COZE_CN_BASE_URL
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
# 加载.env文件中的环境变量,实现配置与代码解耦
load_dotenv()
# 初始化Flask应用
app = Flask(__name__)
# 开启全局跨域支持,简化开发,适配前端本地请求
CORS(app)
设计思路:
- 优先加载环境变量:通过
load_dotenv()读取项目根目录.env文件中的配置,将COZE_API_TOKEN 、WORKFLOW_ID等敏感信息与代码分离,既避免硬编码泄露,又便于不同环境的配置切换; - 全局跨域配置:直接调用
CORS(app)开启所有接口的跨域支持,无需为单个接口单独配置,适合轻量应用的快速开发,若线上部署需精细化配置,可指定允许的域名。
4.1.2 核心工具函数:create_video
封装独立的视频生成函数,将 Coze 工作流调用的逻辑解耦,让代码更模块化、易维护,便于后续单独调用或扩展:
python
# 调用工作流生成视频,独立函数解耦核心逻辑
def create_video(animal_description):
try:
# 从环境变量获取配置,避免硬编码
api_token = os.getenv('COZE_API_TOKEN')
workflow_id = os.getenv('WORKFLOW_ID')
# 初始化Coze客户端,指定国内节点保证访问稳定性
coze = Coze(
auth=TokenAuth(token=api_token), # 令牌认证,符合Coze安全规范
base_url=COZE_CN_BASE_URL
)
# 执行Coze视频生成工作流,传入用户描述参数
workflow = coze.workflows.runs.create(
workflow_id=workflow_id,
parameters={"input": animal_description}
)
# 解析返回结果,提取视频URL
video_url = json.loads(workflow.data)['output']
return video_url
# 全局异常捕获,避免单个请求导致服务崩溃
except Exception as e:
return None
关键设计要点:
- 模块化解耦:将视频生成的核心逻辑封装为独立函数,后续若需在其他接口调用视频生成功能,可直接复用,无需重复代码;
- Coze 客户端优化 :指定
COZE_CN_BASE_URL国内节点,避免跨境访问的网络延迟与不稳定问题,提升接口调用成功率; - 安全认证 :使用
TokenAuth进行令牌认证,符合 Coze 平台的安全规范,避免 API 令牌被盗用; - 结果解析 :针对 Coze 工作流的返回结构,解析
workflow.data获取视频 URL,直接返回给调用方,简化后续接口的逻辑; - 异常兜底 :使用
try-except捕获所有可能的异常(网络错误、Coze 接口报错、数据解析错误、配置缺失等),异常时返回None,让接口层统一处理失败逻辑,保证服务的健壮性。
4.1.3 核心 API 接口:/generate-video
后端的核心接口,实现请求接收、参数校验、逻辑调用、结果返回的完整流程,是前后端交互的核心桥梁:
python
# 视频生成API接口,仅支持POST请求(符合RESTful规范)
@app.route("/generate-video", methods=['POST'])
def generate_video():
# 获取前端JSON格式请求参数
data = request.get_json()
# 提取并清洗用户输入(去除首尾空格,避免无效输入)
animal_description = data.get('input', '').strip()
# 调用视频生成函数,获取视频URL
video_url = create_video(animal_description)
# 统一返回JSON格式结果,让前端处理逻辑更统一
return jsonify({
'success': True,
'video_url': video_url,
'description': animal_description
})
设计思路:
- 请求规范:仅支持 POST 请求,符合 RESTful API 设计规范(POST 用于创建资源,此处为 "创建视频资源");
- 参数清洗 :对用户输入执行
strip()操作,去除首尾空格,避免用户输入空字符、全空格等无效内容; - 统一返回格式 :无论视频生成成功或失败,都返回固定的 JSON 格式,包含
success、video_url、description三个字段,让前端无需处理多种返回格式,降低前端开发复杂度; - 无额外校验:将复杂的异常处理交给底层工具函数,接口层仅做简单的参数提取与调用,保持代码简洁。
4.1.4 前端页面托管与服务启动
python
# 首页路由,托管前端静态页面,实现前后端一体化
@app.route('/')
def index():
return send_file('index.html')
# 服务启动入口
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
设计亮点:
- 前后端一体化 :通过
send_file('index.html')将前端页面与后端代码放在同一目录,启动 Flask 服务即可同时访问前端页面与后端 API,无需单独启动前端服务或配置 Nginx,部署时只需启动一个服务,大幅简化部署流程; - 服务可访问性 :指定
host='0.0.0.0',让服务可以被同一局域网内的其他设备访问(如手机、平板),便于多设备测试; - 调试模式 :开启
debug=True,开发阶段代码修改后自动重启服务,提升开发效率(线上部署时必须改为 False,避免调试信息泄露与安全风险)。
4.2 前端开发:沉浸式交互与全流程状态管理
前端采用原生技术开发,核心围绕「用户体验 」与「操作简洁性」展开,打造了沉浸式的视觉界面与流畅的交互流程,同时实现了全流程的状态管理,让用户的每一步操作都有清晰的视觉反馈。
4.2.1 界面设计:视觉与实用的双重兼顾
前端界面采用左右分栏的沉浸式布局,左侧为输入区,右侧为视频预览区,结构清晰,符合用户「输入 - 预览」的操作习惯,同时在视觉与布局上做了多重优化:
- 视觉风格:使用红橙蓝渐变的背景色,搭配动物主题的元素,贴合「动物世界」的产品定位;卡片式设计结合轻微阴影,打造层次感,避免界面单调;
- 响应式布局 :通过
flex布局 + 媒体查询,在电脑端为左右分栏,在平板 / 手机端自动转为上下布局,保证所有设备的操作体验一致,无布局错乱; - 分区明确:输入区与预览区严格分离,每个区域都有专属的标题与功能,用户可快速定位核心操作区域,降低学习成本;
- 细节美化:按钮采用渐变背景 + hover 上浮效果,输入框添加焦点样式,视频容器为黑色背景,贴合视频播放的视觉习惯,提升整体质感。
4.2.2 核心交互功能:从输入到预览的流畅体验
前端的核心 JavaScript 代码实现了示例填充、视频生成、状态切换、视频预览四大核心功能,同时做了完善的交互优化,让用户操作流畅、无卡顿:
- 示例描述快速填充:为新手用户提供 3 个典型的动物场景示例,点击即可快速填充到输入框,降低输入门槛,解决用户 "不知道怎么描述" 的问题;
- 视频生成核心逻辑:做输入非空校验→禁用按钮并修改文字→切换为加载状态→发送 fetch 请求→处理后端响应→根据结果切换状态(成功 / 失败)→恢复按钮状态,形成完整的操作闭环;
- 原生视频预览:使用 HTML5 Video 组件实现视频的在线播放,支持原生的播放、暂停、进度条、全屏等控制功能,无需引入第三方视频播放器,兼容性强、加载速度快;
- 结果信息展示:视频生成成功后,展示用户的原始描述,让用户清晰知道当前视频对应的描述内容,便于核对。
4.2.3 全流程状态管理:让用户感知每一步操作
优秀的前端交互,核心是让用户的每一步操作都有反馈 。本项目实现了空状态、加载中、生成成功、生成失败四种核心状态的可视化管理,覆盖用户操作的全流程:
- 空状态:页面加载完成后,视频区域显示动物脚印图标 + 提示文字,告知用户 "视频将在这里显示,请输入描述并生成",避免界面空白导致的用户困惑;
- 加载中:点击生成后,显示旋转的加载动画 +"AI 正在努力生成视频" 的文字,禁用提交按钮,避免用户重复点击导致多次请求;
- 生成成功:隐藏加载状态与空状态,显示视频播放组件,同时展示绿色的成功提示与结果信息,让用户明确知道操作成功;
- 生成失败:隐藏加载状态,显示红色的错误提示,告知用户 "生成失败,请稍后重试",同时在控制台打印详细错误信息,便于开发调试。
4.2.4 关键交互优化:细节提升用户体验
前端在核心功能之外,加入了多个细节优化点,让轻量应用也有出色的交互体验,兼顾实用性 与流畅性:
- 按钮状态管理:生成过程中禁用按钮并修改文字为 "生成中...",避免用户重复提交,减少后端无效请求;生成完成后自动恢复按钮状态,无需用户刷新页面;
- 输入非空校验:点击生成时先做本地非空校验,若输入为空则直接弹出提示,无需发送后端请求,减少网络消耗;
- 错误提示个性化:区分「网络错误」与「视频生成错误」,为用户提供更具体的错误信息,便于问题排查;
- 资源懒加载:视频组件默认隐藏,只有生成成功后才加载视频资源,避免页面初始加载时的资源浪费;
- 无框架依赖:所有交互均通过原生 JavaScript 实现,页面加载速度快,无额外的框架体积开销,在低配设备上也能流畅运行。
4.3 项目配置与本地运行:三步快速启动
本项目的配置与运行流程极简,无需复杂的环境配置,只需三步即可完成本地启动,新手也能快速上手:
步骤 1:创建.env 配置文件,管理敏感信息
在项目根目录创建.env文件,添加以下内容,将<你的Coze API令牌>和<你的视频生成工作流ID>替换为自己的 Coze 平台信息:
# Coze平台配置
COZE_API_TOKEN=<你的Coze API令牌>
WORKFLOW_ID=<你的视频生成工作流ID>
重要注意 :.env文件包含敏感的 API 令牌,切勿提交到代码仓库(可添加到.gitignore 文件),避免信息泄露导致的财产损失。
步骤 2:安装 Python 第三方依赖
在项目根目录打开终端,执行以下命令,一键安装所有后端依赖:
bash
pip install flask flask-cors python-dotenv cozepy
所有依赖均为 Python 生态的主流包,下载速度快,无额外的编译依赖,可直接安装。
步骤 3:启动 Flask 服务,访问应用
直接运行后端 Python 代码(假设文件名为app.py),启动服务:
bash
python app.py
服务启动后,在浏览器访问http://127.0.0.1:5000(或同一局域网内的http://你的电脑IP:5000),即可进入 AI 动物视频生成器的主界面,开始使用。
五、线上部署建议:简单修改,快速上线
本项目的本地运行版本可直接用于开发与测试,若需部署到线上服务器,只需做3 处简单修改,即可保证服务的稳定性与安全性,适配生产环境:
-
关闭调试模式 :将
app.run(debug=True, host='0.0.0.0', port=5000)中的debug=True改为debug=False,避免调试信息泄露,同时防止恶意用户通过调试模式执行恶意代码; -
使用专业 WSGI 服务器 :替换 Flask 内置的开发服务器,使用 Gunicorn 作为 WSGI 服务器,提升服务的并发处理能力与稳定性:
bash# 安装Gunicorn pip install gunicorn # 启动服务(4个工作进程,绑定5000端口) gunicorn -w 4 -b 0.0.0.0:5000 app:app -
配置 Nginx 反向代理(可选):若需要域名访问、HTTPS 配置、静态资源缓存,可配置 Nginx 作为反向代理,将请求转发到 Gunicorn 服务,同时实现域名与 HTTPS 的绑定;
-
添加进程守护(可选) :使用
supervisor或systemd将服务注册为系统进程,避免服务器重启后服务中断,保证 7*24 小时运行。
六、项目扩展方向:基于基础版本的功能升级
本项目实现了「文字生成动物视频」的核心功能,基于现有代码架构,可轻松进行功能扩展,适配更多的使用场景,以下是 6 个推荐的扩展方向,供大家参考:
- 视频质量可配置:前端添加视频质量选择框(标清 / 高清 / 4K),后端接收质量参数并传入 Coze 工作流,实现不同质量的视频生成,满足不同场景的需求;
- 视频下载功能:为生成的视频添加下载按钮,通过 JavaScript 实现视频的本地下载,支持用户将视频保存到本地使用;
- 历史记录功能 :通过
localStorage或引入轻量数据库(SQLite),记录用户的生成历史,支持历史记录的查询、复用与删除,提升用户体验; - 描述优化建议:对接大模型接口,为用户的输入描述提供优化建议,让描述更精准,生成的视频效果更好;
- 多主题支持:从「动物世界」扩展到风景、人物、动漫等多个主题,只需切换 Coze 工作流 ID,即可实现多主题的视频生成;
- 批量生成与导出:支持用户输入多个描述,批量生成视频,并提供批量导出功能,适配自媒体创作等批量生产场景;
- 深色模式:添加浅色 / 深色模式切换功能,适配夜间使用场景,保护用户视力;
- 接口限流:添加接口限流功能(如基于 IP 的限流),避免恶意请求导致的服务压力与 Coze API 消耗。
七、项目总结与技术思考
本次 AI 动物视频生成器的开发,是AIGC 轻量应用落地的典型实践,通过 Flask+Coze 工作流的组合,仅用数百行代码就实现了从文字到视频的完整转化,核心收获与技术思考如下:
1. 轻量化技术栈是 AIGC 小应用的最优解
在 AIGC 轻量应用、原型验证、个人项目的开发中,无需追求复杂的技术架构(如微服务、分布式数据库),轻量化的技术栈组合(Flask + 原生前端)能大幅提升开发效率,降低部署与维护成本,同时完全满足核心的功能与体验需求。Coze 平台的工作流则进一步简化了 AIGC 能力的调用,让开发者无需关注视频生成模型的训练、部署与优化,只需专注于业务逻辑与用户体验,真正实现「开箱即用」。
2. 模块化解耦让代码更易维护与扩展
项目中将视频生成的核心逻辑封装为独立的create_video函数,将接口层与业务逻辑层解耦,让代码结构更清晰,后续的功能扩展也变得异常简单。这种「模块化解耦」的设计思想,不仅适用于轻量应用,也是大型项目开发的核心原则 ------好的代码,一定是易于修改的代码。
3. 全流程状态管理是前端体验的核心
对于 AIGC 应用而言,生成内容的过程往往需要一定的时间,用户的耐心有限。此时,全流程的状态管理就显得尤为重要:空状态的提示、加载中的反馈、成功 / 失败的视觉提醒,能让用户的每一步操作都有清晰的反馈,大幅降低用户的焦虑感,提升产品的使用体验。细节,决定了产品的质感。
4. 配置与代码解耦是开发的最佳实践
将敏感配置(API 令牌、工作流 ID)从代码中解耦,通过环境变量管理,不仅能避免敏感信息的泄露,还能让应用在不同环境(开发 / 测试 / 线上)中快速切换配置,无需修改代码。这一最佳实践应贯穿于所有项目的开发中,是保证代码可移植性与安全性的基础。
5. AIGC 应用的核心是「场景化落地」
AIGC 技术的价值,不在于单纯的 "炫技",而在于与具体场景的结合。本次项目将视频生成能力与「动物世界」的场景结合,解决了科普、教育、自媒体创作等场景中视频制作门槛高的问题,让 AI 技术真正服务于实际需求。未来,更多优秀的 AIGC 应用,都会围绕具体的场景需求展开,让技术变得更实用、更贴近用户。
八、写在最后
从几行文字到一段生动的视频,AI 正在不断降低内容创作的门槛,让普通人也能成为视觉内容的创作者。本次 AI 动物视频生成器的开发,不仅是一次技术实践,更是对 AIGC 轻量化落地的一次探索 ------ 借助成熟的低代码平台与轻量的开发框架,我们能快速将自己的想法转化为可直接使用的产品,无需复杂的技术储备。
完整代码
后端:
python
import os
import json
from dotenv import load_dotenv
from cozepy import Coze, TokenAuth, COZE_CN_BASE_URL
from flask import Flask, request, jsonify, send_file
from flask_cors import CORS
# 加载环境变量
load_dotenv()
app = Flask(__name__)
CORS(app) # 允许跨域请求
# 调用工作流生成视频
def create_video(animal_description):
try:
api_token = os.getenv('COZE_API_TOKEN')
workflow_id = os.getenv('WORKFLOW_ID')
# 初始化coze客户端
coze = Coze(
auth=TokenAuth(token=api_token),
base_url=COZE_CN_BASE_URL
)
# 执行工作流
workflow = coze.workflows.runs.create(
workflow_id=workflow_id,
parameters={
"input": animal_description
}
)
# 接收返回的内容
video_url = json.loads(workflow.data)['output']
return video_url
except Exception as e:
return None
# 声明接口路由
@app.route("/generate-video", methods=['POST'])
def generate_video():
# 获取请求参数
data = request.get_json()
animal_description = data.get('input', '').strip()
video_url = create_video(animal_description)
return jsonify({
'success': True,
'video_url': video_url,
'description': animal_description
})
# 访问首页
@app.route('/')
def index():
return send_file('index.html')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
前端:
html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>动物世界 - AI视频生成器</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
body {
background: linear-gradient(135deg, #1a2a6c, #b21f1f, #fdbb2d);
color: #333;
min-height: 100vh;
padding: 20px;
}
.container {
max-width: 1200px;
margin: 0 auto;
}
header {
text-align: center;
padding: 30px 0;
color: white;
}
h1 {
font-size: 3rem;
margin-bottom: 10px;
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.subtitle {
font-size: 1.2rem;
opacity: 0.9;
}
.main-content {
display: flex;
flex-wrap: wrap;
gap: 30px;
margin-top: 20px;
}
.input-section {
flex: 1;
min-width: 300px;
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.output-section {
flex: 2;
min-width: 300px;
background: rgba(255, 255, 255, 0.9);
border-radius: 15px;
padding: 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
}
.section-title {
font-size: 1.5rem;
margin-bottom: 20px;
color: #1a2a6c;
border-bottom: 2px solid #fdbb2d;
padding-bottom: 10px;
}
.animal-input {
width: 100%;
min-height: 150px;
padding: 15px;
border: 2px solid #ddd;
border-radius: 10px;
font-size: 1rem;
resize: vertical;
margin-bottom: 20px;
transition: border-color 0.3s;
}
.animal-input:focus {
border-color: #1a2a6c;
outline: none;
}
.examples {
margin-top: 20px;
}
.example-title {
font-weight: bold;
margin-bottom: 10px;
color: #555;
}
.example-item {
background: #f0f5ff;
padding: 10px;
border-radius: 8px;
margin-bottom: 8px;
cursor: pointer;
transition: background 0.3s;
}
.example-item:hover {
background: #e0ebff;
}
.generate-btn {
background: linear-gradient(to right, #1a2a6c, #b21f1f);
color: white;
border: none;
padding: 15px 30px;
font-size: 1.1rem;
border-radius: 50px;
cursor: pointer;
width: 100%;
margin-top: 20px;
transition: transform 0.3s, box-shadow 0.3s;
font-weight: bold;
letter-spacing: 1px;
}
.generate-btn:hover {
transform: translateY(-3px);
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.3);
}
.generate-btn:disabled {
background: #cccccc;
cursor: not-allowed;
transform: none;
box-shadow: none;
}
.video-container {
width: 100%;
background: #000;
border-radius: 10px;
overflow: hidden;
margin-bottom: 20px;
min-height: 300px;
display: flex;
align-items: center;
justify-content: center;
color: white;
position: relative;
}
.video-placeholder {
text-align: center;
padding: 40px;
}
.video-placeholder i {
font-size: 4rem;
margin-bottom: 20px;
opacity: 0.7;
}
.generated-video {
width: 100%;
height: auto;
max-height: 500px;
border-radius: 10px;
}
.result-info {
background: #f9f9f9;
padding: 15px;
border-radius: 10px;
margin-top: 20px;
}
.loading {
display: none;
text-align: center;
padding: 20px;
}
.spinner {
border: 5px solid #f3f3f3;
border-top: 5px solid #1a2a6c;
border-radius: 50%;
width: 50px;
height: 50px;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.error-message {
background: #ffebee;
color: #c62828;
padding: 15px;
border-radius: 10px;
margin-top: 20px;
display: none;
}
.success-message {
background: #e8f5e9;
color: #2e7d32;
padding: 15px;
border-radius: 10px;
margin-top: 20px;
display: none;
}
footer {
text-align: center;
color: white;
margin-top: 40px;
padding: 20px;
opacity: 0.8;
}
@media (max-width: 768px) {
.main-content {
flex-direction: column;
}
h1 {
font-size: 2.2rem;
}
}
</style>
</head>
<body>
<div class="container">
<header>
<h1>动物世界 AI 视频生成器</h1>
<p class="subtitle">输入动物描述,AI为您生成专属动物视频</p>
</header>
<div class="main-content">
<div class="input-section">
<h2 class="section-title">描述您想看到的动物</h2>
<textarea class="animal-input" id="animalInput" placeholder="例如:一只在草原上奔跑的狮子,金色的毛发在阳光下闪闪发光..."></textarea>
<div class="examples">
<div class="example-title">示例描述:</div>
<div class="example-item" onclick="fillExample('一只憨态可掬的大熊猫在竹林中吃竹子,背景是青山绿水。')">
大熊猫在竹林中吃竹子
</div>
<div class="example-item" onclick="fillExample('一群斑马在非洲大草原上奔跑,尘土飞扬,夕阳西下。')">
斑马在草原上奔跑
</div>
<div class="example-item" onclick="fillExample('一只雄鹰在雪山之巅翱翔,展翅高飞,气势磅礴。')">
雄鹰在雪山之巅翱翔
</div>
</div>
<button class="generate-btn" id="generateBtn" onclick="generateVideo()">生成动物视频</button>
</div>
<div class="output-section">
<h2 class="section-title">生成的视频</h2>
<div class="video-container">
<div class="video-placeholder" id="videoPlaceholder">
<i>🐾</i>
<p>视频将在这里显示</p>
<p>请输入动物描述并点击生成按钮</p>
</div>
<video class="generated-video" id="generatedVideo" controls style="display: none;"></video>
</div>
<div class="loading" id="loading">
<div class="spinner"></div>
<p>AI正在努力生成视频,请稍候...</p>
</div>
<div class="error-message" id="errorMessage">
生成视频时出现错误,请稍后重试。
</div>
<div class="success-message" id="successMessage">
视频生成成功!
</div>
<div class="result-info" id="resultInfo" style="display: none;">
<h3>视频信息</h3>
<p><strong>描述:</strong> <span id="videoDescription"></span></p>
</div>
</div>
</div>
<footer>
<p>动物世界 AI 视频生成器 © | 使用AI技术生成逼真动物视频</p>
</footer>
</div>
<script>
// 填充示例文本
function fillExample(text) {
document.getElementById('animalInput').value = text;
}
// 生成视频函数
function generateVideo() {
const animalInput = document.getElementById('animalInput').value.trim();
const generateBtn = document.getElementById('generateBtn');
const videoPlaceholder = document.getElementById('videoPlaceholder');
const generatedVideo = document.getElementById('generatedVideo');
const loading = document.getElementById('loading');
const errorMessage = document.getElementById('errorMessage');
const successMessage = document.getElementById('successMessage');
const resultInfo = document.getElementById('resultInfo');
const videoDescription = document.getElementById('videoDescription');
// 验证输入
if (!animalInput) {
alert('请输入动物描述');
return;
}
// 禁用按钮并显示加载状态
generateBtn.disabled = true;
generateBtn.textContent = '生成中...';
videoPlaceholder.style.display = 'none';
generatedVideo.style.display = 'none';
errorMessage.style.display = 'none';
successMessage.style.display = 'none';
resultInfo.style.display = 'none';
loading.style.display = 'block';
// 调用后端API生成视频
fetch('/generate-video', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
input: animalInput
})
})
.then(response => {
if (!response.ok) {
throw new Error('网络响应不正常');
}
return response.json();
})
.then(data => {
if (data.success) {
// 显示视频
generatedVideo.src = data.video_url;
generatedVideo.style.display = 'block';
// 显示成功消息和结果信息
successMessage.style.display = 'block';
resultInfo.style.display = 'block';
videoDescription.textContent = animalInput;
} else {
// 显示错误消息
errorMessage.textContent = data.error || '生成视频时出现错误,请稍后重试。';
errorMessage.style.display = 'block';
}
})
.catch(error => {
console.error('Error:', error);
errorMessage.textContent = '网络错误,请检查连接或稍后重试。';
errorMessage.style.display = 'block';
})
.finally(() => {
// 恢复按钮状态
generateBtn.disabled = false;
generateBtn.textContent = '生成动物视频';
loading.style.display = 'none';
});
}
// 初始化页面
document.addEventListener('DOMContentLoaded', function() {
// 可以添加其他初始化代码
});
</script>
</body>
</html>
\ No newline at end of file
希望通过本文的拆解,能为各位开发者提供一些思路与参考,让你也能快速搭建属于自己的 AIGC 应用。在 AIGC 时代,技术的门槛正在降低,创意的价值正在提升,愿我们都能在轻量化开发中,享受技术带来的乐趣,让创意快速落地。