├── .github
└── CODEOWNERS
├── .gitignore
├── README.md
├── nico_downloader
├── LICENSE
├── dic_scripts.js
├── dist
│ ├── ffmpeg-core.wasm
│ ├── ffmpeg-core2.js
│ └── utils.js
├── func
│ ├── ndl.js
│ └── nicojson.js
├── icon_128.png
├── icon_16.png
├── icon_48.png
├── manifest.json
├── nicovideodownloader_scripts.js
├── options.html
├── options.js
└── options_menu.js
└── tool
├── actionTrackId_make.js
├── api.nico
├── newhls_encode.js
├── old.js
└── options.html
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # レビュアーに指定
2 | * @masteralice304
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | test
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # nico downloader
2 |
3 | nico downloader:ニコニコ用のシンプルなChrome拡張
4 |
5 | **Chrome Webストアで公開されています!**
6 |
7 | **https://chromewebstore.google.com/detail/nico-downloader/dncjcadpoakefjpnabimpalenliehbig**
8 |
9 | ---
10 |
11 | - [nico downloader](#nico-downloader)
12 | - [コンセプト](#コンセプト)
13 | - [おことわりと怒りの表明](#おことわりと怒りの表明)
14 | - [要件](#要件)
15 | - [初期設定](#初期設定)
16 | - [使用方法](#使用方法)
17 | - [しくみ](#しくみ)
18 | - [QandAや要望](#qandaや要望)
19 | - [非常に雑なリリースノート](#非常に雑なリリースノート)
20 |
21 |
22 | ## コンセプト
23 | - 動画ページでの保存ボタンの自動作成
24 | - 動画結合処理の実装
25 | - シンプルな機能とある程度のカスタマイズ性の両立
26 | - mp4/aacに対応
27 |
28 | ## おことわりと怒りの表明
29 | 1. 基本的にsm~以外の動画では動作しないようにしてあります
30 | 1. 一部の動画に暗号化されている動画がありますが、いろいろなところに抵触する為対応しません
31 | 1. 絶対に邪な使い方はしないで下さい
32 | 2. しょぼいスペックのPCではまず動きません
33 |
34 | ## 要件
35 | | 区分 | 数値 | 備考 |
36 | | :--------------- | :------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------- |
37 | | CPU | AMD Ryzen Zen プロセッサより新しいプロセッサ | |
38 | | RAM | 16GB以上 | 16GB未満はサポート対象外 p.ff?"AM":"PM"},"%S":function(p){return g(p.Ug,2)},"%t":function(){return"\t"},"%u":function(p){return p.gf||7},"%U":function(p){var u=new Date(p.he+1900,0,1),w=0===u.getDay()?u:Qc(u,7-u.getDay());p=new Date(p.he+1900,p.Ke,p.Ve);return 0>h(w,p)?g(Math.ceil((31-w.getDate()+(Lc(Kc(p.getFullYear())?Mc:Nc,p.getMonth()-1)-31)+p.getDate())/7),2):0===h(w,u)?"01":"00"},"%V":function(p){var u=new Date(p.he+1901,0,4),w=m(new Date(p.he+1900,
171 | 0,4));u=m(u);var D=Qc(new Date(p.he+1900,0,1),p.hf);return 0>h(D,w)?"53":0>=h(u,D)?"01":g(Math.ceil((w.getFullYear()
変換前にメモリ上に保存する関係でメモリを大量に使用
動画1時間あたり約4GBのメモリ消費を想定 |
39 | | OS | Windows 11 23H2以上 | Macintoshは一切の動作保証なし |
40 | | 導入するブラウザ | Chrome最新版 | Chrome以外はサポート対象外(特にEdge) |
41 | | 回線 | 100Mbps以上
nicovideo.jpへのpingやfetchの疎通が常にうまくいく環境 | これ未満でも動かないということはないが、自己責任でお願いします |
42 |
43 |
44 | ## 初期設定
45 | 1. Chromeの拡張機能の設定であったり、右上のボタンを押すなりしてオプションを開きます
46 | 2. 初期設定モードをOFFにします
47 | 3. 一番下の保存ボタンを押します
48 | 4. これで完了です
49 |
50 | ## 使用方法
51 | 1. 動画ページを開く
52 | 1. 基本的にsm~から始まる動画のみサポート
53 | 1. それ以外の動画は動作サポート対象外
54 | 1. 2秒くらい待つ
55 | 1. 動画の右下あたりに「保存」ボタンが生成ささる
56 | 1. クリックされるとシステムメッセージが自動で開かさり処理開始される
57 | 1. 開かれたシステムメッセージはすぐ閉じて大丈夫です
58 | 1. 処理は自動で行われる
59 | 1. ffmpegが裏で処理を行っているので少々重いかもしれない
60 | 1. 保存ダイアログが出るか既定のフォルダに保存される
61 | 1. ここはChromeの設定に依存するため注意を要する
62 |
63 | ## しくみ
64 | 1. 動画ページのシステムメッセージ内にHLSのURLがあるので、そのURLを抽出しそのデータをキャッシュ
65 | 1. 同様に、動画のタイトルを抽出しそのデータをキャッシュ
66 | 1. キャッシュされたデータをもとにCMAFとかを取得
67 | 1. 取得したデータをffmpeg.wasmで結合(aacの場合、aacで出力、mp4の場合mp4で出力)
68 | 1. 結合したデータをblobとして取得
69 | 1. すでにblobになっているのでディスクに書き込めばすぐ保存終了
70 |
71 | ## QandAや要望
72 | | 質問 | 回答 |
73 | | :----------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
74 | | 1. 保存できる画質を設定できるようにしてほしい | <対応予定あり>時間要します |
75 | | 2. 音声データを保存できるようにしてほしい | プルリクを採用し対応しました。→[対応させていただきました](https://github.com/masteralice3104/nico_downloader/pull/8) |
76 | | 3. コメントをダウンロードできるようにしてほしい | <対応検討中> |
77 | | 4. ダウンロードしようとしたら1KBになりました。バグらささっていると思います。 | 十中八九変換に失敗しています。
原因の一例
・PCのメモリが足りない(要件を読んで下さい)
・回線の問題でダウンロードに失敗した(要件を読んで下さい)
・動画が暗号化されている(おことわりを読んで下さい)
・動画が長すぎる(特に3時間以上) |
78 | | 5. バグを発見した | Issuesを立ててください |
79 | | 6. Plz, I've Question by ENG or other... | I understand "Japanese". But I can't understand enough ENG. ------ I'd confirmed that DeepL translation and Google Translate don't correctly translate the dialect I talk. These sentence is also likely to be incorrect. Therefore, if you and I use a translator, our intentions would may be conveyed incorrectly. So I can't respond. |
80 | | 7. 多言語対応してほしい | 一応多言語対応できる状態になっていますがそもそも正しい翻訳なのかかなり怪しい状況です |
81 | | 8. 「あ、 nico downloaderの現状、不具合、リリースノートなどはこちらから のリンク先がなくなってます」 | 直しました。2024.9.16 |
82 | | 9. なんか良さげな改造した!見て! | プルリクください。変更点をすべて確認した後、採用する場合があります。 |
83 | | 10. バージョンが細かすぎるのでは? | Chrome Web Storeの審査に時間をかけないための工夫です。 |
84 | | |
85 |
86 | ## 非常に雑なリリースノート
87 | | バージョン名 | 日次 | アップデート項目 |
88 | | ------------ | ---------- | ------------------------------------------------------------------------ |
89 | | 1.0.0.0 | 覚えてない | リリース前バージョン 初作成 |
90 | | 1.0.2.2 | | リリース |
91 | | 1.0.2.3 | | リファクタリング及びバグの修正 |
92 | | 1.0.2.4 | | デバッグモードの実装 |
93 | | 1.1.0.0 | | ニコニコ大百科用の機能追加 |
94 | | 1.2.0.0 | 2022.3.14 | 自動保存モード追加
setOption修正 |
95 | | 1.2.0.1 | 2022.6.18 | nm番号のものがDLできなかった件修正 |
96 | | 2.0.0.0 | 2023.6.1 | HLSモード対応
外部のffmpeg.exeを使用したバージョン |
97 | | 3.0.0.0 | 2023.6.13 | HLSモードをffmpeg.wasmを使ったものに変更 |
98 | | 3.0.0.1 | 2023.6.18 | 修正 |
99 | | 3.0.0.2 | 2023.11.1 | ニコニコの突然のUI変更に対応 |
100 | | 4.0.0.0 | 2023.12.3 | 大規模なリファクタリングにて再構築 |
101 | | 4.1.0.0 | 2024.8.5 | リファクタリング |
102 | | 5.0.0.0 | 2024.8.5 | 帰ってきたニコニコ対応 |
103 | | 5.0.0.1 | 2024.8.7 | 保存時メモリを大量に使う問題に対処 |
104 | | 5.0.0.2 | 2024.8.7 | 二重ダウンロードされることがある問題に対処 |
105 | | 5.0.0.3 | 2024.8.10 | 初期設定モードの説明が変なことになっていたのを修正 |
106 | | 5.0.0.4 | 2024.8.11 | リファクタリング |
107 | | 5.0.0.5 | 2024.8.11 | オプション画面を書き換え |
108 | | 5.0.0.6 | 2024.9.6 | 誤字修正、ニコニコの動画ページ変更追従 |
109 | | 5.0.0.7 | 2024.9.16 | 多言語対応の設定を追加
オプションページの変更 |
110 | | 5.0.0.8 | 2024.9.17 | 保存された動画への一部メタタグの追加 |
111 | | 5.0.0.9 | 2024.9.23 | 軽微な修正 |
112 | | 5.0.0.10 | 2024.9.26 | 5.0.0.7へのロールバック |
113 | | 5.0.0.11 | 2024.9.27 | シリーズが存在しない動画の場合途中で落ちる現象の修正、微修正 |
114 | | 5.0.0.13 | 2024.9.28 | 投稿者が存在しない動画への対処 |
115 | | 5.0.0.14 | 2024.11.4 | aacに対応( https://github.com/masteralice3104/nico_downloader/pull/8 ) |
116 | | 5.0.0.15 | 2024.11.4 | タグなし動画の場合途中で落ちる現象の修正 |
117 | | 5.0.0.16 | 2025.02.22 | ニコニコの画面更新に対応 |
118 | | 5.0.0.17 | 2025.02.22 | オプション初期処理が抜けていたのを修正 |
119 | | 5.0.0.18 | 2025.02.24 | モードが取得できなかった場合はデフォルトのmp4にする仕組み導入 |
--------------------------------------------------------------------------------
/nico_downloader/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2021 masteralice3104
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/nico_downloader/dic_scripts.js:
--------------------------------------------------------------------------------
1 | let start_res = 0;
2 | let end_res = 0;
3 |
4 |
5 |
6 | //ページ表示時発火処理
7 | window.onload = function () {
8 | Start_Dic();
9 | }
10 |
11 | function Start_Dic() {
12 | const thisURL = location.href;
13 |
14 |
15 |
16 |
17 | //スレのみページ
18 | if (thisURL.match("https://dic.nicovideo.jp/b/a/.")) {
19 |
20 | refresh_resNo();
21 |
22 |
23 | //html要素作成
24 | let button_threadnext = document.createElement('button');
25 | button_threadnext.id = `next_30`;
26 | button_threadnext.innerHTML = `次の30件を読込`;
27 | if (end_res % 30 == 0) {
28 | document.getElementsByClassName("st-bbs_resbody")[document.getElementsByClassName("st-bbs_resbody").length - 1].after(button_threadnext);
29 | document.getElementById("next_30").onclick = next_30load;
30 | }
31 |
32 | let button_threadprev = document.createElement('button');
33 | button_threadprev.id = `prev_30`;
34 | button_threadprev.innerHTML = `前の30件を読込`;
35 | if (start_res != 0) {
36 | document.getElementsByClassName("st-bbs_reshead")[0].before(button_threadprev);
37 | document.getElementById("prev_30").onclick = prev_30load;
38 | }
39 |
40 | resnumhead_plus();
41 |
42 | pinres();
43 |
44 |
45 | }
46 | if (thisURL.match("https://dic.nicovideo.jp/a/.")) {
47 | pinres();
48 | }
49 |
50 | }
51 |
52 | function pinres() {
53 |
54 | let button_threadpin1 = document.createElement('button');
55 | button_threadpin1.id = `threadpin_move_button1`;
56 | button_threadpin1.innerText = `最後に記録したレスに移動`;
57 |
58 | let button_threadpin2 = document.createElement('button');
59 | button_threadpin2.id = `threadpin_move_button2`;
60 | button_threadpin2.innerText = `最後に記録したレスに移動`;
61 |
62 | if (setOption(kiji_URL_get())) {
63 | document.getElementsByClassName("st-bbs_reshead")[0].before(button_threadpin1);
64 | document.getElementById("threadpin_move_button1").onclick = threadpin_move;
65 | document.getElementsByClassName("st-bbs_resbody")[document.getElementsByClassName("st-bbs_resbody").length - 1].after(button_threadpin2);
66 | document.getElementById("threadpin_move_button2").onclick = threadpin_move2;
67 | DebugPrint("threadpin_move set")
68 | } else {
69 |
70 | }
71 | }
72 |
73 | function refresh_resNo() {
74 | if (document.getElementsByClassName("st-bbs_resNo")) {
75 | //ページ最初と最後のレス番号取得
76 | start_res = Number(document.getElementsByClassName("st-bbs_resNo")[0].innerHTML);
77 | end_res = Number(document.getElementsByClassName("st-bbs_resNo")[document.getElementsByClassName("st-bbs_resNo").length - 1].innerHTML)
78 | DebugPrint(start_res + "~" + end_res);
79 | }
80 | }
81 |
82 |
83 | function prev_30load() {
84 |
85 | document.getElementById("prev_30").setAttribute("disabled", true);
86 |
87 |
88 | let kijiURL = kiji_URL_get();
89 | let DL_URL = kijiURL + "/" + Number(start_res - 30) + "-"
90 | DebugPrint(DL_URL);
91 |
92 | if (start_res != 1) {
93 | //https://www.codit.work/notes/ld2h3c2k1coufqauzydl/ を参考にした
94 | const result = fetch(DL_URL, {
95 | method: "GET"
96 | }).then(function (response) {
97 | return response.text();
98 | }).then(function (data) {
99 | const parser = new DOMParser();
100 | const doc = parser.parseFromString(data, "text/html");
101 |
102 | //中身取得
103 | let res_head = doc.getElementsByClassName("st-bbs_reshead");
104 | let res_body = doc.getElementsByClassName("st-bbs_resbody");
105 | let res_num = doc.getElementsByClassName("st-bbs_resbody").length;
106 |
107 | //htmlに追加
108 | //ここがちょっと違う
109 | for (let i = res_num - 1; i >= 0; i--) {
110 | let add_element = createElementFromHTML(res_head[i].outerHTML);
111 | document.getElementsByClassName("st-bbs_reshead")[0].before(add_element)
112 |
113 | add_element = createElementFromHTML(res_body[i].outerHTML);
114 | document.getElementsByClassName("st-bbs_reshead")[0].after(add_element)
115 | }
116 |
117 | //番号更新
118 | refresh_resNo();
119 |
120 | if (start_res != 1) { } else {
121 | document.getElementById("prev_30").remove();
122 |
123 | let last_element = document.createElement('p');
124 | last_element.innerText = "最初のレスまで読み込みました";
125 | document.getElementsByClassName("st-bbs_reshead")[0].before(last_element);
126 | }
127 | document.getElementById("prev_30").removeAttribute("disabled");
128 | resnumhead_plus();
129 | });
130 |
131 | }
132 | }
133 |
134 | function next_30load() {
135 |
136 | document.getElementById("next_30").setAttribute("disabled", true);
137 |
138 | let kijiURL = kiji_URL_get();
139 | let DL_URL = kijiURL + "/" + Number(end_res + 1) + "-"
140 | DebugPrint(DL_URL);
141 |
142 | if (end_res % 30 == 0) {
143 | //https://www.codit.work/notes/ld2h3c2k1coufqauzydl/ を参考にした
144 | const result = fetch(DL_URL, {
145 | method: "GET"
146 | }).then(function (response) {
147 | return response.text();
148 | }).then(function (data) {
149 | const parser = new DOMParser();
150 | const doc = parser.parseFromString(data, "text/html");
151 |
152 | //中身取得
153 | let res_head = doc.getElementsByClassName("st-bbs_reshead");
154 | let res_body = doc.getElementsByClassName("st-bbs_resbody");
155 | let res_num = doc.getElementsByClassName("st-bbs_resbody").length;
156 |
157 | //htmlに追加
158 | for (let i = 0; i < res_num; i++) {
159 | let add_element = createElementFromHTML(res_head[i].outerHTML);
160 | document.getElementsByClassName("st-bbs_resbody")[document.getElementsByClassName("st-bbs_resbody").length - 1].after(add_element)
161 |
162 | add_element = createElementFromHTML(res_body[i].outerHTML);
163 | document.getElementsByClassName("st-bbs_reshead")[document.getElementsByClassName("st-bbs_reshead").length - 1].after(add_element)
164 | }
165 |
166 | //番号更新
167 | refresh_resNo();
168 |
169 |
170 |
171 | if (end_res % 30 == 0) {
172 | document.getElementById("next_30").removeAttribute("disabled");
173 | } else {
174 | document.getElementById("next_30").remove();
175 |
176 | let last_element = document.createElement('p');
177 | last_element.innerText = "最新のレスまで読み込みました";
178 | document.getElementsByClassName("st-bbs_resbody")[document.getElementsByClassName("st-bbs_resbody").length - 1].after(last_element);
179 |
180 | }
181 | resnumhead_plus();
182 | });
183 |
184 | }
185 | }
186 |
187 |
188 |
189 |
190 |
191 | //https://qiita.com/seijikohara/items/911f886d8eb79862870b
192 | //ぶちこんだHTMLをelementにして返す
193 | function createElementFromHTML(html) {
194 | const tempEl = document.createElement('div');
195 | tempEl.innerHTML = html;
196 | return tempEl.firstElementChild;
197 | }
198 |
199 | //元記事URL取得
200 | function kiji_URL_get() {
201 | let href = document.getElementsByClassName("st-pg_navi")[0].href;
202 | href = href.replace("https://dic.nicovideo.jp/a/", "https://dic.nicovideo.jp/b/a/")
203 | return href;
204 | }
205 |
206 |
207 | function resnumhead_plus() {
208 | DebugPrint("resnumhead_plus");
209 | for (let i = 0; i < document.getElementsByClassName("resnumhead").length; i++) {
210 |
211 | if (setOption(kiji_URL_get())) {
212 | if (setOption(kiji_URL_get()) === document.getElementsByClassName("resnumhead")[i].getAttribute("name")) {
213 | document.getElementsByClassName("resnumhead")[i].innerText = "■";
214 | } else {
215 | document.getElementsByClassName("resnumhead")[i].innerText = "□";
216 | }
217 | } else {
218 | document.getElementsByClassName("resnumhead")[i].innerText = "□";
219 | }
220 | document.getElementsByClassName("resnumhead")[i].href = "javascript:void(0);"
221 | document.getElementsByClassName("resnumhead")[i].onclick = pin_dome;
222 | document.getElementsByClassName("resnumhead")[i].id = document.getElementsByClassName("resnumhead")[i].getAttribute("name");
223 |
224 | }
225 | }
226 |
227 | function pin_dome(e) {
228 | let res_no = e.currentTarget.getAttribute("name");
229 | let kiji_URL = kiji_URL_get();
230 | DebugPrint("pin_dome : " + kiji_URL + " : " + res_no);
231 |
232 |
233 |
234 | //変更
235 | if (e.currentTarget.innerText === "■") {
236 | //ローカルストレージを0で上書き
237 | Option_setWriting(kiji_URL, "0");
238 | //e.currentTarget.innerText = "□";
239 | } else {
240 | //ローカルストレージに書き込み
241 | Option_setWriting(kiji_URL, res_no);
242 | //e.currentTarget.innerText = "■";
243 | }
244 | resnumhead_plus();
245 |
246 | }
247 |
248 | function threadpin_move2() {
249 | threadpin_move()
250 | }
251 |
252 | function threadpin_move() {
253 |
254 | DebugPrint("threadpin_move")
255 | let kiji_URL = kiji_URL_get();
256 | let id = Number(setOption(kiji_URL));
257 | if (id === 0) {
258 | let defaultURL = kiji_URL + "/1-";
259 | location.href = defaultURL;
260 | }
261 |
262 | if (start_res <= id && end_res >= id) {
263 | location.hash = "";
264 | location.hash = id.toString();
265 | return;
266 | }
267 |
268 |
269 | let page = Math.floor(id / 30) * 30 + 1;
270 | let pageURL = kiji_URL + "/" + page;
271 |
272 | if (start_res > id | start_res === 0) {
273 | setTimeout(threadpin_move, 200);
274 | location.href = pageURL + "#" + id.toString();
275 |
276 |
277 |
278 | // document.getElementById("prev_30").click();
279 |
280 |
281 | }
282 | if (end_res < id | end_res === 0) {
283 | // document.getElementById("next_30").click();
284 | setTimeout(threadpin_move, 200);
285 | location.href = pageURL + "#" + id.toString();
286 |
287 |
288 | }
289 |
290 | }
--------------------------------------------------------------------------------
/nico_downloader/dist/ffmpeg-core.wasm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/masteralice3104/nico_downloader/a4fac44a27252a09b070d11464c3b68ab9c5fe96/nico_downloader/dist/ffmpeg-core.wasm
--------------------------------------------------------------------------------
/nico_downloader/dist/ffmpeg-core2.js:
--------------------------------------------------------------------------------
1 |
2 | var createFFmpegCore = (function() {
3 | var _scriptDir = typeof document !== 'undefined' && document.currentScript ? document.currentScript.src : undefined;
4 | if (typeof __filename !== 'undefined') _scriptDir = _scriptDir || __filename;
5 | return (
6 | function(createFFmpegCore) {
7 | createFFmpegCore = createFFmpegCore || {};
8 |
9 |
10 | var e;e||(e=typeof createFFmpegCore !== 'undefined' ? createFFmpegCore : {});var ba,ca;e.ready=new Promise(function(a,b){ba=a;ca=b});e.quit=function(a){if(e.onExit)e.onExit(a);throw new da(a);};e.exit=ea;fa=k=function(){};var ia={},ja;for(ja in e)e.hasOwnProperty(ja)&&(ia[ja]=e[ja]);var ka=[],la="./this.program";function ma(a,b){throw b;}var na=!1,pa=!1,qa=!1,ra=!1;na="object"===typeof window;pa="function"===typeof importScripts;
11 | qa="object"===typeof process&&"object"===typeof process.versions&&"string"===typeof process.versions.node;ra=!na&&!qa&&!pa;var l="",sa,ta,ua,va;
12 | if(qa)l=pa?require("path").dirname(l)+"/":__dirname+"/",sa=function(a,b){ua||(ua=require("fs"));va||(va=require("path"));a=va.normalize(a);return ua.readFileSync(a,b?null:"utf8")},ta=function(a){a=sa(a,!0);a.buffer||(a=new Uint8Array(a));assert(a.buffer);return a},1
1.下記「初期設定モード」をOFFにし、ページの一番下にある「保存」ボタンを押下します。
143 |2.動画ページを開き、動画の右下あたりにある保存ボタンを押します。
144 |3.しばらくダウンロードと変換処理に時間がかかります。
145 |4.動画が保存されます。既定のフォルダに自動保存または保存ダイアログが表示されます。(Chromeの保存設定によります)
146 | 147 | 148 | 149 | 150 |259 | 260 |
vX.X.X.X
278 | 279 | 280 |19 |
109 | 110 |