我们构建一条纯本地(或低API依赖)的生产线,核心组件如下:
全部代码在单张RTX 3060(12GB)上可运行,总耗时约20分钟/分钟级成片。
首先,我们用LLM将用户故事大纲转化为带时间码和画面描述的脚本。这里采用结构化输出(JSON),便于后续程序逐条处理。
import requests
import json
def generate_script(story_idea: str) -> list:
prompt = f"""将以下故事转化为5个分镜,每个分镜包含:
- scene_description: 画面描述(包含角色、背景、动作)
- dialogue: 角色台词(若有)
- duration_sec: 预估时长(3-8秒)
输出JSON数组。
故事:{story_idea}"""
response = requests.post(
"https://api.deepseek.com/v1/chat/completions",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"model": "deepseek-chat",
"messages": [{"role": "user", "content": prompt}],
"response_format": {"type": "json_object"}
}
)
return json.loads(response.json()["choices"][0]["message"]["content"])["scenes"]
# 示例
scenes = generate_script("一个机器人男孩在废弃城市中寻找花朵,最终发现一朵发光的花")
print(json.dumps(scenes, indent=2, ensure_ascii=False))输出示例:
[
{"id":1,"desc":"机器人男孩站立在废墟中,背景是灰暗的天空,他低头看着地面","dialogue":"这里什么都没有...","duration":5},
{"id":2,"desc":"男孩抬头,远处有微光,他迈出一步","dialogue":"那是什么?","duration":4}
]保持同一角色在不同分镜中的外观是关键。我们采用 IP-Adapter 注入角色参考图(仅需提供一张角色正面照),无需训练LoRA。代码基于diffusers库实现:
from diffusers import StableDiffusionXLPipeline, IPAdapter
import torch
pipe = StableDiffusionXLPipeline.from_pretrained(
"stabilityai/stable-diffusion-xl-base-1.0",
torch_dtype=torch.float16
).to("cuda")
# 加载IP-Adapter(支持FaceID风格)
pipe.load_ip_adapter(
"h94/IP-Adapter",
subfolder="sdxl_models",
weight_name="ip-adapter-plus_sdxl_vit-h.safetensors"
)
pipe.set_ip_adapter_scale(0.8) # 控制参考强度
# 加载参考图(角色正面照)
from PIL import Image
ref_image = Image.open("character_front.png").resize((512, 512))
# 生成每个分镜图
def generate_scene_image(prompt: str, ref_img: Image) -> Image:
images = pipe(
prompt=prompt,
ip_adapter_image=ref_img,
negative_prompt="low quality, blurry, distorted",
num_inference_steps=30,
width=832, height=480
).images
return images[0]
# 批量生成
scene_images = []
for s in scenes:
img = generate_scene_image(s["desc"], ref_image)
scene_images.append(img)
img.save(f"scene_{s['id']}.png")IP-Adapter无需微调即可将参考图的身份特征迁移到任意场景,完美解决“换脸似换人”的痛点。
静态画面缺乏吸引力。我们为每个分镜生成一段3-5秒的短视频,使用 AnimateDiff(基于SD1.5的Motion Module)让角色衣物飘动、背景光晕闪烁。由于AnimateDiff专为512x512设计,我们将之前的图片作为ControlNet输入,保持构图不变,仅添加运动。
from diffusers import AnimateDiffPipeline, MotionAdapter
from diffusers.utils import export_to_video
adapter = MotionAdapter.from_pretrained("guoyww/animatediff-motion-adapter-v1-5-2")
pipe_anim = AnimateDiffPipeline.from_pretrained(
"SG161222/Realistic_Vision_V5.1_noVAE",
motion_adapter=adapter,
torch_dtype=torch.float16
).to("cuda")
# 启用FreeInit提升运动平滑度
pipe_anim.enable_free_init(num_steps=5)
def animate_scene(image: Image, prompt_plus: str, n_frames=24) -> List[Image]:
# 将静态图作为初始噪声或控制条件(此处简化:直接生成随机运动)
output = pipe_anim(
prompt=f"{prompt_plus}, slow motion, gentle breeze",
negative_prompt="static, no movement",
num_frames=n_frames,
guidance_scale=7.5,
num_inference_steps=25
).frames[0] # 返回列表[PIL]
return output
# 仅对第1个场景做动画测试(实际可循环)
anim_frames = animate_scene(scene_images[0], scenes[0]["desc"])
export_to_video(anim_frames, "scene_1_anim.mp4", fps=8)性能提示:AnimateDiff生成24帧需约30秒(GPU),若时间紧张,可改用图像增强运动插件如RIFE做帧插值,或仅对背景层进行仿射变换(平移/缩放)——这是漫剧常用的“伪动效”技巧。
使用微软Edge TTS(免费)生成台词音频,并精确对齐时间轴。
import edge_tts
import asyncio
import subprocess
async def text_to_speech(text: str, output_file: str):
communicate = edge_tts.Communicate(text, "zh-CN-XiaoyiNeural")
await communicate.save(output_file)
# 为每个分镜生成音频
audio_files = []
for s in scenes:
if s.get("dialogue"):
audio_path = f"audio_{s['id']}.mp3"
asyncio.run(text_to_speech(s["dialogue"], audio_path))
audio_files.append(audio_path)
else:
audio_files.append(None)最后,用FFmpeg合成视频流(动画)与音频流,并加上淡入淡出转场:
# 假设我们将所有动画片段拼接为单一视频(或分别合成)
# 此处展示单个分镜合成命令
def combine_av(video_path: str, audio_path: str, output_path: str):
cmd = [
"ffmpeg", "-i", video_path, "-i", audio_path,
"-c:v", "libx264", "-c:a", "aac", "-shortest",
"-pix_fmt", "yuv420p", output_path
]
subprocess.run(cmd, check=True)
combine_av("scene_1_anim.mp4", "audio_1.mp3", "final_scene_1.mp4")批量处理后,用concat协议将所有片段合并成最终漫剧视频。
ip_adapter_scale至0.6。motion_scale=0.5参数(需修改源码),或改用ControlNet Tile控制整体结构。torch.cuda.empty_cache(),防止显存泄漏导致OOM。本文揭开了AI漫剧的技术黑箱,从分镜脚本到动态视频,全程依赖开源模型和百行代码。零基础不再意味着从绘画学起,而是学会“编排模型”——将LLM的创意、扩散模型的视觉生成力、运动模块的动态感知力串联成自动化工作流。这套管线的延伸空间极大:加入背景音乐情绪识别、自动字幕生成、多角色语音分离,可进一步逼近专业动画品质。技术从来不是创作的壁垒,相反,当代码成为画笔,每个人都能成为世界的造物主。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。