WWW.YOUINFO.SITE
标签聚合 分配

/tag/分配

LinuxDo 最新话题 · 2026-06-09 21:44:27+08:00 · tech

Python版本 """ 基于音节/字数精确分配时间 """ import re import tkinter as tk from tkinter import ttk, filedialog, messagebox, scrolledtext # ==================== 核心逻辑 ==================== def count_english_syllables(word): w = word.strip('.,;:!?"\'()[]{}').lower() if not w: return 0 vowels = set("aeiouy") count = 0 prev_is_vowel = False for ch in w: is_vowel = ch in vowels if is_vowel and not prev_is_vowel: count += 1 prev_is_vowel = is_vowel if w.endswith("e") and not w.endswith("le") and count > 1: count -= 1 if w.endswith("le") and len(w) > 2 and w[-3] not in vowels: count += 1 return max(count, 1) def count_pronunciation_units(text): total = 0 tokens = re.findall(r'[\u4e00-\u9fff]|[a-zA-Z]+|\d+%?|[^\s]', text) for token in tokens: if re.match(r'[\u4e00-\u9fff]', token): total += 1 elif re.match(r'[a-zA-Z]+', token): total += count_english_syllables(token) elif re.match(r'\d+%?', token): digits = token.replace('%', '') total += min(len(digits) + 1, 5) return total def split_sentences(text): parts = re.split(r'(?<=[.,;])\s+', text) return [p.strip() for p in parts if p.strip()] def ms_to_parts(ms): total_sec = ms / 1000 m = int(total_sec // 60) s = total_sec - m * 60 return m, s def fmt_lyrics3(ms): m, s = ms_to_parts(ms) return f"[{m:02d}:{s:05.2f}]" def fmt_srt(ms): m, s = ms_to_parts(ms) return f"{m:02d}:{s:05.2f}".replace(".", ",") def fmt_ass(ms): m, s = ms_to_parts(ms) h = m // 60 m = m % 60 return f"{h}:{m:02d}:{s:05.2f}" def fmt_vtt(ms): m, s = ms_to_parts(ms) return f"{m:02d}:{s:06.3f}" def generate_subtitles(text, total_seconds, fmt="lyrics3"): total_ms = float(total_seconds) * 1000 sentences = split_sentences(text) if not sentences: return "", 0 units_per_sentence = [count_pronunciation_units(s) for s in sentences] total_units = sum(units_per_sentence) if total_units == 0: return "", 0 ms_per_unit = total_ms / total_units timings = [] cur = 0.0 for i, s in enumerate(sentences): dur = units_per_sentence[i] * ms_per_unit timings.append((cur, cur + dur, s)) cur += dur formatters = {"lyrics3": fmt_lyrics3, "srt": fmt_srt, "ass": fmt_ass, "vtt": fmt_vtt} f = formatters.get(fmt, fmt_lyrics3) lines = [] if fmt == "vtt": lines.append("WEBVTT\n") elif fmt == "ass": lines.append("[Script Info]") lines.append("ScriptType: v4.00+") lines.append("PlayResX: 384") lines.append("PlayResY: 288\n") lines.append("[V4+ Styles]") lines.append("Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding") lines.append("Style: Default,Arial,20,&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2,2,2,10,10,10,1\n") lines.append("[Events]") lines.append("Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text") for i, (start, end, sent) in enumerate(timings): if fmt == "srt": lines.append(str(i + 1)) lines.append(f"{f(start)} --> {f(end)}") lines.append(sent) lines.append("") elif fmt == "ass": lines.append(f"Dialogue: 0,{f(start)},{f(end)},Default,,0,0,0,,{sent}") elif fmt == "vtt": lines.append(f"{f(start)} --> {f(end)}") lines.append(sent) lines.append("") else: lines.append(f"{f(start)}{sent}") return "\n".join(lines), len(sentences) # ==================== GUI ==================== class SubtitleApp: def __init__(self, root): self.root = root self.root.title("字幕时间轴生成器") self.root.geometry("900x720") self.root.configure(bg="#1e1e2e") self.root.minsize(700, 550) # 样式 style = ttk.Style() style.theme_use("clam") style.configure("TFrame", background="#1e1e2e") style.configure("TLabel", background="#1e1e2e", foreground="#cdd6f4", font=("Segoe UI", 11)) style.configure("TButton", background="#45475a", foreground="#cdd6f4", font=("Segoe UI", 10), borderwidth=0, padding=8) style.map("TButton", background=[("active", "#585b70")]) style.configure("TEntry", fieldbackground="#313244", foreground="#cdd6f4", font=("Segoe UI", 11), padding=6) style.configure("TCombobox", fieldbackground="#313244", foreground="#cdd6f4", font=("Segoe UI", 11), padding=4) self.build_ui() def build_ui(self): # 主容器 main = ttk.Frame(self.root, padding=20) main.pack(fill="both", expand=True) # 标题 title = tk.Label(main, text="🎬 字幕时间轴生成器", font=("Segoe UI", 20, "bold"), bg="#1e1e2e", fg="#cba6f7") title.pack(pady=(0, 5)) subtitle = tk.Label(main, text="基于音节/字数精确分配时间 · 支持中英混合", font=("Segoe UI", 10), bg="#1e1e2e", fg="#6c7086") subtitle.pack(pady=(0, 20)) # 输入区域 input_frame = ttk.Frame(main) input_frame.pack(fill="both", expand=True) lbl_input = tk.Label(input_frame, text="📝 输入文本(按句号/逗号/分号自动分句)", font=("Segoe UI", 11, "bold"), bg="#1e1e2e", fg="#a6adc8") lbl_input.pack(anchor="w") self.text_input = scrolledtext.ScrolledText( input_frame, height=10, font=("Segoe UI", 11), bg="#313244", fg="#cdd6f4", insertbackground="#cdd6f4", relief="flat", borderwidth=0, padx=12, pady=12, wrap=tk.WORD, highlightthickness=1, highlightbackground="#45475a" ) self.text_input.pack(fill="both", expand=True, pady=(5, 15)) # 设置行 settings_frame = ttk.Frame(main) settings_frame.pack(fill="x", pady=(0, 15)) # 时长 dur_frame = ttk.Frame(settings_frame) dur_frame.pack(side="left", padx=(0, 30)) ttk.Label(dur_frame, text="⏱ 总时长(秒)").pack(side="left", padx=(0, 8)) self.duration_var = tk.StringVar(value="73") self.duration_entry = ttk.Entry(dur_frame, textvariable=self.duration_var, width=10) self.duration_entry.pack(side="left") # 格式 fmt_frame = ttk.Frame(settings_frame) fmt_frame.pack(side="left", padx=(0, 30)) ttk.Label(fmt_frame, text="📄 输出格式").pack(side="left", padx=(0, 8)) self.format_var = tk.StringVar(value="lyrics3") fmt_combo = ttk.Combobox(fmt_frame, textvariable=self.format_var, values=["lyrics3", "srt", "ass", "vtt"], state="readonly", width=10) fmt_combo.pack(side="left") # 统计 self.stats_var = tk.StringVar(value="分句: 0 句 | 总发音单位: 0") stats_label = tk.Label(settings_frame, textvariable=self.stats_var, font=("Segoe UI", 10), bg="#1e1e2e", fg="#6c7086") stats_label.pack(side="right") # 按钮 btn_frame = ttk.Frame(main) btn_frame.pack(fill="x", pady=(0, 15)) self.btn_generate = tk.Button( btn_frame, text="✨ 生成字幕", font=("Segoe UI", 12, "bold"), bg="#cba6f7", fg="#1e1e2e", activebackground="#b4befe", activeforeground="#1e1e2e", relief="flat", borderwidth=0, padx=24, pady=10, cursor="hand2", command=self.on_generate ) self.btn_generate.pack(side="left", padx=(0, 10)) self.btn_copy = tk.Button( btn_frame, text="📋 复制全部", font=("Segoe UI", 11), bg="#45475a", fg="#cdd6f4", activebackground="#585b70", activeforeground="#cdd6f4", relief="flat", borderwidth=0, padx=20, pady=10, cursor="hand2", command=self.on_copy ) self.btn_copy.pack(side="left", padx=(0, 10)) self.btn_save = tk.Button( btn_frame, text="💾 保存文件", font=("Segoe UI", 11), bg="#45475a", fg="#cdd6f4", activebackground="#585b70", activeforeground="#cdd6f4", relief="flat", borderwidth=0, padx=20, pady=10, cursor="hand2", command=self.on_save ) self.btn_save.pack(side="left") # 输出区域 output_frame = ttk.Frame(main) output_frame.pack(fill="both", expand=True) lbl_output = tk.Label(output_frame, text="📤 生成结果", font=("Segoe UI", 11, "bold"), bg="#1e1e2e", fg="#a6adc8") lbl_output.pack(anchor="w") self.text_output = scrolledtext.ScrolledText( output_frame, height=12, font=("Cascadia Code", 10), bg="#11111b", fg="#a6e3a1", insertbackground="#a6e3a1", relief="flat", borderwidth=0, padx=12, pady=12, wrap=tk.NONE, highlightthickness=1, highlightbackground="#45475a" ) self.text_output.pack(fill="both", expand=True, pady=(5, 0)) def on_generate(self): text = self.text_input.get("1.0", "end-1c").strip() if not text: messagebox.showwarning("提示", "请先输入文本。") return try: duration = float(self.duration_var.get()) if duration <= 0: raise ValueError except ValueError: messagebox.showwarning("提示", "请输入有效的正数时长(秒)。") return fmt = self.format_var.get() result, count = generate_subtitles(text, duration, fmt) self.text_output.delete("1.0", "end") if result: self.text_output.insert("1.0", result) total_units = sum(count_pronunciation_units(s) for s in split_sentences(text)) self.stats_var.set(f"分句: {count} 句 | 总发音单位: {total_units}") def on_copy(self): result = self.text_output.get("1.0", "end-1c").strip() if result: self.root.clipboard_clear() self.root.clipboard_append(result) messagebox.showinfo("提示", "已复制到剪贴板!") def on_save(self): result = self.text_output.get("1.0", "end-1c").strip() if not result: messagebox.showwarning("提示", "没有可保存的内容,请先生成字幕。") return fmt = self.format_var.get() exts = {"lyrics3": ".txt", "srt": ".srt", "ass": ".ass", "vtt": ".vtt"} ext = exts.get(fmt, ".txt") path = filedialog.asksaveasfilename( defaultextension=ext, filetypes=[(f"{fmt.upper()} 字幕", f"*{ext}"), ("所有文件", "*.*")] ) if path: with open(path, "w", encoding="utf-8") as f: f.write(result) messagebox.showinfo("提示", f"已保存到:{path}") if __name__ == "__main__": root = tk.Tk() app = SubtitleApp(root) root.mainloop() HTML版本 3 个帖子 - 3 位参与者 阅读完整话题

