跳至主要内容

用本地模型跑一整套字幕轉錄與翻譯流程

· 閱讀時間約 3 分鐘

前言

我很偶爾會有「外文影片 → 中文字幕」的需求。

這通常分成兩塊執行:

  1. 音檔 → 原文逐字稿
  2. 原文逐字稿 → 翻譯成中文

以前怎麼做

  1. 轉錄這塊以前都用 faster-whisper,在以前 LLM 還不發達的年代,我都只會用幾個預設參數跑,能出字幕就好。(甚至有自己切音檔 → 依序翻譯 → 再合併的鬼操作)

  2. 轉錄完成後,我都直接把 SRT 丟到 translatesubtitles.co 套 Google 翻譯,雖然一秒就翻完,但翻得不精準、也完全不吃上下文,一句一句各翻各的,日文的效果還特別差。

現在怎麼做

  1. 最近剛好又有這個需求,想到 LLM 可以幫忙,請 LLM 幫我看了一下,才知道原來有一堆實用參數可以調,像是逐字時間戳、自動換溫度重試、不讓前段錯誤污染後段,調好之後轉錄結果穩定很多。

  2. 以前連 ChatGPT3.5 都還沒出,現在則是本地 LLM 就能做翻譯了。重點是小模型提示詞要寫好、要分批、要有重試機制,這幾件事設計好,一整套流程跑起來非常順手,翻譯品質也遠勝 Google 翻譯。

痛點:LLM 如何做翻譯?

因為 LLM 翻譯,特別是小模型,最大的麻煩是「對齊」,模型常會偷偷合併、拆分或漏句,譯文就對不回時間軸了。

這邊 Claude 設計的解法是:給每句一個 [編號]

  • 系統提示裡把規則講死(編號數量、順序必須一模一樣,不可合併拆分漏句)。
  • 用一次送一批帶編號的句子當輸入,再放幾句上下文當參考;輸出的部分必須要用指定的格式回傳,對得上才過。
  • 那輸出對不上的情況呢?就做重試機制,最多可以重試 N 次,若還是不行就先繼續下一批,這批先保留原文。
  • 每次成功的進度先寫進 JSON 檔案,下次可以直接做「斷點續傳」,隨時中斷也不會白做工。

心得

  • 這樣一來,從影片到中文字幕,全程在本機完成,不用上傳、不用等線上服務,不會被審查,而且成功率極高。
  • 這套流程我覺得還算滿意,可以給 80 分,夠用就好了,如果有更好的方法也可以跟我說。
  • 花幾個小時來回跟 Claude 嘴砲,設計流程、修正流程還滿有趣的。(感謝老闆的 Token)

筆記

  1. Whisper:影音轉錄字幕檔
  2. Ollama:用本地 LLM 翻譯字幕

批次下載 YouTube 縮圖並調整尺寸

· 閱讀時間約 1 分鐘

前言

今天在更新網站上「Tiny Desk Concerts」的欄位,突然想到沒有把下載步驟記下來,在這邊補一下。

第一步:用 yt-dlp 抓整個播放清單的縮圖

yt-dlp ^
--skip-download ^
--write-thumbnail ^
--convert-thumbnails jpg ^
-o "%(title)s.%(ext)s" ^
"{播放清單/影片網址}"

第二步:用 ImageMagick 統一縮放

magick mogrify -resize 480x270! *.jpg

mogrify 會直接覆寫原檔,省下另開資料夾的功夫。

尺寸後面的 ! 代表忽略原始長寬比,強制拉伸到指定尺寸。

沒加的話,ImageMagick 會把 480x270 當成最大邊界框,在框內保持原始比例縮放。

筆記

大小寫問題讓網站連結失效

· 閱讀時間約 3 分鐘

發現問題

今天偶然發現之前寫的多益資源整理,這篇文章連結點下去會直接跳回首頁。

