1- function formatSize ( size ) {
2- size = Number ( size ) ;
1+ const { formatSize, promiseAllStepN } = UsefulScriptGlobalPageContext . Utils ;
2+ const { injectScriptSrc } = UsefulScriptGlobalPageContext . DOM ;
33
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 ( ) ;
521
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+ } ) ;
944 }
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+ } ;
1848
1949window . onload = ( ) => {
2050 const yt_data = JSON . parse (
@@ -50,20 +80,19 @@ window.onload = () => {
5080
5181 // video
5282 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 = `
5986 ${ video . qualityLabel }
6087 - ${ 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 ) ;
6796 }
6897
6998 // audio
@@ -73,7 +102,7 @@ window.onload = () => {
73102 <audio src="${ audio . url } " controls></audio>
74103 <p>
75104 ${ audio . audioTrack ?. displayName || audio . audioQuality }
76- - ${ formatSize ( audio . contentLength ) }
105+ - ${ formatSize ( audio . contentLength , 2 ) }
77106 </p>
78107 ` ;
79108 document . body . appendChild ( div ) ;
0 commit comments