w-dwload-dlp 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/.editorconfig +9 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.js +55 -0
  4. package/.jsdoc +25 -0
  5. package/LICENSE +21 -0
  6. package/README.md +63 -0
  7. package/SECURITY.md +5 -0
  8. package/babel.config.js +15 -0
  9. package/dist/w-dwload-dlp.umd.js +7 -0
  10. package/dist/w-dwload-dlp.umd.js.map +1 -0
  11. package/docs/WDwloadDlp.mjs.html +417 -0
  12. package/docs/fonts/Montserrat/Montserrat-Bold.eot +0 -0
  13. package/docs/fonts/Montserrat/Montserrat-Bold.ttf +0 -0
  14. package/docs/fonts/Montserrat/Montserrat-Bold.woff +0 -0
  15. package/docs/fonts/Montserrat/Montserrat-Bold.woff2 +0 -0
  16. package/docs/fonts/Montserrat/Montserrat-Regular.eot +0 -0
  17. package/docs/fonts/Montserrat/Montserrat-Regular.ttf +0 -0
  18. package/docs/fonts/Montserrat/Montserrat-Regular.woff +0 -0
  19. package/docs/fonts/Montserrat/Montserrat-Regular.woff2 +0 -0
  20. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.eot +0 -0
  21. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.svg +978 -0
  22. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.ttf +0 -0
  23. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff +0 -0
  24. package/docs/fonts/Source-Sans-Pro/sourcesanspro-light-webfont.woff2 +0 -0
  25. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.eot +0 -0
  26. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.svg +1049 -0
  27. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.ttf +0 -0
  28. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff +0 -0
  29. package/docs/fonts/Source-Sans-Pro/sourcesanspro-regular-webfont.woff2 +0 -0
  30. package/docs/global.html +484 -0
  31. package/docs/index.html +84 -0
  32. package/docs/scripts/collapse.js +39 -0
  33. package/docs/scripts/commonNav.js +28 -0
  34. package/docs/scripts/linenumber.js +25 -0
  35. package/docs/scripts/nav.js +12 -0
  36. package/docs/scripts/polyfill.js +4 -0
  37. package/docs/scripts/prettify/Apache-License-2.0.txt +202 -0
  38. package/docs/scripts/prettify/lang-css.js +2 -0
  39. package/docs/scripts/prettify/prettify.js +28 -0
  40. package/docs/scripts/search.js +99 -0
  41. package/docs/styles/jsdoc.css +776 -0
  42. package/docs/styles/prettify.css +80 -0
  43. package/g.mjs +38 -0
  44. package/package.json +32 -0
  45. package/script.txt +18 -0
  46. package/src/WDwloadDlp.mjs +345 -0
  47. package/test/all.test.mjs +16 -0
  48. package/toolg/addVersion.mjs +4 -0
  49. package/toolg/cleanFolder.mjs +4 -0
  50. package/toolg/gDistRollup.mjs +30 -0
  51. package/toolg/modifyReadme.mjs +4 -0
  52. package/yt-dlp-2024.04.09/ffmpeg.exe +0 -0
  53. package/yt-dlp-2024.04.09/yt-dlp.exe +0 -0
  54. package/yt-dlp.md +15 -0