奇怪,網址明明還停在 /blog/toeic-resources-2026/,內容卻是首頁。

但我在本地跑沒有問題啊!?

想說是不是 Cloudflare Pages 的問題,但往回前翻好幾版都有這個問題。

找出問題

我先去看了 sitemap、RSS、文章列表頁,所有指向這篇的連結都是小寫 /toeic-resources-2026/,沒有問題。

也跑去看了 public/blog/ 底下的資料夾,確實有 toeic-resources-2026/index.html,檔案在啊。

那為什麼 Cloudflare 找不到?

我請 AI 幫我比對 git 跟磁碟上的檔名,這時候真相浮出水面:

GIT:  public/blog/TOEIC-resources-2026/index.html
DISK: public/blog/toeic-resources-2026/index.html

兩邊的大小寫不一樣。

為什麼

雖然我想不起來了,不過最有可能的情況應該是,我手動把資料夾從大寫的 TOEIC-resources-2026 改成小寫的 toeic-resources-2026,因為其他文章 slug 都是小寫,看起來比較一致。

當時改完,本機看一切正常,就 commit、push 上去了,根本沒注意到 git 其實沒抓到這次改名。

事後才知道,這是三個東西交織的結果:

  • Windows 檔案系統大小寫不敏感,Foofoo 是同一個資料夾。
  • Git on Windows 預設 core.ignorecase=true,會配合 Windows 的行為,這次的重新命名根本沒被當成一次 diff。
  • Cloudflare Pages 跑在 Linux 上,大小寫嚴格區分,/toeic-resources-2026//TOEIC-resources-2026/ 對它來說是兩個完全不同的網址。

於是,本機看起來沒事,repo 裡其實還是大寫,部署上去就只認大寫,小寫的 URL 全部 404。

解決問題

要讓 git「真的」承認這次改名,得從索引裡先把舊的拿掉,再加回新的:

git rm -r --cached public/blog/TOEIC-resources-2026
git add public/blog/toeic-resources-2026
git commit -m "Fix case: TOEIC-resources-2026 → toeic-resources-2026"
git push

--cached 只動 git 索引,不會碰到磁碟上的實體檔案。

未來怎麼防範

可以考慮把 git 設成大小寫敏感:

git config core.ignorecase false

之後任何資料夾或檔名只要改了大小寫,git status 就會老老實實顯示「舊名稱被刪除 + 新名稱新增」,不會再無聲無息地漏掉。

再順手跑了一下 git status 全域掃描,確認其他歷史檔案沒有同樣的漏網之魚。

中島美雪《時代》

· 閱讀時間約 4 分鐘

《時代》

中島美雪的代表作《時代》,是在 1975 年那一年,她連續闖過兩個比賽的一首歌。

1975 年 10 月:Popcon

10 月 12 日,第 10 屆 Popcon(ポピュラーソングコンテスト)在靜岡縣つま恋舉辦。

那一屆收到了 12,000 首 應募曲,中島美雪的〈時代〉拿下了最高獎 グランプリ。也因為這個獎,她得到了代表日本參加 11 月世界歌謠祭的資格。

1975 年 11 月:世界歌謠祭

11 月 16 日,「第 6 屆世界歌謠祭」在日本武道館舉辦。〈時代〉再次拿下了最大獎 Grand Prix(グランプリ)。

那一屆的主持人,是日本傳奇歌手坂本九,以及當時已經紅遍亞洲的翁倩玉

下面這段珍貴的影片中,約 1 分 56 秒處,收錄了當年在世界歌謠祭的影像,你可以清楚地聽到坂本九與翁倩玉主持的聲音。


坂本九:「Entry number 30, 日本, 中島みゆき, "時代".」

翁倩玉:「Entry number 30, Japan, "Time Goes Around".」

伴奏的故事

