1
- function formatSize ( size ) {
2
- size = Number ( size ) ;
1
+ const { formatSize, promiseAllStepN } = UsefulScriptGlobalPageContext . Utils ;
2
+ const { injectScriptSrc } = UsefulScriptGlobalPageContext . DOM ;
3
3
4
- if ( ! size ) return "?" ;
4
+ const xhrDownloadUint8Array = async ( { url, contentLength } , progressCb ) => {
5
+ if ( typeof contentLength === "string" )
6
+ contentLength = parseInt ( contentLength ) ;
7
+ progressCb ( {
8
+ loaded : 0 ,
9
+ total : contentLength ,
10
+ speed : 0 ,
11
+ } ) ;
12
+ const chunkSize = 65536 ;
13
+ const getBuffer = ( start , end ) =>
14
+ fetch ( url + `&range=${ start } -${ end ? end - 1 : "" } ` ) . then ( ( r ) =>
15
+ r . arrayBuffer ( )
16
+ ) ;
17
+ const data = new Uint8Array ( contentLength ) ;
18
+ let downloaded = 0 ;
19
+ const tasks = [ ] ;
20
+ const startTime = Date . now ( ) ;
5
21
6
- // format to KB, MB, GB
7
- if ( size < 1024 ) {
8
- return size + "B" ;
22
+ for ( let start = 0 ; start < contentLength ; start += chunkSize ) {
23
+ const exceeded = start + chunkSize > contentLength ;
24
+ const curChunkSize = exceeded ? contentLength - start : chunkSize ;
25
+ const end = exceeded ? null : start + chunkSize ;
26
+ tasks . push ( ( ) => {
27
+ console . log ( "dl start" , url , start , end ) ;
28
+ return getBuffer ( start , end )
29
+ . then ( ( buf ) => {
30
+ console . log ( "dl done" , url , start , end ) ;
31
+ downloaded += curChunkSize ;
32
+ data . set ( new Uint8Array ( buf ) , start ) ;
33
+ const ds = ( Date . now ( ) - startTime + 1 ) / 1000 ;
34
+ progressCb ( {
35
+ loaded : downloaded ,
36
+ total : contentLength ,
37
+ speed : downloaded / ds ,
38
+ } ) ;
39
+ } )
40
+ . catch ( ( err ) => {
41
+ console . log ( "Download error" ) ;
42
+ } ) ;
43
+ } ) ;
9
44
}
10
- if ( size < 1024 * 1024 ) {
11
- return ( size / 1024 ) . toFixed ( 2 ) + "KB" ;
12
- }
13
- if ( size < 1024 * 1024 * 1024 ) {
14
- return ( size / ( 1024 * 1024 ) ) . toFixed ( 2 ) + "MB" ;
15
- }
16
- return ( size / ( 1024 * 1024 * 1024 ) ) . toFixed ( 2 ) + "GB" ;
17
- }
45
+ await promiseAllStepN ( 6 , tasks ) ;
46
+ return data ;
47
+ } ;
18
48
19
49
window . onload = ( ) => {
20
50
const yt_data = JSON . parse (
@@ -50,20 +80,19 @@ window.onload = () => {
50
80
51
81
// video
52
82
for ( let video of videos ) {
53
- const div = document . createElement ( "div" ) ;
54
- div . innerHTML = `
55
- <a
56
- href="${ video . url } "
57
- target="_blank">
58
- <p>
83
+ const button = document . createElement ( "button" ) ;
84
+ button . style = "display:block;margin-bottom:5px" ;
85
+ button . innerHTML = `
59
86
${ video . qualityLabel }
60
87
- ${ video . width } x${ video . height }
61
- - ${ formatSize ( video . contentLength ) }
62
- ${ video . audioQuality ? "" : " (no audio)" }
63
- </p>
64
- </a>
65
- ` ;
66
- document . body . appendChild ( div ) ;
88
+ - ${ formatSize ( video . contentLength , 2 ) }
89
+ ${ video . audioQuality ? "" : " (no audio)" } ` ;
90
+ button . onclick = ( ) => {
91
+ let data = xhrDownloadUint8Array ( video , ( progress ) => {
92
+ console . log ( progress ) ;
93
+ } ) ;
94
+ } ;
95
+ document . body . appendChild ( button ) ;
67
96
}
68
97
69
98
// audio
@@ -73,7 +102,7 @@ window.onload = () => {
73
102
<audio src="${ audio . url } " controls></audio>
74
103
<p>
75
104
${ audio . audioTrack ?. displayName || audio . audioQuality }
76
- - ${ formatSize ( audio . contentLength ) }
105
+ - ${ formatSize ( audio . contentLength , 2 ) }
77
106
</p>
78
107
` ;
79
108
document . body . appendChild ( div ) ;
0 commit comments