# Plan - [ ] [[PWA - 渐进式 Web 应用]]实现手机 mp3 上传 - [ ] http://100.84.194.21:3000 - [ ] openai 的 transcribe 实现 [[ASR]],[[Web Audio API]]实现变速播放 - [ ] 实现上传 url,抓取音视频 下载 youtube 的 url 并转为音频,按照 5 分钟一个批次来处理转写和变速 ``` 当你执行 `yt-dlp -x --audio-format mp3 https://youtube.com/xxxx` 流程其实是: 1. yt-dlp 下载原始视频文件(通常是 `.webm` 或 `.mp4`); 2. 调用 `ffmpeg`: - 分离音频轨道 - 转码成你指定的格式(如 mp3) - 删除临时文件 ``` ## 相关技术 [[Web Audio API]] ```Java 上传MP3 ↓ 调用Whisper API获取transcription + 时间戳 ↓ 分句 + 词汇检测(标记哪些句子需要变速) ↓ 使用Web Audio API动态调整播放速度 ↓ 无缝播放 ``` # React Native 做 iOS 的关键点 **1. 开发环境要求** - 需要 **Mac 电脑**(这是硬性要求) - 安装 Xcode(苹果官方开发工具) - 配置 CocoaPods(iOS 依赖管理) **2. 发布到 App Store 需要** - **Apple Developer 账号**:$99/年 - 这是无法省掉的成本,想上架 iOS 就必须交这个钱 **3. 实际开发流程** ```Java Next.js (Web端) + React Native (App端) ↓ 共用后端 API ↓ Node.js + 数据库 ``` # 更省钱的替代方案 如果暂时没有 Mac 或不想花 $99: **方案 A:[[PWA - 渐进式 Web 应用]](渐进式 Web 应用)** - 用 Next.js 做成 PWA - 可以"添加到主屏幕",体验接近原生 app - 完全免费,不需要上架 App Store **方案 B:Expo + EAS** - Expo 可以在云端构建 iOS app(不需要 Mac) - 但发布还是需要 Apple Developer 账号 # 我的建议 1. **先做 Web 版**:用 Next.js + Vercel 快速验证想法 2. **等有用户了再考虑 app**:确认值得投入成本 3. **iOS 门槛确实高**:Mac + 年费是绕不过去的 你现在是想同时做 Web 和 iOS,还是先专注一个平台? Retry 7 你遇到的经典问题变体 这是“分词粒度选择(tokenization granularity)”在语言学习/词汇掌握场景下的变体:为了让人读/学得顺手,应该把文本切成什么单位(词、词形、词根、短语、子词…)来统计“我不认识的东西”。 ⸻ 结论(TL;DR) 为了做“从字幕里找出我可能不认识的词”的英语听力助手,不要把 BPE/WordPiece 这类面向模型的子词当作学习单位。 用一个“以人读为中心”的三层方案更合适: 1. 短语级(MWE)优先:把固定搭配/动词短语(如 look up, take off, in spite of)作为一个“词”。 2. 词元级(lemma)统一:把屈折变化(walk, walks, walked)统一到词元 walk;收缩词统一(don’t → do not)。 3. 子词只做兜底:只在极少数未登录的长复合词/新词上做形态切分提示,不作为你的“已知词表”的主键。 这样更贴近人类的“词感”,能显著减少误报/漏报: • 不会把 went 当作新词(已知 go 即可)。 • 不会把 look up 拆成两个“已知词”而漏掉“短语新义”。 • 不会产生 ##tion、ing 之类模型友好但“人不学习”的碎片。 为什么是这个粒度 • 词元(lemma)符合人类词汇记忆:我们记 go,而不是单独记 go/goes/went/gone 四个条目。 • 多词表达(MWE)在口语/听力里信息量很大(动词短语、习语、固定搭配),拆开会丢义项。 • 子词(BPE/WordPiece)服务于 OOV 与参数效率,对人学习意义不大,且会把熟词拆碎,造成假阳性“新词”。 可落地的分词/归一化流水线 目标:输入字幕,输出“我未知”的词元或短语清单,尽量贴合人的直觉。 Step 0. 预处理(正则化) • 小写化(但保留专有名词的大小写信号)。 • 收缩词展开:I’m → I am, don’t → do not, won’t → will not, gonna → going to, wanna → want to 等。 • 变体统一:美式/英式拼写(color/colour)、连字符(well-known / well known)做规则统一。 Step 1. 基础分词 + 句法/词性 • 常规英文分词(空格+标点)→ 词性(POS)→ 依存(可选)。 Step 2. 多词表达识别(强烈建议) • 识别并合并: • 动词短语:look up, run into, put up with, take care of • 固定搭配/习语:in charge of, as soon as, kind of • 粒度规则:合并后用下划线表示一个 token:look_up。 • 技术途径:基于词表的匹配(高精度)+ 句法模板(V + Particle/Prep)做补充。 Step 3. 词形还原(Lemmatization) • 对非 MWE的 token 做词元化:went → go, better(比较级)→ good。 • 屈折 vs 派生区分: • 屈折(walked, cats)统一为已知 walk, cat; • 派生(happy → happiness, unhappy)可设“半已知”策略(见下)。 Step 4. 命名实体与数字的处理 • 命名实体(人名/地名/组织)默认“忽略统计”或单独列表(很多并非语言技能障碍)。 • 数字/日期/单位统一成占位(如 `<NUM>`),避免噪声。 Step 5. 个人词库对齐与未知判定 • 你的“已知表”建议分三栏: • known_lemmas(词元) • known_mwes(短语) • known_morph_families(可选,派生家族,如 act → action, active, activity) • 判定逻辑(从严到宽): 1. 在 known_mwes?→ 已知 2. 否则取 lemma:在 known_lemmas?→ 已知 3. 否则检查是否属于某派生家族(规则或词典)→ 标记“半已知”(供复习而不算难点) 4. 其余为未知。 • 可加频次权重(基于通用频表或你语料的相对频次),优先推送“高频未知”。 ⸻ 真实字幕里的典型坑与对策 • 收缩词不展开会虚增未知(don’t ≠ 新词)。 • 动词短语拆开会丢义(figure_out 与 figure 差异大)。 • 不规则变化(went, better, worst)需要词形还原词典支持。 • 连字符与复合词(decision-making, five-year-old):建议作为一个词处理,但也保留子词提示(decision + make + -ing)用于讲解。 • 拼写变体(theater/theatre):统一到一种规范键。 ⸻ 你可以用的开源组件(思路与组合) 不必追新版本,挑稳定好用的就行。 • 分词/词性/词形还原:spaCy / Stanza(英语管线足够) • MWE 识别: • 规则 + 词表(自建动词短语表); • spaCy Matcher/DependencyMatcher 根据(动词+小品词/介词)模板合并。 • 收缩词展开:小词典就够(几十条覆盖 95% 场景)。 • 频率信息:任意通用频表或你自己的语料频次。 •(可选)派生家族:简单规则(前后缀)+ 白名单纠错。 ⸻ 极简判定流程(伪代码) ```Java text = normalize_case_and_variants(subtitles) text = expand_contractions(text)              # I'm→I am, don't→do not, gonna→going to tokens = tokenize(text)                       # 基础分词 tokens = merge_mwes(tokens)                   # look up→look_up, in spite of→in_spite_of ann = pos_and_lemma(tokens)                   # 词性+词元 unknown = [] for tok in ann:     if tok.is_entity or tok.is_number:         continue     key = tok.mwe_lemma if tok.is_mwe else tok.lemma     if key in known_mwes or key in known_lemmas:         continue     elif in_derivational_family(key, known_morph_families):         mark_as_semi_known(key)               # 半已知:用于温习,不算“生词炸弹”     else:         unknown.append(key) ``` 可按频次或行级密度排序,给学习计划用 可配置的“人味儿”开关 • 是否把专有名词计入未知:默认不计;备选:仅计“可发音难点”的人名地名。 • 派生是否算已知:面向应试→算;面向表达力→不算,单列讲解。 • 高频功能词:若你的已知表未覆盖,可直接白名单前 2–3k 功能词。 • 阈值:一句里未知 > k 个则推送暂停/讲解卡片。 ⸻ 小示例 字幕:“I’m gonna look it up and then I’ll figure it out.” • 展开:I am going to look it up and then I will figure it out. • 合并 MWE:look_up, figure_out • 词元:am → be, going → go, will → will … • 未知判定:如果你已知 look_up 但未知 figure_out,则只推 figure_out;若已知 go,不会把 going 计为新词。 一句话总结 把“短语(MWE)+ 词元(lemma)”作为主单位,子词仅兜底。这套粒度最贴近人阅读与记忆方式,能更准确地从字幕里筛出对你真正陌生的内容,同时避免把语法变化和收缩词当成“新词”干扰学习。