cnBeta全文版 · 2026-06-09 14:35:45+08:00 · tech

6月9日消息,Meta要为自己的AI数据中心建设培养技工。据路透社报道,Meta将投入1.15亿美元,设立名为"美国劳动力学院"(America's Workforce Academy)的免费培训项目,面向数据中心技术岗位培养新人,并承诺毕业生将获得工作机会。 Meta发言人称,该项目将提供数据中心技术员的通用培训。毕业后的岗位不是直接进入Meta,而是在参与Meta数据中心建设的总承包商处担任全职工作。发言人没有说明具体会开放多少岗位、涉及哪些承包商,也没有说明这些岗位是否属于工会岗位。 AI数据中心不只缺芯片,也缺施工人员 这笔1.15亿美元放在Meta的整体投入中不算大。路透社称,Meta已承诺未来三年在美国基础设施和就业方面投入总计6,000亿美元,其中包括建设大型数据中心,为CEO马克·扎克伯格(Mark Zuckerberg)在AI智能体技术上的押注提供算力。 但AI基础设施不是只靠显卡、服务器和电力合同就能落地。数据中心要建起来,还需要铺设线路、安装设备、完成机电和现场施工。美国建造商与承包商协会(Associated Builders and Contractors)表示,预计将在该项目期间培训数千人。 Meta总裁兼副董事长迪娜·鲍威尔·麦考密克(Dina Powell McCormick)称,AI革命带来变化,也带来"历史性机会"。这意味着AI公司正在把一部分基础设施压力,从算力采购扩展到劳动力供给。 保证就业,但不是保证进Meta 这个项目最具吸引力的地方,是"免费培训"和"毕业后有工作机会"。对不想上大学、或需要尽快进入收入稳定岗位的人来说,数据中心建设潮正在创造一批新的蓝领就业通道。 不过按路透社的说法,毕业生将获得工作机会,岗位来自参与Meta数据中心建设的总承包商,而非Meta直接雇佣。Meta也没有披露岗位数量、用工企业名单和是否为工会岗位。这更接近Meta为自己的建设链条提前储备人力,而不是传统意义上的企业校园招聘。 这一区别很重要。对求职者而言,培训是否真能转化为长期职业路径,取决于岗位地点、薪酬、合同稳定性和后续项目是否持续。对Meta而言,保证有人能进场施工,才是AI数据中心扩张不被工地进度拖住的现实前提。 建设期用工密集,长期岗位有限 路透社还提到,数据中心通常会带来短期建设岗位高峰,但永久岗位数量较少。Meta去年在得克萨斯州开工的一座大型数据中心,预计建设高峰期现场工人超过1,800人,但投入运营后约创造100个岗位;另一座位于俄克拉荷马州的数据中心,预计建设高峰期超过1,000个施工岗位,完工后约有100个运营岗位。 这也是此类培训项目面临的公共争议所在。地方政府和社区常常期望数据中心带来长期就业,但真正密集用工的阶段往往集中在建设期。美国劳动力学院能为一批人打开进入技能工种的入口,但它无法把数据中心变成长期大规模雇主。 AI基础设施建设正在把电工、机电、数据中心技术员等岗位重新推到公司战略前台。AI最终要落在服务器、机房、供电和施工现场上,谁能把这些设施建起来,也会成为科技公司竞争的一部分。 查看评论

v2ex · 2026-06-06 19:53:44+08:00 · tech

请教下大佬,最近翻出个历史遗留问题,折腾几天无果,特来求助: 背景:2008 年用常用邮箱(账号 A )注册了国区 Apple ID ; 2009 年苹果自动分配了一个同前缀的 @ mac .com 邮箱给我。 变故:2018 年我想把账号 A 挪去美区用,于是登录国区 ID ,把主邮箱改绑成了一个备用邮箱(账号 B )。 报错: 现在用这个 @ mac .com 登录或找回密码,系统直接报错:“此 Apple 账户无效或不受支持。” 和客服沟通后,对方说隐私政策限制,无法用 @ mac .com 反查。必须提供 2018 年改绑后的“账号 B”才能处理。 时隔多年,我实在想不起当年改绑的账号 B 是哪一个了,可能的邮箱都翻看过了。但我手里有当年账号 A 里保存的所有苹果历史邮件和购买凭证。 请问下,这种“账户无效或不受支持”还有救吗?是被注销了还是冻结了? 既然客服不给反查,有没有什么办法能联系高级顾问,通过提供原始注册邮箱(账号 A )和历史邮件凭证来证明所有权并找回?

v2ex · 2026-06-06 18:53:44+08:00 · tech

请教下大佬,最近翻出个历史遗留问题,折腾几天无果,特来求助: 背景:2008 年用常用邮箱(账号 A )注册了国区 Apple ID ; 2009 年苹果自动分配了一个同前缀的 @ mac .com 邮箱给我。 变故:2018 年我想把账号 A 挪去美区用,于是登录国区 ID ,把主邮箱改绑成了一个备用邮箱(账号 B )。 报错: 现在用这个 @ mac .com 登录或找回密码,系统直接报错:“此 Apple 账户无效或不受支持。” 和客服沟通后,对方说隐私政策限制,无法用 @ mac .com 反查。必须提供 2018 年改绑后的“账号 B”才能处理。 时隔多年,我实在想不起当年改绑的账号 B 是哪一个了,可能的邮箱都翻看过了。但我手里有当年账号 A 里保存的所有苹果历史邮件和购买凭证。 请问下,这种“账户无效或不受支持”还有救吗?是被注销了还是冻结了? 既然客服不给反查,有没有什么办法能联系高级顾问,通过提供原始注册邮箱(账号 A )和历史邮件凭证来证明所有权并找回?

v2ex · 2026-06-06 17:59:52+08:00 · tech

请教下大佬,最近翻出个历史遗留问题,折腾几天无果,特来求助: 背景:2008 年用常用邮箱(账号 A )注册了国区 Apple ID ; 2009 年苹果自动分配了一个同前缀的 @ mac .com 邮箱给我。 变故:2018 年我想把账号 A 挪去美区用,于是登录国区 ID ,把主邮箱改绑成了一个备用邮箱(账号 B )。 报错: 现在用这个 @ mac .com 登录或找回密码,系统直接报错:“此 Apple 账户无效或不受支持。” 和客服沟通后,对方说隐私政策限制,无法用 @ mac .com 反查。必须提供 2018 年改绑后的“账号 B”才能处理。 时隔多年,我实在想不起当年改绑的账号 B 是哪一个了,可能的邮箱都翻看过了。但我手里有当年账号 A 里保存的所有苹果历史邮件和购买凭证。 请问下,这种“账户无效或不受支持”还有救吗?是被注销了还是冻结了? 既然客服不给反查,有没有什么办法能联系高级顾问,通过提供原始注册邮箱(账号 A )和历史邮件凭证来证明所有权并找回?

v2ex · 2026-06-06 17:57:52+08:00 · tech

请教下大佬,最近翻出个历史遗留问题,折腾几天无果,特来求助: 背景:2008 年用常用邮箱(账号 A )注册了国区 Apple ID ; 2009 年苹果自动分配了一个同前缀的 @ mac .com 邮箱给我。 变故:2018 年我想把账号 A 挪去美区用,于是登录国区 ID ,把主邮箱改绑成了一个备用邮箱(账号 B )。 报错: 现在用这个 @ mac .com 登录或找回密码,系统直接报错:“此 Apple 账户无效或不受支持。” 和客服沟通后,对方说隐私政策限制,无法用 @ mac .com 反查。必须提供 2018 年改绑后的“账号 B”才能处理。 时隔多年,我实在想不起当年改绑的账号 B 是哪一个了,可能的邮箱都翻看过了。但我手里有当年账号 A 里保存的所有苹果历史邮件和购买凭证。 请问下,这种“账户无效或不受支持”还有救吗?是被注销了还是冻结了? 既然客服不给反查,有没有什么办法能联系高级顾问,通过提供原始注册邮箱(账号 A )和历史邮件凭证来证明所有权并找回?