一遍关于自动AI小说推文的实现

PS: 市面上已经出现不少收费的软件工具，类似极虎漫剪、速推之类封装好的工具，但其核心功能实现都是一样，要考验的还是 GPT 效果；今年出现的 Sora 相当这个赛道方向的进化版本，在以后更有可能冲击影视制作领域 (UE4)

功能设计

1、提取分镜场景：小说文本分句、SD 生成图片和 TTS 文本转语音频

2、小说内容 > 推导提示词 (SD 绘画)

3、图片音频合并视频

模型:
TTS (edge)、SD 绘画模型 (这里使用)、GPT (这里使用 Gemini)

项目地址:story-vision

核心代码

小说分镜提取 GPT

Copy
prompt = """我想让你对小说内容进行分镜，根据原文描述推断出的场景；推断和补充缺失或隐含的信息，包括但不限于：人物衣服，人物发型，人物发色，人物脸色，人物五官特点，人物体态，人物情绪，人物肢体动作等）、风格描述（包括但不限于：年代描述、空间描述、时间段描述、地理环境描述、天气描述）、物品描述（包括但不限于：动物、植物、食物、水果、玩具）、画面视角（包括但不限于：人物比例、镜头深度描述、观察角度描述），但不要过度。通过镜头语言描述，描绘更丰富的人物情绪和情感状态，你理解后通过句子生成一段新的描述内容。输出格式改为：插画一：原文描述：对应的原文全部句子；画面描述：对应的画面剧情内容；画面角色：画面中出现的角色名称；穿着：主角穿着便装；位置：坐在吧台前；表情：面部线条温和，表情惬意； 行为：手上轻轻晃动着手中的酒杯。环境：吧台的背景是暗调的，烛光在背景中摇曳，给人一种迷离的感觉。如果你理解了这一点要求，请确认这五点要求，返回结果只要这五点的内容，小说内容如下:"""

def split_text_into_chunks(text, max_length=ai_max_length):
"""
Split text into chunks with a maximum length, ensuring that splits only occur at line breaks.
"""
lines = text.splitlines()
chunks = []
current_chunk = ''
for line in lines:
if len(current_chunk + ' ' + line) <= max_length:
current_chunk += ' ' + line
else:
chunks.append(current_chunk)
current_chunk = line
chunks.append(current_chunk)
return chunks

def rewrite_text_with_genai(text, prompt="Please rewrite this text:"):
chunks = split_text_into_chunks(text)
rewritten_text = ''
# pbar = tqdm(total=len(chunks), ncols=150)
genai.configure(api_key=cfg['genai_api_key'])
model = genai.GenerativeModel('gemini-pro')
for chunk in chunks:
_prompt=f"{prompt}\n{chunk}",
response = model.generate_content(
contents=_prompt,
generation_config=genai.GenerationConfig(
temperature=0.1,
),
stream=True,
safety_settings = [
{
"category": "HARM_CATEGORY_DANGEROUS",
"threshold": "BLOCK_NONE",
},
{
"category": "HARM_CATEGORY_HARASSMENT",
"threshold": "BLOCK_NONE",
},
{
"category": "HARM_CATEGORY_HATE_SPEECH",
"threshold": "BLOCK_NONE",
},
{
"category": "HARM_CATEGORY_SEXUALLY_EXPLICIT",
"threshold": "BLOCK_NONE",
},
{
"category": "HARM_CATEGORY_DANGEROUS_CONTENT",
"threshold": "BLOCK_NONE",
},
]
)
for _chunk in response:
if _chunk.text is not None:
rewritten_text += _chunk.text.strip()
# pbar.update(1)
# pbar.close()
return rewritten_text

分镜输出

SD 文生图

SD 的提示词是通过上面输出的分镜文本让 GPT 编写的

Copy
from diffusers import StableDiffusionPipeline
from diffusers.utils import load_image
import torch

model_path = "./models/cetusMix_Whalefall2.safetensors"
pipeline = StableDiffusionPipeline.from_single_file(
model_path,
torch_dtype=torch.float16,
variant="fp16"
).to("mps")
generator = torch.Generator("mps").manual_seed(31)

def sd_cetus(save_name, prompt):
prompt = prompt
image = pipeline(prompt).images[0]
image.save('data/img/'+ save_name +'.jpg')

图片效果

TTS 音频生成

网上有很多关于 TTS 的，这里使用了 edge 提供的

Copy
import edge_tts
import asyncio

voice = 'zh-CN-YunxiNeural'
output = 'data/voice/'
rate = '-4%'
volume = '+0%'

async def tts_function(text, save_name):
tts = edge_tts.Communicate(
text,
voice=voice,
rate=rate,
volume=volume
)
await tts.save(output + save_name + '.wav')

视频效果

[video(video-7erojzmT-1713340240300)(type-csdn)(url-https://live.csdn.net/v/embed/379613)(image-https://video-community.csdnimg.cn/vod-84deb4/00b03862fc8b71eebfc44531859c0102/snapshots/0bc4b0ed08a54fc2a412ee3ad1f3fdf2-00005.jpg?auth_key=4866938633-0-0-f335ae8248a7095d7f5d885a25aba80e)(title - 第 1 章 进局子了_out)]