@@ -0,0 +1,417 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+
5
+ <meta charset="utf-8">
6
+ <title>WDwloadDlp.mjs - Documentation</title>
7
+
8
+
9
+ <script src="scripts/prettify/prettify.js"></script>
10
+ <script src="scripts/prettify/lang-css.js"></script>
11
+ <!--[if lt IE 9]>
12
+ <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
13
+ <![endif]-->
14
+ <link type="text/css" rel="stylesheet" href="styles/prettify.css">
15
+ <link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
16
+ <script src="scripts/nav.js" defer></script>
17
+
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
+ </head>
20
+ <body>
21
+
22
+ <input type="checkbox" id="nav-trigger" class="nav-trigger" />
23
+ <label for="nav-trigger" class="navicon-button x">
24
+ <div class="navicon"></div>
25
+ </label>
26
+
27
+ <label for="nav-trigger" class="overlay"></label>
28
+
29
+ <nav >
30
+
31
+
32
+ <h2><a href="index.html">Home</a></h2><h3>Global</h3><ul><li><a href="global.html#WDwloadDlp">WDwloadDlp</a></li></ul>
33
+
34
+ </nav>
35
+
36
+ <div id="main">
37
+
38
+ <h1 class="page-title">WDwloadDlp.mjs</h1>
39
+
40
+
41
+
42
+
43
+
44
+
45
+
46
+ <section>
47
+ <article>
48
+ <pre class="prettyprint source linenums"><code>import path from 'path'
49
+ import process from 'process'
50
+ import get from 'lodash-es/get.js'
51
+ import genID from 'wsemi/src/genID.mjs'
52
+ import now2strp from 'wsemi/src/now2strp.mjs'
53
+ import sep from 'wsemi/src/sep.mjs'
54
+ import strright from 'wsemi/src/strright.mjs'
55
+ import strdelright from 'wsemi/src/strdelright.mjs'
56
+ import isestr from 'wsemi/src/isestr.mjs'
57
+ import isfun from 'wsemi/src/isfun.mjs'
58
+ import cdbl from 'wsemi/src/cdbl.mjs'
59
+ import execProcess from 'wsemi/src/execProcess.mjs'
60
+ import fsIsFile from 'wsemi/src/fsIsFile.mjs'
61
+ import fsIsFolder from 'wsemi/src/fsIsFolder.mjs'
62
+ import fsCopyFile from 'wsemi/src/fsCopyFile.mjs'
63
+ import fsDeleteFile from 'wsemi/src/fsDeleteFile.mjs'
64
+
65
+
66
+ let fdSrv = path.resolve()
67
+
68
+
69
+ function isWindows() {
70
+ return process.platform === 'win32'
71
+ }
72
+
73
+
74
+ /**
75
+ * 下載video檔案,預設轉mp4,核心調用yt-dlp,只能用於Windows作業系統
76
+ *
77
+ * yt-dlp: https://github.com/yt-dlp/yt-dlp
78
+ *
79
+ * @param {String} url 輸入網址字串,支援網站種類詳見yt-dlp
80
+ * @param {String} fp 輸入儲存video(*.mp4)檔案路徑字串
81
+ * @param {Object} [opt={}] 輸入設定物件,預設{}
82
+ * @param {Function} [opt.funProg=null] 輸入回傳進度函數,傳入參數為prog代表進度百分比、nn代表當前已下載ts檔案數量、na代表全部須下載ts檔案數量,預設null
83
+ * @returns {Promise} 回傳Promise,resolve回傳成功訊息,reject回傳錯誤訊息
84
+ * @example
85
+ * // import WDwloadDlp from 'w-dwload-dlp'
86
+ * import WDwloadDlp from './src/WDwloadDlp.mjs'
87
+ *
88
+ * async function test() {
89
+ *
90
+ * //url
91
+ * let url = `https://www.youtube.com/watch?v=uj8hjLyEBmU&amp;ab_channel=%E7%A0%81%E5%86%9C%E9%AB%98%E5%A4%A9` //youtube
92
+ * // let url = `https://www.bilibili.com/video/BV1JZ421x7q8/?spm_id_from=333.1073.channel.secondary_floor_video.click` //bilibili
93
+ *
94
+ * //fp
95
+ * let fp = './test.mp4'
96
+ *
97
+ * //funProg
98
+ * let funProg = (prog, nn, na) => {
99
+ * console.log('prog', `${prog.toFixed(2)}%`, nn, na)
100
+ * }
101
+ *
102
+ * //WDwloadDlp
103
+ * await WDwloadDlp(url, fp, {
104
+ * clean: true, //單一程序執行時, 事先清除之前暫存檔, 減少浪費硬碟空間
105
+ * funProg,
106
+ * })
107
+ *
108
+ * console.log('done:', fp)
109
+ * }
110
+ * test()
111
+ * .catch((err) => {
112
+ * console.log('catch', err)
113
+ * })
114
+ * // prog 0.49% 1 99
115
+ * // prog 5.05% 4 99
116
+ * // ...
117
+ * // prog 99.00% 98 99
118
+ * // prog 100.00% 99 99
119
+ * // done: ./test.mp4
120
+ *
121
+ */
122
+ async function WDwloadDlp(url, fp, opt = {}) {
123
+ let errTemp = null
124
+
125
+ //funProg
126
+ let funProg = get(opt, 'funProg')
127
+
128
+ //isWindows
129
+ if (!isWindows()) {
130
+ return Promise.reject('operating system is not windows')
131
+ }
132
+
133
+ //check
134
+ if (!isestr(url)) {
135
+ return Promise.reject('url is not a file')
136
+ }
137
+
138
+ //fdExe
139
+ let fdms = 'yt-dlp-2024.04.09'
140
+ let fdExeSelf = `${fdSrv}/${fdms}/`
141
+ let fdExeDist = `${fdSrv}/node_modules/w-dwload-dlp/${fdms}/`
142
+ let fdExe = fdExeSelf
143
+ if (fsIsFolder(fdExeDist)) {
144
+ fdExe = fdExeDist
145
+ }
146
+
147
+ //exeDl
148
+ let exeDl = path.resolve(fdExe, 'yt-dlp.exe')
149
+ exeDl = `"${exeDl}"` //用雙引號包住避免路徑有空格
150
+ // console.log('exeDl', exeDl)
151
+
152
+ //cwdOri, cwdTar
153
+ let cwdOri = process.cwd()
154
+ let cwdTar = fdExe
155
+ // console.log('process.cwd1', process.cwd())
156
+
157
+ //chdir, 若不切換mseed2ascii預設輸出檔案是在工作路徑, 輸出檔變成會出現在專案下
158
+ process.chdir(cwdTar)
159
+ // console.log('process.cwd2', process.cwd())
160
+
161
+ //id
162
+ let id = `${now2strp()}-${genID(6)}`
163
+
164
+ //fnAny
165
+ let fnAny = `${id}` //無副檔名
166
+
167
+ //fdDownloads
168
+ let fdDownloads = path.resolve(fdExe, 'Downloads')
169
+ // console.log('fdDownloads', fdDownloads)
170
+
171
+ //fpInAny
172
+ let fpInAny = path.resolve(fdDownloads, fnAny)
173
+ // console.log('fpInAny', fpInAny)
174
+
175
+ //fpInMp4
176
+ let fpInMp4 = path.resolve(fdDownloads, `${id}.mp4`)
177
+ // console.log('fpInMp4', fpInMp4)
178
+
179
+ let bdl = false
180
+ let nnPre = 0
181
+ let nn = 0
182
+ let na = 0
183
+ let prog = 0
184
+ let bFunProg = isfun(funProg)
185
+ let cbStdout = (msg) => {
186
+ // console.log('cbStdout', msg)
187
+
188
+ //s
189
+ let s = sep(msg, ' ')
190
+ // console.log('s', s)
191
+
192
+ //s1
193
+ let s1 = get(s, 1, '')
194
+
195
+ //bp
196
+ let bp = strright(s1, 1) === '%'
197
+
198
+ //check
199
+ if (!bp) {
200
+ return
201
+ }
202
+
203
+ //prog
204
+ let _prog = strdelright(s1, 1)
205
+ _prog = cdbl(_prog)
206
+ // console.log('_prog(ori)', _prog)
207
+
208
+ //bdl
209
+ if (!bdl &amp;&amp; _prog === 100) {
210
+ bdl = true
211
+ return //當第1次達100%先跳出, 不處理之後檔案下載進度
212
+ }
213
+ // console.log('bdl', bdl)
214
+
215
+ //check, 若bdl=false, 代表尚未完成下載清單100%, 不處理之後檔案下載進度
216
+ if (!bdl) {
217
+ return
218
+ }
219
+ // console.log('eff. download')
220
+
221
+ _prog *= 0.99 //最高99%, 因可能還有轉檔(例如webm轉mp4), 故最後100%改由最後完成階段觸發
222
+ // console.log('_prog(99%)', _prog)
223
+
224
+ //update
225
+ if (prog &lt; _prog) {
226
+ prog = _prog
227
+ }
228
+ else {
229
+ return
230
+ }
231
+ // console.log('prog', prog)
232
+
233
+ //nna
234
+ let s10 = get(s, 10)
235
+ s10 = strdelright(s10, 1)
236
+ let nna = sep(s10, '/')
237
+
238
+ //nn
239
+ nn = get(nna, 0, '')
240
+ nn = cdbl(nn)
241
+ // console.log('nn', nn)
242
+
243
+ //check, 若nn沒有>nnPre則視為不需要觸發funProg, 減少切太細導致高頻觸發
244
+ if (nn &lt;= nnPre) {
245
+ return
246
+ }
247
+
248
+ //na
249
+ na = get(nna, 1, '')
250
+ na = cdbl(na)
251
+ // console.log('na', na)
252
+
253
+ //call
254
+ if (bFunProg) {
255
+ // console.log('prog', nn, na, prog)
256
+ funProg(prog, nn, na)
257
+ }
258
+
259
+ //update
260
+ nnPre = nn
261
+
262
+ }
263
+
264
+ //cmdDl
265
+ let cmdDl = `"${url}" -o "${fpInAny}" --newline --merge-output-format "mp4"`
266
+ // console.log('cmdDl', cmdDl)
267
+
268
+ //execProcess
269
+ await execProcess(exeDl, cmdDl, { cbStdout })
270
+ // .then(function(res) {
271
+ // console.log('execProcess then', res)
272
+ // })
273
+ .catch((err) => {
274
+ console.log('execProcess catch', err)
275
+ errTemp = 'execProcess error'
276
+ })
277
+
278
+ //call
279
+ if (bFunProg) {
280
+ prog = 100
281
+ // console.log('prog', prog)
282
+ funProg(prog, na, na) //因是強制100%, 故nn要直接給na
283
+ }
284
+
285
+
286
+ // //clearInterval
287
+ // clearInterval(t)
288
+
289
+ //chdir, 不論正常或錯誤皆需還原工作路徑
290
+ process.chdir(cwdOri)
291
+
292
+ //check
293
+ if (isestr(errTemp)) {
294
+ return Promise.reject(errTemp)
295
+ }
296
+
297
+ // //check, 若因m3u8內method給NONE無法被N_m3u8DL-CLI識別處理, 故會採取僅合併ts不轉檔方式產生ts
298
+ // if (!fsIsFile(fpInAny) &amp;&amp; fsIsFile(fpInTs)) {
299
+
300
+ // //cmdFfmpeg
301
+ // let cmdFfmpeg = `-i "${fpInTs}" -vcodec copy -acodec copy "${fpInAny}"`
302
+ // // console.log('cmdFfmpeg', cmdFfmpeg)
303
+
304
+ // //execProcess
305
+ // await execProcess(exeFfmpeg, cmdFfmpeg)
306
+ // // .then(function(res) {
307
+ // // console.log('execProcess then', res)
308
+ // // })
309
+ // .catch(() => {
310
+ // //console.log('execProcess catch', err)
311
+ // //特殊偵測處理, 不再提供報錯訊尋
312
+ // })
313
+
314
+ // }
315
+
316
+ // //check, 若下載檔案為webm, 則再轉為mp4
317
+ // if (fsIsFile(fpInWebm) &amp;&amp; !fsIsFile(fpInMp4)) {
318
+
319
+ // //cmdFfmpeg
320
+ // let cmdFfmpeg = `-i -k "${fpInWebm}" "${fpInMp4}"`
321
+ // // console.log('cmdFfmpeg', cmdFfmpeg)
322
+
323
+ // //execProcess
324
+ // await execProcess(exeFfmpeg, cmdFfmpeg)
325
+ // .then(function(res) {
326
+ // console.log('execProcess then', res)
327
+ // })
328
+ // .catch((err) => {
329
+ // console.log('execProcess catch', err)
330
+ // //特殊偵測處理, 不再提供報錯訊尋
331
+ // })
332
+
333
+ // }
334
+
335
+ //check
336
+ if (!fsIsFile(fpInMp4)) {
337
+ console.log(`can not find the merged file[${fpInMp4}]`)
338
+ errTemp = `invalid url[${url}] or can not download`
339
+ return Promise.reject(errTemp)
340
+ }
341
+
342
+ //fpOut
343
+ let fpOut = fp
344
+ // console.log('fpOut', fpOut)
345
+
346
+ let rc
347
+
348
+ //fsCopyFile
349
+ rc = fsCopyFile(fpInMp4, fpOut)
350
+ errTemp = get(rc, 'error')
351
+ if (errTemp) {
352
+ return Promise.reject(errTemp.toString())
353
+ }
354
+
355
+ //fsDeleteFile
356
+ rc = fsDeleteFile(fpInMp4)
357
+ //可能無檔案無法刪, 故不檢查錯誤
358
+
359
+ // //fsDeleteFile
360
+ // rc = fsDeleteFile(fpInWebm)
361
+ // //可能無檔案無法刪, 故不檢查錯誤
362
+
363
+ // //fsDeleteFile
364
+ // rc = fsDeleteFile(fpInMp4)
365
+ // errTemp = get(rc, 'error')
366
+ // if (errTemp) {
367
+ // return Promise.reject(errTemp.toString())
368
+ // }
369
+
370
+ // //fsDeleteFile
371
+ // rc = fsDeleteFile(fpInTs)
372
+ // //可能無檔案無法刪, 故不檢查錯誤
373
+
374
+ // //fsDeleteFolder
375
+ // rc = fsDeleteFolder(fdDownloadsId)
376
+ // errTemp = get(rc, 'error')
377
+ // if (errTemp) {
378
+ // return Promise.reject(errTemp.toString())
379
+ // }
380
+
381
+ // //fsCleanFolder
382
+ // rc = fsCleanFolder(fdLogs)
383
+ // errTemp = get(rc, 'error')
384
+ // if (errTemp) {
385
+ // return Promise.reject(errTemp.toString())
386
+ // }
387
+
388
+ return 'ok'
389
+ }
390
+
391
+
392
+ export default WDwloadDlp
393
+ </code></pre>
394
+ </article>
395
+ </section>
396
+
397
+
398
+
399
+
400
+
401
+
402
+ </div>
403
+
404
+ <br class="clear">
405
+
406
+ <footer>
407
+ Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 4.0.3</a> on Tue May 21 2024 21:53:47 GMT+0800 (台北標準時間) using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
408
+ </footer>
409
+
410
+ <script>prettyPrint();</script>
411
+ <script src="scripts/polyfill.js"></script>
412
+ <script src="scripts/linenumber.js"></script>
413
+
414
+
415
+
416
+ </body>
417
+ </html>