〈時代〉在舞台上原本是有管弦樂團伴奏的版本。但拿下 Grand Prix 之後的 得獎者加演(安可),中島美雪走上台前,對著指揮耳語了幾句。接著,整個樂團安靜下來,她抱著吉他,只用一把吉他自彈自唱了一遍〈時代〉。

這個決定來自於她的伯樂、YAMAHA 音樂振興會的理事長 川上源一 對她說過的一段話:

「あなたはすごい詞を書く。将来、詞で勝負するようなアーティストに育って欲しい。できれば大音量をバックにするよりも、ギター一本で歌った方が、あなたの詞が人々に伝わる」

「妳寫的詞非常出色。希望將來你能成長為一位以歌詞實力取勝的藝術家。如果可以的話,與其背負著巨大的音量(伴奏),不如只用一把吉他自彈自唱,你的歌詞反而更能傳達進人們的心裡。」(AI 翻譯)

從那之後,中島美雪在每一張專輯的工作人員名單裡,都會寫上一行 「DAD 川上源一」,以此致敬這位恩人。

關於父親

中島美雪在出道單曲〈薊花姑娘的搖籃曲〉發行前一週(1975 年 9 月 16 日),父親就因腦溢血倒下、昏迷不醒。

10 月的 Popcon、11 月的世界歌謠祭,她其實都是從父親昏迷的病房趕到會場上台的。父親後來於 1976 年 1 月離世,始終沒能聽到女兒奪冠的消息。

世界歌謠祭頒給她的 5,000 美元獎金,後來拿去當作父親的葬儀費用。

1993 年的彩蛋

中島美雪在 1993 年重新錄製了《時代》,歌曲的開頭,她取樣了在世界歌謠祭裡面,主持人坂本九翁倩玉的介紹詞,以及歌曲開頭的一小段演唱。

翁倩玉:「Entry number 30, Japan, compose and sung by Miyuki Nakajima, the title of the song: Time Goes Around.」

(這聲音也太美了吧!!)

備註

我在「這篇貼文」中提到我前陣子跑去看了《陽光女子合唱團》,才發現其實我以前經常聽到這位國民阿嬤翁倩玉的聲音。

至於坂本九的話,我最喜歡的歌曲是《見上げてごらん夜の星を》。

參考資料

收集部落格 RSS 網址列表

· 閱讀時間約 2 分鐘

最近「部落格問題挑戰」這個問答挑戰突然很多人響應。

想說可以收集一下大家的答案,就像 Ava 的「bear blog question challenge」一樣!

這樣的話,我就需要收集一下大家的 RSS Feed 了,在這邊記錄一下做法。

雖然都是 AI 在做。


目標

BlogBlog 同樂會 頁面上的所有部落格整理成一份可匯入閱讀器的 OPML 清單

1. 取得部落格網址列表

  1. 在 BlogBlog 同樂會 頁面爬取所有連結。
  2. 去除重複網址,整理並輸出成 txt 檔案。

2. 將網址列表轉成 RSS Feed

  1. 先比對既有的 OPML(原本就訂閱過的就不用找了)
  2. 用平台規則猜 RSS 位置,用 cURL 去試試看,平台型部落格通常都會直接成功。
  3. 抓首頁 HTML,找 link rel="alternate",有的話通常就直接是 RSS 網址了。
  4. 測試常見路徑(/feed/rss/index.xml/atom.xml 等等)
  5. 輸出成 rss_feeds.csv:每個站的 RSS、來源、狀態

這時候大概能收集到九成的 RSS Feed 了,剩下的就手動稍微找一下,很快就處理完了!

最後輸出成 url.opml.xml,然後在我的 FreshRSS 閱讀器開一個帳號,把這份清單匯入進去。

之後只要上去搜尋關鍵字「部落格問題挑戰」就可以了!

e89295

· 閱讀時間約 1 分鐘

TIL,《我的部落格》的網站名稱「e89295」,是用三個十六進位的 UTF-8 位元組來表示的:0xE80x920x95

