跳到正文
阿里雲開發者社區 AI·· 3 小時前AI 評分44

AI 小説結構化文本解析與分鏡自動映射:面向 AI 漫劇本地流水線的文本預處理方案

AI 小说结构化文本解析与分镜自动映射|面向 AI 漫剧本地流水线的文本预处理方案

AI 導讀

這套 Python 方案將小説文本拆分為分鏡單元,並自動整理場景描述、對白及角色特徵 ID。程式會清理心理描寫、生成正負提示詞,為每個鏡頭設定 24 幀,最後將分鏡列表輸出至 scene_list.json。

正文
import json
import re
from typing import List, Dict
class NovelSceneParser:
    def __init__(self, character_mapping: Dict[str, str]):
        """
        character_mapping:小说角色名 -> 本地角色特征缓存ID
        示例:{"苏晚": "su_wan", "林辰": "lin_chen"}
        """
        self.character_mapping = character_mapping
        # 提示词模板,适配漫剧视频生成
        self.pos_template = (
            "9:16竖屏漫剧,平涂漫剧画风,{scene_content},"
            "动作平缓,镜头稳定,光影柔和,角色五官保持一致,无大幅度形变"
        )
        self.neg_template = (
            "画面闪烁,五官崩坏,肢体畸形,水印,多余文字,画风突变,色彩跳变"
        )
        # 匹配对话:角色:“台词”
        self.pat_dialogue = re.compile(r"([^::]{1,12})[::][\"“](.*?)[\"”]")
        # 场景切换标记,适配小说里的换行、分割标记
        self.pat_scene_split = re.compile(r"\n{2,}")
        # 过滤纯心理描写,这类文本很难可视化
        self.filter_pattern = re.compile(r"心里想着|暗自思忖|内心知道|脑海中闪过")
    def clean_text(self, text: str) -> str:
        """文本清洗,剔除不利于画面生成的内容"""
        text = self.filter_pattern.sub("", text)
        text = re.sub(r"\s+", " ", text)
        return text.strip()
    def extract_characters(self, text: str) -> List[str]:
        """从段落内识别出场角色,返回角色特征ID列表"""
        hit_ids = set()
        for name, cid in self.character_mapping.items():
            if name in text:
                hit_ids.add(cid)
        return list(hit_ids)
    def parse_block(self, block: str, shot_index: int, episode_tag: str) -> Dict:
        """单段文本解析为一个镜头单元"""
        dialogue_items = self.pat_dialogue.findall(block)
        dialogue_text = ";".join([f"{name}:{words}" for name, words in dialogue_items])
        # 去除对话之后的纯描述文本
        desc_text = self.pat_dialogue.sub("", block)
        desc_text = self.clean_text(desc_text)
        char_ids = self.extract_characters(block)
        # 优先使用场景描述生成画面提示词,描述为空则使用台词
        prompt_content = desc_text if len(desc_text) > 8 else dialogue_text
        prompt_content = prompt_content[:120] # 截断,防止提示词过长
        scene_item = {
            "scene_id": f"{episode_tag}_shot{shot_index}",
            "scene_description": desc_text,
            "dialogue": dialogue_text,
            "character_ids": char_ids,
            "positive_prompt": self.pos_template.format(scene_content=prompt_content),
            "negative_prompt": self.neg_template,
            "frame_count": 24
        }
        return scene_item
    def parse_novel(self, novel_text: str, episode_tag: str = "ep01") -> List[Dict]:
        """入口:整篇小说文本 -> 分镜列表"""
        blocks = self.pat_scene_split.split(novel_text)
        blocks = [b.strip() for b in blocks if b.strip()]
        scene_list = []
        for idx, block in enumerate(blocks, start=1):
            scene = self.parse_block(block, idx, episode_tag)
            scene_list.append(scene)
        return scene_list
if __name__ == "__main__":
    # 角色映射表,需要提前和IPAdapter缓存角色对应
    char_map = {
        "苏晚": "su_wan",
        "林辰": "lin_chen"
    }
    parser = NovelSceneParser(char_map)
    # 读取AI小说导出文本
    with open("novel_raw.txt", "r", encoding="utf-8") as f:
        novel_content = f.read()
    scene_result = parser.parse_novel(novel_content, episode_tag="ep01")
    out_file = "scene_list.json"
    with open(out_file, "w", encoding="utf-8") as fw:
        json.dump(scene_result, fw, ensure_ascii=False, indent=2)
    print(f"解析完成,共生成 {len(scene_result)} 个镜头,输出:{out_file}")

來源:阿里雲開發者社區 AI · developer.aliyun.com