Sign in

    srt

    Download zip
    Author
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    7 months ago
    Downloads
    40

    #SRT字幕生成器

    一个用MoonBit编写的SRT字幕文件生成工具,可以根据文本内容自动生成带有时间戳的字幕文件。

    #功能特性

    • 📝 从文本文件自动生成SRT字幕
    • ⏱️ 智能时间计算(适配剪映甜美女声语速)
    • 🎯 自动过滤中文注释(全角括号内容)
    • 📄 标准SRT格式输出
    • 🧪 完整的测试覆盖
    • 📚 详细的API文档

    #安装

    #前提条件

    #获取项目

    # 克隆项目(如果是从Git获取) git clone <项目地址> cd srt

    #快速开始

    #1. 准备输入文件

    创建 src.txt 文件,包含要转换为字幕的文本:

    你好,世界 欢迎使用SRT生成器 这是一个示例字幕文件

    注意:
    • 每行一个台词
    • 空行表示1秒的停顿
    • 以全角括号()包围的内容会被自动过滤

    #2. 运行程序

    moon run cmd/main

    #3. 查看结果

    程序会:
    1. 在终端显示生成的SRT内容
    2. 创建 output.srt 文件

    生成的 output.srt 文件内容示例:
    1 00:00:00,000 --> 00:00:01,000 你好,世界 2 00:00:02,000 --> 00:00:03,000 欢迎使用SRT生成器 3 00:00:04,000 --> 00:00:05,000 这是一个示例字幕文件

    #API文档

    #核心类型

    #Srt - SRT字幕容器

    ///|
    /// SRT字幕文件的容器结构体。
    pub(all) struct Srt {
    pieces : Array[Piece]
    }

    方法:
    • Srt::new() -> Srt - 创建空SRT文件
    • Srt::add_piece(self : Srt, piece : Piece) -> Unit - 添加字幕片段

    #Piece - 字幕片段

    ///|
    /// SRT文件中的字幕片段,包含时间和内容信息。
    pub(all) struct Piece {
    index : Int // 字幕序号
    start : Int // 开始时间(秒)
    end : Int // 结束时间(秒)
    text : String // 字幕文本
    }

    方法:
    • Piece::new(index : Int, start : Int, end : Int, text : String) -> Piece - 创建字幕片段
    • Piece::sec_to_hms(sec : Int) -> String - 秒数转换为HMS格式

    #文件操作

    #read_lines

    /// 从文本文件读取所有行,并进行预处理。
    pub fn read_lines(file_path : String) -> Array[String] raise @fs.IOError

    功能:
    • 读取文件内容
    • 统一换行符为\n
    • 过滤以全角括号开头和结尾的行

    #write_lines

    /// 将字符串数组写入文件,每行用换行符分隔。
    pub fn write_lines(file_path : String, lines : Array[String]) -> Unit raise @fs.IOError

    #算法说明

    #时间计算

    程序使用以下算法计算每个台词的时间:

    1. 字符时间计算:
      台词时长 = ceil(字符数 × 0.2) 秒
      其中 0.2 是 CHAR_PER_SECOND 常量,表示每个字符0.2秒。

    2. 空行处理:
      • 空行表示1秒的停顿
      • 空行不会生成字幕片段

    3. 时间累加:
      • 每个台词结束后,时间指针移动到该台词的结束时间
      • 下一个台词从这个时间开始

    #示例计算

    输入文本:
    你好(2字符) 空行 世界(2字符)

    计算过程:
    1. "你好":2 × 0.2 = 0.4秒 → 向上取整为1秒(时间:0-1秒)
    2. 空行:1秒停顿(时间:1-2秒)
    3. "世界":2 × 0.2 = 0.4秒 → 向上取整为1秒(时间:2-3秒)

    #开发指南

    #项目结构

    srt/ ├── src/ # 库代码 │ ├── srt.mbt # SRT核心逻辑 │ └── fs.mbt # 文件系统操作 ├── cmd/main/ # 命令行程序 │ └── main.mbt # 主程序入口 ├── srt_mbt_test.mbt # 黑盒测试 ├── srt_mbt_wbtest.mbt # 白盒测试 └── moon.mod.json # 项目配置

    #运行测试

    # 运行所有测试 moon test # 运行测试并更新快照 moon test --update # 只运行当前包的测试 moon test -p srt_mbt # 详细模式 moon test -v

    #代码格式化

    moon fmt

    #类型检查

    moon check

    #配置调整

    #修改语速

    在 cmd/main/main.mbt 中修改 CHAR_PER_SECOND 常量:

    // 默认:剪映甜美女声语速(0.2秒/字符)

    ///|
    const CHAR_PER_SECOND = 0.2

    // 快速语速(0.15秒/字符)
    // const CHAR_PER_SECOND = 0.15

    // 慢速语速(0.25秒/字符)
    // const CHAR_PER_SECOND = 0.25

    #修改输入输出文件

    在 cmd/main/main.mbt 的 main 函数中修改文件路径:

    // 修改输入文件
    let lines = @srt.read_lines("my_input.txt") catch { ... }

    // 修改输出文件
    @srt.write_lines("my_output.srt", ...) catch { ... }

    #示例代码

    #基本使用

    ///|
    test "基本SRT创建" {
    let srt = @srt.Srt::new()
    let piece = @srt.Piece::new(1, 0, 5, "Hello, World!")
    srt.add_piece(piece)

    inspect(srt.pieces.length(), content="1")
    inspect(piece.text, content="Hello, World!")
    }

    #时间格式转换

    ///|
    test "时间格式转换" {
    inspect(@srt.Piece::sec_to_hms(0), content="00:00:00,000")
    inspect(@srt.Piece::sec_to_hms(65), content="00:01:05,000")
    inspect(@srt.Piece::sec_to_hms(3665), content="01:01:05,000")
    }

    #文件操作

    ///|
    test "文件读写示例" {
    // 注意:这些测试需要实际文件,通常使用模拟数据
    let test_lines = ["Line 1", "Line 2", "Line 3"]

    // 模拟写入
    let content = test_lines.join("\n")
    inspect(
    content,
    content=(
    #|Line 1
    #|Line 2
    #|Line 3
    #|
    ),
    )
    }

    #许可证

    本项目基于 Apache License 2.0 许可证开源。

    #贡献指南

    1. Fork 项目
    2. 创建功能分支
    3. 提交更改
    4. 推送到分支
    5. 创建 Pull Request

    #问题反馈

    如果您遇到问题或有改进建议,请:
    1. 查看现有问题
    2. 创建新issue,包含:
      • 问题描述
      • 复现步骤
      • 期望行为
      • 实际行为

    #更新日志

    #v0.1.0

    • 初始版本发布
    • 基本SRT生成功能
    • 文件读写支持
    • 完整测试套件
    • 详细API文档

    Srt

    SRT字幕文件的容器结构体。

    包含一个字幕片段数组,用于存储和管理整个SRT文件的内容。 每个SRT文件由多个按时间顺序排列的字幕片段组成。

    字段:
    • pieces : 字幕片段数组,按时间顺序存储所有字幕片段。

    read_lines

    fn read_lines(file_path : String) -> Array[String] raise
    IOError

    从文本文件读取所有行,并进行预处理。

    此函数执行以下操作:
    1. 读取整个文件内容为字符串
    2. 统一换行符为\n(处理Windows的\r\n)
    3. 按换行符分割为行数组
    4. 过滤掉以全角括号开头和结尾的行(通常用于中文注释)

    参数:
    • file_path : 要读取的文件路径

    返回:经过预处理的行数组

    可能抛出的错误:@fs.IOError - 当文件读取失败时

    示例:
    // 假设文件内容为:
    // 第一行
    // (这是注释)
    // 第二行
    let lines = read_lines("example.txt")
    inspect(lines.length(), content="2")
    inspect(lines[0], content="第一行")
    inspect(lines[1], content="第二行")

    write_lines

    fn write_lines(file_path : String, lines : Array[String]) -> Unit raise
    IOError

    将字符串数组写入文件,每行用换行符分隔。

    此函数执行以下操作:
    1. 将字符串数组用\n连接成单个字符串
    2. 将结果字符串写入指定文件

    参数:
    • file_path : 要写入的文件路径
    • lines : 要写入的字符串数组,每个元素将成为文件的一行

    可能抛出的错误:@fs.IOError - 当文件写入失败时

    示例:
    let lines = ["第一行", "第二行", "第三行"]
    write_lines("output.txt", lines)
    // 文件内容将是:
    // 第一行
    // 第二行
    // 第三行

    Source Files