星期三, 12月 08, 2010

下載並轉換 Youtube 的 annotation 至 SRT 格式

很久沒寫網誌了,尤其是英文版的。基本上沒有太多太值得寫文章紀錄的事情,而且我實在太懶了,有些本來想寫的,拖太久以後也就算了。所以現在比較常在 Google Buzz 上寫簡單的紀錄就算了。

廢話說完,進入正題。Youtube 上越來越多人不用他的 caption (字幕)功能來加字幕,反而喜歡用 annotation (浮動註釋)功能來做。網路上其實已經有很多線上或離線工具可以用來下載 Youtube 影片或字幕的工具,像是 get_flash_videos、clive、youtube-dl、Google2SRT、Youtube Subtitle Ripper等等,但是對於如何下載並轉換 annotation 的資訊則很少見。不過今天我找到解決方案了。


首先,我從這篇文章的使用者評論中,知道了怎樣下載 annotation。我也寫了個簡單的 bash script 用 wget 來下載 caption 和 annotation,不過那個 script 實在是太簡單了,所以就不紀錄了。下載回來的 annotation 是 XML 格式的,所以接下來的問題就是如何轉換成一般字幕格式。

現在大部分的播放器都支援許多純文字格式字幕,而轉換的方法在 Google2SRT 的程式碼中應該可以找到,不過我還是自己寫了個 bash script 來把 annotation 由 XML 格式轉換到最簡單的 SRT 字幕格式。

我寫的這個 bash script 稱為 ann2srt,使用 XMLStarlet 來解析 XML。除此之外,其他就只有用到 bash 內建指令,以及一些 coreutils 中的工具,像是 cuttr。由於 XML 格式的 annotations 並沒有照時間順序存檔,所以目前轉換出來的 SRT 字幕自然也沒有照時間順序排列,因此可能在某些播放器上會有相容性的問題。雖然加上排序的功能並不是很難,但是因為 mplayer 顯然可以正確處理亂序的 SRT 字幕,所以就先這樣吧!ann2srt 的程式碼如下:


#!/bin/bash
#
# Convert the youtube annotation into SRT subtitle
#
# By Shang-Feng Yang <storm_dot_sfyang_at_gmail_dot_com>
# Version: 0.1
# License: GPL v3

function usage() {
echo -e "Usage:\n"
echo -e "\t$(basename $0) ANNOTATION_FILE\n"
}

function parseXML() {
cat ${ANN} |xmlstarlet sel -t -m 'document/annotations/annotation' -v 'TEXT' -o ',' -m 'segment/movingRegion/rectRegion' -v '@t' -o ',' -b -n
}

function reformatTime() {
H=$(echo $1 |cut -d ':' -f 1)
M=$(echo $1 |cut -d ':' -f 2)
S=$(echo $1 |cut -d ':' -f 3)
printf '%02d:%02d:%02.3f' ${H} ${M} ${S} |tr '.' ','
}

ANN=$1
SRT=$(basename ${ANN} .xml).srt
IFS=$'\n'
I=0

[ -f ${ANN} ] || { usage; exit 1; }
[ -f ${SRT} ] && rm ${SRT}

for LINE in $(parseXML); do
(( I++ ))
C=$(echo ${LINE} |cut -d ',' -f 1)
B=$(echo ${LINE} |cut -d ',' -f 2)
E=$(echo ${LINE} |cut -d ',' -f 3)
echo -e "${I}\n$(reformatTime ${B}) --> $(reformatTime ${E})\n${C}\n" >> ${SRT}
done


mplayer 的使用者請注意:播放時請使用 -ass 選項開啟 SSA/ASS 支援。由於 annotation 的特性所至,在同一時段可能會有不只一個 annotation 顯示在畫面上,而 mplayer 內建的 SRT 解析器遇到這種狀況時會只顯示其中一個,但使用 -ass 的話,所有時段重疊的 annotation 都會顯示出來。

SRT 是相當簡單的字幕格式,不支援任何特效,所以 annotation 的位置及顏色等資訊無法也一併轉換。如果我接下來有改版的話,大概會改成轉換成 SSA/ASS 格式吧...

繼續閱讀全文