![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_3.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_3.png)
花了不少時間,總算把 Netflix 雙字幕作出來了~~~(撒花)
使用方式與之前 3waNetflix V1.8 以前都相同,啟動後
我把原本官方的字幕畫面,複製一份放到分頁 tab 裡的「字幕選擇」空間
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_5.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_5.png)
在字幕選擇可以切換音訊、主要字幕、次要字幕
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_7.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_7.png)
主要字幕就與之前的設定方式一樣
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_9.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_9.png)
第二行的字幕通常大家會用英文吧,所以預設的字體大小跟字距稍微調小調宅些
V1.9 算是滿大的更新,作起來相當累人...
(2022-09-24) V1.9 版:
1、加回 jQuery 3.6.0
2、雙字幕功能
3、第二字幕 UI 設定介面
4、加入字型選擇
5、使用者正在「準備切換下一集」或「選集數」 或 「調影片速度」,停用設定 UI
6、UI 控制區,只有滑鼠進入的高度 70% 切入才有效,不然螢幕太小時,調時間軸也會一直檔到
7、原 3wanetflix 的字幕要插在 video 裡,這樣全螢幕才有作用,現在發現要再 video 外層的 div 才行
8、修正字幕不需要強制大寫:font-variant: small-caps
9、主要字幕、次要字幕可各自設定樣式
10、如果有下一集、工作人員名單、返回瀏覽、略過簡介,要可以點
11、已知問題:
(1). 啟動 3waNetflix V1.9 版後,下方進度條會失蹤,需要用滑鼠滑過下排音量控制才會出現
(2). 當滑鼠進入下排控制區時,字幕功能就會暫停,請往上移開
(3). 已知有些改 1080p 或是部分字幕是「圖片型字幕」出字會異常,之後再研究
然後來寫點開發過程的心痠:
禮拜一主管 Jeffrey 聽說我有在作 Netflix Plugin 可以放大、改字幕顏色的功能,問說能不能加個
雙字幕,這樣方便學英文還是其他語言。自己也是很期待這個功能開發能不能實現~~
初期開發在看 Netflix 一直按 F12 ,從 console 裡面找看看有哪些資料能用,但一直都找不到
與 track、語言有關的資訊,localstorage 也沒有
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664036789_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664036789_1.png)
嘗試在 window 找了許久,沒找到有用的資訊可以幫助雙字幕
然後羽山想嘗試找出網頁裡會呼叫字幕連結的位置,比如點了「英語字幕」會抓到一個 xml 的位置
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664036979_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664036979_1.png)
然後利用 source 攔截,一步一步看,就一直進入 window.a000 的虛空
看不太出來他加密後的邏輯怎麼解算
羽山之前有找到一篇網友提供 Request 加載的 xhr ,是直接改寫 ajax 呼叫方式:
From : https://stackoverflow.com/questions/25335648/how-to-intercept-all-ajax-requests-made-by-different-js-libraries
(function(open) {
XMLHttpRequest.prototype.open = function(method, url, async, user, pass) {
console.log(url)
this.addEventListener("readystatechange", function() {
console.log(this.readyState); // this one I changed
}, false);
open.call(this, method, url, async, user, pass);
};
})(XMLHttpRequest.prototype.open);
如此一來,任何 ajax 呼叫後,都可以從中提取曾呼叫的 url 網址~~~
或是重新註冊 JSON.parse ,把 global JSON.parse 改寫成一樣會作 json decode 但可以把值寫到自己想要的變數,測錄 json 包。
這二個作法可能在 chrome extension V2 比較有機會達成,自從升 V3 以後,直接變成 background service_worker,初期光 access html dom 就有點中混亂,得讓使用者自己 chrome.action.onClicked
這個作法是參考另一個 NflxMultiSubs 開源專案裡的一段 code
// Hook JSON.parse() and attempt to intercept the manifest
// For cadmium-playercore-6.0022.710.042.js and later
const hookJsonParseAndAddCallback = function(_window) {
const _parse = JSON.parse;
_window.JSON.parse = (...args) => {
const result = _parse.call(JSON, ...args);
if (result && result.result && result.result.movieId) {
const movieId = result.result.movieId
console.log(`Intercepted manifest ${movieId}`);
window.__NflxMultiSubs.updateManifest(result.result);
}
return result;
};
};
hookJsonParseAndAddCallback(window);
寫的真的很猛~~學習到這個技術真是痛快啊XD,以前怎麼都沒想這麼作...♥
如果 V3 可以用就好了 :( 權限不知道要怎麼加才辦的到...
熬夜試了一、二個晚上沒成功,就繼續照自己原來的土炮繼續作 XD
一個大膽的想法,就是如果一直按「繁體中文、英文」,反覆一直按呢...
沒錯,按完後可以拿到「繁中、英文」而且只有第一次他會xhr載字幕,稍微頓一下
之後切換都相當順暢
從這個角度切入後,要克服的就是不能讓「選字幕的位置不見」,Netflix 有個奇怪的設計
他不需要的東西,直接從畫面 remove 掉,不是隱藏呦,直接 remove...
比如你在選「某一集」的選單開啟,這時他的「時間軸」看似隱藏,實際也是 remove 掉
整個 dom 元件不給你操作,笑死...
所以土炮仔羽山的作法,就是讓一個屁孩,一直狂點右下角的字幕,只要一直點就不會消失...
然後再一直反覆點你要的字幕(繁中、英文),點完再收集到記憶體位置,然後再用自己的字體樣式
重新拚裝後,插到網頁裡的畫面
測試的範例程式:
這段程式是我最初測雙字幕寫的
前面那堆 js 就 jQuery-3.6.0.min.js
流程:
1、載入 jQuery
2、隱藏原本的字幕(因為要用雙字幕合併後的字幕)
3、隱藏右下角字幕選單(註解掉,沒執行,這樣大家比較明白)
4、跑一個 Interval ,裡面再跑三組 timeout
(1) 一直按右下角那個「字幕」的按鈕,讓選單出現
(2) 按「繁體中文」,等100ms
(3) 取得繁體中文字的內容,再按「英文」,再等100ms
(4) 將「取得的中、英文」合併成一組文字,如果這組跟之前一樣,就不顯示了
(5) 在 body 插一個浮動 div[reqc='myword'] ,然後把字的樣式設一設就顯示
(話說 Netflix 的工程師好像很愛用 屬性 data-uia,而羽山自己很愛用 reqc)
這個測試看來是有成功了~那麼可以土炮達成就成功了一半~~~(大心~撒花)
接下來就偷工簡料,重新引入 jquery ,之前自己寫 jquery-light 還是沒辦法把事件寫的那麼完美
重新把肥肥的 jquery-3.6.0.min.js 塞入程式的最開始,因為不知道怎麼用 js 檔引入,所以就放
在程式碼的最前面...(笑)
塞入整包的 jquery 真的事半工備...
可惜短命的 jquery-light (By 3wa FeatherMountain...),換成正牌 jquery 幾乎沒改啥 Code 就直上,當初努力想實作還是很有價值~
短命的 jquery-light 也是從 v0.5~v1.8 很努力工作了
接下來講到哪了~
對了~講到拷貝字幕 UI
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_6.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_6.png)
拷貝後的字幕 UI 可以省下很多自己刻的時間
但拷貝完後的字幕選單,要確保這是單向使用,原來的官方選單就隱藏放到 z-index:-2 藏起來
然後在點擊時,先把「勾勾」的SVG 樣式、點到的亮字、暗字 class 都記下來,當使用者在點擊時
就註冊新的勾勾,註冊亮、暗字,然後把使用者點擊「主要字幕、次要字幕」寫到 localstorage、global window 裡。
這裡羽山用 my_netflix_sub1、my_netflix_sub2
神奇的點雙字幕小人就會一直幫你點這二個字幕,點個不停。
有些情況是不能點的,剛才提到如果使用者想使用時間軸、換下一集、選集、全螢幕、調整影片速度…
當滑鼠觸及這些東西,就不能讓小人再點擊字幕按鈕、字幕選擇
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664039097_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664039097_1.png)
如程式碼 1295 行附近,就是在指這個情境
當一切都很美好時,發現全螢幕一點下去,又變成地獄了…
所以改寫 netflix 的全螢幕按鈕
新的全螢幕寫法參考:https://usefulangle.com/post/12/javascript-going-fullscreen-is-rare
這寫的還真是符合我需要的功能,直接把這段拿來用,然後全螢幕整個 body 就接近90%成就達成^_^~
目前美中不足就是因為小人一直在點字幕,所以 timeline 時間軸會很不好按
於是把整個下排控制 bar 作了一個 body onmousemove 的區塊,滑鼠一進去,小人就不點了
此時滑鼠只要經過原本下排任意一個功能,時間軸就會顯示出來
也因為小人不幫你點,所以滑鼠在下排控制區,就多了一行文字提示...
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664039461_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664039461_1.png)
滑鼠在下方控制區時,雙字幕將無法正常使用
因為小人沒在點了齁
總之還有一個大魔王要克服,就是像「2077 電馭叛客:邊緣行者」裡的「日文字幕」
他是使用「圖片型」的字幕~在舊的 V1.8 我有實作可以調整大小、高度,但樣式都無法調整
在這個版本我目前爆肝有點嚴重,最近都二、三點才睡,所以完全沒修他...
選了圖片型的日文字幕,目前就會變成這樣
或是使用者安裝了嘻花的 1080p extension
老實說我不知道那個 1080p 到底畫質有沒有比較好,但載入後都是抓圖片型的字幕,相當奇妙
以上大概就是我目前 V1.9 Beta 的一些心得
2022-09-26 補充:
昨晚在奮戰圖片型的字幕,$("svg image") 的 href,值如:
blob:http://www.netflix.com/..........................................
這個用法經過一連串查找相關的資料,最接近的使用方法是:
URL.createObjectURL(blob);
但 blob:URL 這種 data urls 是上面那行執行完的成果
且他在畫入 image 元件後,應該馬上就又執行 URL.RevokeObjectURL 把顯示後的結果回收
土炮的字幕來回切換的過程,就無法延續使用 blob 的內容,就算用 jquery clone obj 也
無法正確的把 svg image 複製出來在另建的空間裡呈現
思來想去到凌晨四點還睡不著:( 早上八點多忽然驚醒,眼看要遲到,不如就請特休一小時休息好好準備上班,就在請完假後,腦中忽然出現一個想法~~
「background service 到底能不能 inject 啊…就算他有嚴格的 meta Content-Security-Policy」
但是否就作到滴水不漏!?
這個想法迫使我再一次挑戰 inject script
想法很簡單,利用 <img onerror=""> 注入 script 看看呢!?
然後要注到他的 window 也能覆蓋齁~如果注的下去,那 extension V2 的寫法,就可以整個搬來 V3 了
所以先假設...
<img onerror="alert('test');" src="//3wa.tw/xxxx">
隨便加載一張失敗的圖,載入後,居然有跳出 alert 呢~~~
那麼...
<img onerror="URL.createObjectURL = null;"> 看看會不會整個日文字幕都壞掉?
咦,失敗了
那麼
<img onerror="window.URL.createObjectURL = null;"> 呢!?
靠B,成功了~~~笑死
原來還可以這樣硬幹一張假圖,onerror 去把整個網站的 js 注成我插的啊....囧>
這樣就有趣了,我只要再註冊一次他的 URL.createObjectURL、JSON.parse 就什麼事都能作了啊
之前這麼土炮還真辛苦 XD
所以你各位裝來路不明的 extension 最好看仔細他們寫了什麼鬼東西啊...
為了讓「流過的圖片blob」可以被攔劫,所以我作了一點點擴充,我把 blob 的內容用
FileReader 開啟,然後在 body 放一個可以藏 base64 的 div 作為資料交換空間
var reader = new FileReader(); // 加載 FileReader
reader.onload = function() {
var dom = document.querySelectorAll("div[reqc='my_netflix_imageSubsB64']");
if(dom.length==0) return;
var dataUrl = reader.result;
var b64 = dataUrl;
var m = dom[0].innerHTML.split('|||3WA_BR|||');
//字幕|||3WA|||時間
m.push(b64+"|||3WA|||"+new Date().getTime());
m = m.slice(-10); /* keep last 10 */
dom[0].innerHTML = m.join('|||3WA_BR|||');
};
這個 div html 的內容會保留最後抓到的十張字幕影像
內容為
base64|||3WA|||當時的時間
|||3WA_BR||| --> 這是斷行
base64|||3WA|||當時的時間
|||3WA_BR||| --> 這是斷行
大概是這樣,出字幕的時候,大概只需要針對還持續更新的字幕(大概0.5秒內吧,最多二組不同內容的字幕)
這樣應該就可以把圖片的字幕作出來,擺在我想放的空間裡
日文的圖片字幕常常滿多特別效果,之後再考慮如果屬特殊位置的字,再作調整
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_5.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_5.png)
總算作出 V2.0 版了,這次 UI 調整後較為緊緻一些
然後原來滑鼠移入中間就會出現,改成要點選右下原來的字幕按鈕
由於重新定義了 URL.createObjectURL 昨晚測下來,發現如果回 Netflix 首頁,再重新點回影片播放頁
都會出現 Netflix 錯誤異常,需要重整瀏覽器,把新加的定義註解掉後,就不會當機
所以在 appClass.method 加入 fixOrinURL:
狀況一:
如果畫面不是播放頁時,且發現 URL.createObjectURL 有改寫,就還原原版
狀況二:
如果使用者按「下一集、切換其他集」這裡畫面仍是播放頁,但仍會當機,解決方法就是把這二個按鈕,再 bind click,按下去就還原原版
經過這一波操作就不會 netflix crash
V2.0 作了以下修正調整:
(2022-09-27) V2.0 版:
1、使用注意事項獨立一個 tab 分頁
2、圖片型字幕閃耀問題修正
3、當畫面靜置一段時間,會發生無法回上頁、右上的問題反應也無法點選
4、調整 UI 時,有時會失效
5、無人說話時,字幕退場的時間不精準
6、如果使用者在調整時間軸,延長消失時間(6秒)
7、全螢幕時,滑鼠沒移動一段時間後要自動隱藏(6秒)
8、縮小設定畫面可以觸發顯示的範圍
9、調整畫面很容易滑鼠移動就消失,將 mouseout 改成 mouseleave 後較為正常
10、UI 控制區,只有滑鼠進入的高度 36% 切入才有效,不然螢幕太小時,調時間軸也會一直檔到
11、UI 控制區,改成點右下角語言,並加入嘻花效果
12、英文字幕,二行字會黏在一起
13、UI 控制區畫面改緊緻,滑塊加大
14、播放結束後,按下一集異常
15、直接按下一集的三角按鈕
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_1.png)
(V2.0 畫面) 字幕語言選單
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_2.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_2.png)
(V2.0 畫面) 主要字幕
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_3.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_3.png)
(V2.0 畫面) 次要字幕
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_4.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664241872_4.png)
(V2.0 畫面) 注意事項獨立收在一起
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_11.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1664034045_11.png)
有興趣一起研究的同好也歡迎加入
真是美好的一天,能作出來真的很開心~~~
2022-09-27 09:41 羽山筆
(2022-09-29) V2.1 版:
1、直接按下一集的三角按鈕,會發生異常
2、全螢幕時,立刻隱藏下方控制區
3、影片暫停時,暫停取新字幕
4、按「空白鍵」可以控制「播放、停止」
5、按「o 或 O」(Open) 可以「喚出字幕選單」
6、3WA Icon 、x_close.png 改成 base64 png
7、滑鼠移出設定 UI 視窗,等 1 秒再隱藏,重新滑入就停止計時,不然太容易不見
(2022-10-05) V2.2 版:
1、全螢幕回上一頁,要停止全螢幕
2、滑鼠進入下方 Control 區,時間軸需要顯示,不用透過滑過聲音鈕(總算找到解法了~撒花)
3、如果第二字幕有字幕檔,直接讀出字幕檔顯示
4、安裝後 3waNetflix 後,自動啟動,不用手點了
5、(圖片型字幕) 當滑鼠進入下方控制區,包含進度條,雙字幕將無法正常使用,請往上移開
6、主字幕可正常依雙行字顯示
7、音訊切換,造成主字幕勾勾跑版
(2022-10-08) V2.3 版:
1、停用自動顯示進度條(太容易造成影片停住)
2、影片標題下移、加一點透明度
3、當切換音訊,再切回原來的音訊,沒有正常執行
(2022-10-19) V2.4 版:
1、76、寬螢幕如果遇到超長字幕,偶爾會透在底下(如:迷霧:第6集 剩 1:30 左右)
2、77、當影片播放進入最後 1%,停止翻譯字幕
3、78、當影片暫停時,停止翻譯字幕
4、79、全螢幕按鈕應避免 Focus ,不然空白鍵會觸發
5、80、熱鍵 → 下10秒
6、81、熱鍵 ← 上10秒
7、82、熱鍵 M 消音、有聲
8、83、熱鍵 F 全螢幕
9、83、熱鍵 S 略過片頭
10、84、熱鍵 N 下一集
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291377_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291377_1.png)
V2.4 版主要是把一些常用的功能作成鍵盤熱鍵
同時也把說明的部分加強
(2022-11-05) V2.5 版:
1、85、熱鍵 S 發現 bug,有時按下後,會回到片頭
2、86、使用者可自定自動跳過片頭
3、87、使用者可自定自動跳至下一集
4、88、電影,在片尾時「返回瀏覽」,如果是全螢幕,離開全螢幕
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291377_2.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291377_2.png)
V2.5 版,加入自動功能,可以自動跳過片頭、自動跳下一集
(2022-11-10) V2.6 版:
1、89、清字幕 localStorage 不小心清到字幕設定
(2022-11-10) V2.7 版:
1、90、六人行「英文 (CC)」 字幕,有全大寫的問題
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291377_3.jpg](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291377_3.jpg)
V2.7 有網友許願,想看六人行時,英文字幕不要全大寫
這部分只針對「英文 (CC)」字幕處理,所有字轉成小寫,用 . 裁切英文句子,依每一句字首首字符合[a-z]
就轉成大寫,另外若有遇到 “.....“ 這種六人行對話很常見的強調區,裡面全改大寫。
詳見:appClass.method.fix_sentence_first_letter_upper_case
(2022-11-10) V2.8 版:
1、91、修正自動下一集會 crash 的問題
2、92、自動跳過片頭,才不會發生出現跳過片頭,使用者點了進度條或切頁,數量變 0 的問題
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291717_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670291717_1.png)
羽山為了取圖片型字幕,重新包裝後的「URL.createObjectURL」,經過包裝後的函式,當回到 Netflix 主頁就會發生抱歉,服務中斷,之前一直沒明白失敗的原因~~
後來的作法就是在每一個有機會回到首頁的按鈕,再把原本的「URL.createObjectURL」換回原生的
但有網友表示,自動播放下一集,仍會發生服務中斷,因為 Netflix 內鍵的自動下一集是靠程式觸發,不屬
於任何按鈕
羽山的個人設定,很早之前就取消這二個預設勾選的設定,所以一直沒發現這個 crash 的原因
於是再次認真研究如何安全的包裝「URL.createObjectURL」,反覆的在播放頁註冊 URL.createObjectURL,某次在回到首頁的時候,看到出現 meta policy 的錯誤提示 (可惜沒有截圖)
大概就是 blob content not allow
![//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670292566_1.png](//3wa.tw/photo/small.php?w_size=1280&compassion=95&file_name=users/shadow/1670292566_1.png)
netflix 的畫面設計的很有意思,所有的換頁似乎都是靠 ajax 在重讀資料,沒有作到所謂的更換連結
所以改過的 URL.createObjectURL 回到首頁,如果函式無法正常使用就會出現錯誤視窗
經過一連串測試,我在 361 行包了 try catch ,原本要讀出「圖片型字幕」的部分,在首頁如果發生問題,這段就 pass 掉,另外原本 URL.createObjectURL 會 return 值,在原來的 my_netflix_URLCREATEOBJECTURL 就 return 值,再次嘗試會不會 crash...
不過私心覺得還是不要勾 netflix 內鍵的自動播下一集,自製的比較好用 XD
看來應該是修好了,V2.8 版的自動下一集總算不會再 crash 了 (大心,撒花)
希望就此可以完全根除 netflix 服務中斷的問題
下一版該認真面對下方進度條了嗎...