SRT字幕文件可以导入nuendo吗?可以!发个代码,也不知道能有多少人用得上哈~

最近一段时间探索了一下Nuendo 的影视配音制作功能。从12开始,他们就一直在强调自己在这个方面做了强化,所谓“对白之家”
我就开始好奇,想测试一下看看到底有多智能
adr的编辑补录功能确实很强大。
但是有时候工作起来,给音轨打点有点太累了
我就在想有没有什么工具能够在这个场景优化一下。
于是我想到了ai
找了通义给我写了一段代码
亲测有效!
下面把这个代码分享出来,因为我自己用的是苹果,所以有个py文件传在附件里了,如果用win的朋友可以上网查一下看看怎么搞哈



Python:
import re
import csv

def convert_srt_time_to_hhmmssff(time_str):
    """Convert SRT timecode to hh:mm:ss:ff format."""
    hours, minutes, seconds_milliseconds = time_str.split(':')
    seconds, milliseconds = seconds_milliseconds.split(',')
    frame = int(round(float(milliseconds) / 1000 * 30))  # Assuming 30 fps
    return f"{hours}:{minutes}:{seconds}:{frame:02d}"

def parse_srt_file(srt_filename, output_filename):
    """Parse SRT file and write converted data to CSV file."""
    last_known_role = ""
    entries = []
    pattern = re.compile(r'(\d\d:\d\d:\d\d,\d\d\d) --> (\d\d:\d\d:\d\d,\d\d\d)')
   
    with open(srt_filename, 'r', encoding='utf-8') as file:
        lines = file.readlines()
       
        i = 0
        index_number = 1  # Initialize index_number with 1
        role_reset_needed = False  # Flag to indicate if role needs to be reset
       
        while i < len(lines):
            if lines[i].strip().isdigit():  # Skip index number
                index_number = int(lines[i].strip())  # Assign index_number
                i += 1
           
            if '-->' in lines[i]:  # Time code line
                match = pattern.match(lines[i])
                if match:
                    start_time, end_time = match.groups()
                    start_time_converted = convert_srt_time_to_hhmmssff(start_time)
                    end_time_converted = convert_srt_time_to_hhmmssff(end_time)
                   
                    i += 1
                    text = ''
                    while i < len(lines) and lines[i].strip() != '':
                        text += lines[i].strip()
                        i += 1
                   
                    # Extract comment and remove brackets
                    comment_match = re.search(r'【.*?】', text)
                    comment = comment_match.group(0).strip('【】') if comment_match else ''
                    text = re.sub(r'【.*?】', '', text).strip()
                   
                    # Determine role name and dialog based on context
                    if comment_match:
                        role_name = ''  # Set role name to empty if there is a comment
                        dialog = text.strip()  # Assign dialog directly from text
                        role_reset_needed = True  # Reset role after this entry
                    else:
                        parts = text.split(':', 1)
                        if len(parts) == 2:
                            potential_role_name = parts[0].strip()
                            potential_dialog = parts[1].strip()
                           
                            # Check if the potential role name is short enough to be a role name
                            if len(potential_role_name) <= 5:
                                role_name = potential_role_name
                                dialog = potential_dialog
                                last_known_role = role_name  # Update last_known_role
                                role_reset_needed = False  # Reset flag since we have a new role
                            else:
                                role_name = last_known_role
                                dialog = text.strip()
                        else:
                            role_name = last_known_role
                            dialog = text.strip()
                   
                    # Use the previously assigned index_number
                    id_value = index_number
                   
                    entries.append({
                        "轨道名称": "标记",
                        "时码输入": start_time_converted,
                        "时码输出": end_time_converted,
                        "描述": '',
                        "长度": '',
                        "ID": id_value,
                        "注释": comment,
                        "录音完成": '',
                        "角色名字": role_name if not role_reset_needed else '',
                        "对话": dialog,
                        "对话翻译 1": ''
                    })
                i += 1
            else:
                i += 1
   
    with open(output_filename, 'w', newline='', encoding='utf-8') as csvfile:
        fieldnames = ["轨道名称", "时码输入", "时码输出", "描述", "长度", "ID", "注释", "录音完成", "角色名字", "对话", "对话翻译 1"]
        writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
       
        writer.writeheader()
        for entry in entries:
            writer.writerow(entry)

# 指定输入和输出文件的位置
input_filename = 'path/to/your_srt_file.srt'  # 替换为你的SRT文件的实际路径
output_filename = 'path/to/converted.csv'  # 替换为你想要保存CSV文件的路径

# 调用函数
parse_srt_file(input_filename, output_filename)
print(f"转换完成,CSV文件已保存为 {output_filename}")


运行的时候需要python环境,我下载的是python3

给大家看一下效果哈

这是原本srt文件的预览
11821724204651_.pic.jpg



有序号,角色名(角色名后有冒号,冒号为中文字符)、提示词(方括号内标注,方括号为中文字符)
对白内容(画外音的标注是【画外音】这个模式
有完整的时间区段,时码格式是小时分秒和千进制的毫秒
这个python程序是让这个srt文件变成一个符合nuendo导入的csv格式文件
当然其实excel也可以做,但是可能稍显复杂了,
通过这个转换完之后,这个csv文件是这个样子的
11831724204652_.pic.jpg

把时码的出入点转化为hhmmssff带帧数的格式,然后把【】里的文字统一标注为注释行
角色名字归为角色行
对话内容包括画外音全部归入对话行
如果是双人对话,可能在原始文档里只有一个“角色名:对白”的格式,后面的对白就是没有角色名的了
那么这个转换出来,两个角色名之间的角色,会被填成第一个角色的名字,这样方便后续在nuendo里归类
他如何识别:前到底是角色名还是引用呢?
我在这里设定了冒号前如果是5个字,那么归为角色名
如果冒号前超过了5个字,那会归为对话
转换完成,导入nuendo,
下图就是最后呈现出来的效果了
11841724204653_.pic.jpg

利用这个adr编辑器,确实可以很好的补录和编辑


但是还有个小问题我没搞懂
就是我怎么操作能把同一个人说话的mark点选中的部分全部导出到一个轨道呢?


ai告诉我可以用generate audio track from markers
但是我没找到这个按钮在哪里……
有懂的老师希望不吝赐教哈~




希望这个东西对大家有帮助!
 

附件

  • srt-csv_auto.py.zip
    2.4 KB · 查看: 48
打赏用户
飞来音

AntiO

战列舰
KONTAKT VIP
电音人星公民
初级 VIP
正式用户
🧱星陨矿
105,350
🧊星能体
60
🍀星灵素
54
🏵️星元核
0
太强了群友
虽然我应该用不上但还是顶一下帖子
 

飞来音

无问不答指挥官
社区管理员
KONTAKT VIP
中级 VIP
初级 VIP
🧱星陨矿
61,200
🧊星能体
125
🍀星灵素
90
🏵️星元核
35
我只能说 666····史诗级拓荒教程