new TextDecoder().decode(new Uint8Array([0xE8, 0x92, 0x95]))

如何用 Telegram 傳送通知給自己

· 閱讀時間約 2 分鐘

前言

前幾天看到 Eddie 在這篇文章中提到,戒了 IG 後「會想一直開自己網站刷留言,看看有沒有新留言!」。

其實我的這套「留言系統」有接「通知功能」耶!只要有人留言,就會觸發 Telegram 的機器人通知我,這樣我就能快快審核,不用定時一直上去檢查。

不過,更簡單的方法應該是:Google Apps Script 內建直接用 Gmail 發信,這樣還能順便備份留言,一舉兩得,簡單又好用!(但我還沒試過,講得我自己都想用了)

正文

有時候會希望程式跑完某件事之後,自動發個通知給自己,像是排程結束、伺服器異常、或是有人填了表單之類的。

這件事其實用 Telegram 來做超簡單,只要申請一個 BOT、拿到 Chat ID,然後用 POST 打一下 Telegram 的 API 就搞定了!

BTW,其實我早期一直都是用 Line Notify 來做通知,但是 Line 又複雜又難用,而且 2025 年 Notify 功能就收掉了,於是就改成用 Telegram 來做通知了。

筆記

I'm Marcus 的閱讀軌跡(推薦系統)

· 閱讀時間約 2 分鐘

今天看到 I'm Marcus 的文章:「来玩玩新开发的小游戏吧」。

Marcus 在自己的部落格實作了一套基於「閱讀軌跡」的文章推薦系統,這個設計還滿有意思的。

我觀察到的一些東西:

  1. 文章向量壓縮到 64 維,整份資料不到 200KB,載入和計算速度都很快。
  2. 使用者記錄存在瀏覽器的 Local Storage,完全不需要後端,隱私性高又即時。
  3. 文章不僅能標記「喜歡」,還能標記「不喜歡」,系統會同時考慮兩種訊號。
  4. 根據「已反饋文章」計算出使用者向量,並對「未反饋文章」計算相似度,決定推薦哪篇文章,也不會重複推薦。
  5. 每次根據當下的狀態計算推薦,並且記錄下來,形成一條固定的閱讀軌跡。

我推測他的運作原理大概是:

  1. 使用者向量 = AVG(喜歡文章向量) - AVG(不喜歡文章向量)
  2. 計算所有的 Cosine Similarity(使用者向量, 未反饋文章)
  3. 取 Top 1 作為推薦

幾個吹毛求疵的小缺點:

  • 只有推薦一篇文章的話,我自己會覺得有點「被牽著走」的感覺,選擇有點太少了。(不過這樣才是「軌跡」,所以也不是缺點,只是一種取捨)
  • 按「換點口味」會被視為負反饋,但這不一定代表我對該主題不感興趣,可能只是對該文章不感興趣而已。
  • 要讓使用者評分實在是有點難度,但這確實是比較尊重使用者的做法。(通常會用隱性一點的特徵)

用 FFMPEG 製作 Nightcore 風格音樂

· 閱讀時間約 1 分鐘

今天跟 GPT 學到了用 FFMPEG 製作 Nightcore 風格音樂的方法。

Nightcore 的核心特徵是「音調變高、速度變快」,聽起來像花栗鼠在唱歌的那種感覺。

指令

ffmpeg -i input.mp3 -af "asetrate=44100*1.35,aresample=44100" output.mp3
  • asetrate=44100*1.35:改變音訊的播放速率,將採樣率強制改為原來的 1.35 倍,音調與速度都會同步提高。

  • aresample=44100:將採樣率重採樣回標準的 44100Hz,確保檔案在所有設備上都能正常播放。

微調速度

  • atempo=1.05:純速度濾波器,不影響音調,用來微調最終節奏。

例如可以這樣搭配:

ffmpeg -i input.mp3 -af "asetrate=44100*1.3,aresample=44100,atempo=1.05" output.mp3