@@ -9,7 +9,7 @@ import os from "node:os";
99import stream from "node:stream" ;
1010import crypto from "node:crypto" ;
1111
12- //#region node_modules/.pnpm/twitch-gql-queries@0.1.13 /node_modules/twitch-gql-queries/dist/index.js
12+ //#region node_modules/.pnpm/twitch-gql-queries@0.1.17 /node_modules/twitch-gql-queries/dist/index.js
1313var CLIENT_ID = "kimne78kx3ncx6brgo4mv6wki5h1ko" ;
1414var MAX_QUERIES_PER_REQUEST = 35 ;
1515var gqlRequest = async ( queries , requestInit ) => {
@@ -48,7 +48,7 @@ var getQueryShareClipRenderStatus = (variables) => ({
4848 variables,
4949 extensions : { persistedQuery : {
5050 version : 1 ,
51- sha256Hash : "f130048a462a0ac86bb54d653c968c514e9ab9ca94db52368c1179e97b0f16eb "
51+ sha256Hash : "e0a46b287d760c6890a39d1ccd736af5ec9479a267d02c710e9ac33326b651d2 "
5252 } }
5353} ) ;
5454var getQueryStreamMetadata = ( variables ) => ( {
@@ -258,18 +258,16 @@ const parseMediaPlaylist = (lines) => {
258258 duration : Number . parseFloat ( segLines [ i ] . replace ( EXTINF , "" ) . replace ( "," , "" ) ) ,
259259 map
260260 } ) ;
261- const endlist = lines . includes ( "#EXT-X-ENDLIST" ) ;
262261 return {
263262 type : "playlist" ,
264263 isMasterPlaylist : false ,
265- endlist,
264+ endlist : lines . includes ( "#EXT-X-ENDLIST" ) ,
266265 segments
267266 } ;
268267} ;
269268const parse = ( playlist ) => {
270269 const lines = playlist . split ( "\n" ) . map ( ( line ) => line . trim ( ) ) . filter ( Boolean ) ;
271- const isMasterPlaylist = MASTER_PLAYLIST_TAGS . some ( ( s ) => lines . some ( ( line ) => line . startsWith ( `#${ s } :` ) ) ) ;
272- return isMasterPlaylist ? parseMasterPlaylist ( lines ) : parseMediaPlaylist ( lines ) ;
270+ return MASTER_PLAYLIST_TAGS . some ( ( s ) => lines . some ( ( line ) => line . startsWith ( `#${ s } :` ) ) ) ? parseMasterPlaylist ( lines ) : parseMediaPlaylist ( lines ) ;
273271} ;
274272
275273//#endregion
@@ -316,8 +314,7 @@ const ILLEGAL_PATH_CHARS_MAP = {
316314 "|" : "|"
317315} ;
318316const sanitizeFilename = ( str ) => {
319- const chars = Object . keys ( ILLEGAL_PATH_CHARS_MAP ) ;
320- const regex = `[${ chars . map ( ( c ) => c === "\\" ? "\\\\" : c ) . join ( "" ) } ]` ;
317+ const regex = `[${ Object . keys ( ILLEGAL_PATH_CHARS_MAP ) . map ( ( c ) => c === "\\" ? "\\\\" : c ) . join ( "" ) } ]` ;
321318 return str . replace ( new RegExp ( regex , "g" ) , ( c ) => ILLEGAL_PATH_CHARS_MAP [ c ] ) ;
322319} ;
323320const getOutputPath = ( template , videoInfo ) => {
@@ -513,8 +510,7 @@ const createLogger = (logPath) => (event) => {
513510const nameEq = ( name ) => ( event ) => event [ 0 ] === name ;
514511const getLog = async ( logPath ) => {
515512 try {
516- const logContent = await fsp . readFile ( logPath , "utf8" ) ;
517- return logContent . split ( "\n" ) . filter ( Boolean ) . map ( ( line ) => line . split ( " " ) . map ( ( v ) => JSON . parse ( v ) ) ) ;
513+ return ( await fsp . readFile ( logPath , "utf8" ) ) . split ( "\n" ) . filter ( Boolean ) . map ( ( line ) => line . split ( " " ) . map ( ( v ) => JSON . parse ( v ) ) ) ;
518514 } catch {
519515 return null ;
520516 }
@@ -755,8 +751,7 @@ const parseRateLimit = (rateLimit) => {
755751} ;
756752const isUrlsAvailableFetch = async ( urls , gzip ) => {
757753 try {
758- const responses = await Promise . all ( urls . map ( ( url ) => fetch ( url , { headers : { "Accept-Encoding" : gzip ? "deflate, gzip" : "" } } ) ) ) ;
759- return responses . map ( ( res ) => res . ok ) ;
754+ return ( await Promise . all ( urls . map ( ( url ) => fetch ( url , { headers : { "Accept-Encoding" : gzip ? "deflate, gzip" : "" } } ) ) ) ) . map ( ( res ) => res . ok ) ;
760755 } catch ( e ) {
761756 return urls . map ( ( ) => false ) ;
762757 }
@@ -886,7 +881,7 @@ const downloadFrag = async (downloader, url, destPath, limitRateArg, gzip, type
886881//#region src/utils/getDlFormat.ts
887882const getDlFormat = ( formats , formatArg ) => {
888883 const dlFormat = formatArg === "best" ? formats [ 0 ] : formats . find ( ( f ) => f . format_id . toLowerCase ( ) === formatArg . toLowerCase ( ) ) ;
889- if ( ! dlFormat ) throw new Error ( " Wrong format" ) ;
884+ if ( ! dlFormat ) throw new Error ( ` Wrong format: ${ formatArg } ` ) ;
890885 return dlFormat ;
891886} ;
892887
@@ -1091,13 +1086,11 @@ const timeFmt = new Intl.DateTimeFormat(LOCALE, {
10911086} ) ;
10921087const formatSpeed = ( n ) => {
10931088 const i = n === 0 ? 0 : Math . floor ( Math . log ( n ) / Math . log ( 1024 ) ) ;
1094- const value = n / Math . pow ( 1024 , i ) ;
1095- return `${ value . toFixed ( 2 ) } ${ UNITS [ i ] } /s` ;
1089+ return `${ ( n / Math . pow ( 1024 , i ) ) . toFixed ( 2 ) } ${ UNITS [ i ] } /s` ;
10961090} ;
10971091const formatSize = ( n ) => {
10981092 const i = n === 0 ? 0 : Math . floor ( Math . log ( n ) / Math . log ( 1024 ) ) ;
1099- const value = n / Math . pow ( 1024 , i ) ;
1100- return `${ value . toFixed ( 2 ) } ${ UNITS [ i ] } ` ;
1093+ return `${ ( n / Math . pow ( 1024 , i ) ) . toFixed ( 2 ) } ${ UNITS [ i ] } ` ;
11011094} ;
11021095const showProgress = ( downloadedFrags , fragsCount ) => {
11031096 const dlFrags = Array . from ( downloadedFrags . values ( ) ) ;
@@ -1130,6 +1123,7 @@ const showProgress = (downloadedFrags, fragsCount) => {
11301123const WAIT_BETWEEN_CYCLES_SEC = 60 ;
11311124const RETRY_MESSAGE = `Retry every ${ WAIT_BETWEEN_CYCLES_SEC } second(s)` ;
11321125const downloadVideo = async ( formats , videoInfo , args ) => {
1126+ if ( formats . length === 0 ) throw new Error ( "Cannot get video formats" ) ;
11331127 if ( args [ "list-formats" ] ) {
11341128 showFormats ( formats ) ;
11351129 process . exit ( ) ;
@@ -1297,8 +1291,7 @@ const getVideoInfoByClipMeta = (clipMeta) => ({
12971291//#region src/utils/downloadWithStreamlink.ts
12981292const DEFAULT_STREAMLINK_ARGS = [ "--twitch-force-client-integrity" , "--twitch-access-token-param=playerType=frontpage" ] ;
12991293const getDefaultOutputTemplate = ( ) => {
1300- const now = ( /* @__PURE__ */ new Date ( ) ) . toISOString ( ) . slice ( 0 , 16 ) . replace ( "T" , " " ) . replace ( ":" , "_" ) ;
1301- return `%(uploader)s (live) ${ now } [%(id)s].%(ext)s` ;
1294+ return `%(uploader)s (live) ${ ( /* @__PURE__ */ new Date ( ) ) . toISOString ( ) . slice ( 0 , 16 ) . replace ( "T" , " " ) . replace ( ":" , "_" ) } [%(id)s].%(ext)s` ;
13021295} ;
13031296const downloadWithStreamlink = async ( link , streamMeta , channelLogin , args ) => {
13041297 if ( ! await isInstalled ( "streamlink" ) ) throw new Error ( "streamlink is not installed. Install it from https://streamlink.github.io/" ) ;
@@ -1412,12 +1405,10 @@ const getVideoFormats = async (videoId) => {
14121405 if ( ! accessToken ) return [ ] ;
14131406 const manifest = await getManifest ( videoId , accessToken ) ;
14141407 if ( ! manifest ) return [ ] ;
1415- const formats = parseDownloadFormats ( manifest ) ;
1416- return formats ;
1408+ return parseDownloadFormats ( manifest ) ;
14171409} ;
14181410const getFullVodPath = ( vodPath ) => {
1419- const hashedVodPath = crypto . createHash ( "sha1" ) . update ( vodPath ) . digest ( "hex" ) . slice ( 0 , 20 ) ;
1420- return `${ hashedVodPath } _${ vodPath } ` ;
1411+ return `${ crypto . createHash ( "sha1" ) . update ( vodPath ) . digest ( "hex" ) . slice ( 0 , 20 ) } _${ vodPath } ` ;
14211412} ;
14221413const getVodUrl = ( vodDomain , fullVodPath , broadcastType = "ARCHIVE" , videoId = "" , format = "chunked" ) => {
14231414 const playlistName = broadcastType === "HIGHLIGHT" ? `highlight-${ videoId } ` : "index-dvr" ;
@@ -1449,11 +1440,10 @@ const getAvailableFormats = async (vodDomain, fullVodPath, broadcastType, videoI
14491440 return formats ;
14501441} ;
14511442const getVideoFormatsByFullVodPath = async ( fullVodPath , broadcastType , videoId ) => {
1452- const responses = await Promise . all ( VOD_DOMAINS . map ( ( domain ) => {
1443+ const vodDomainIdx = ( await Promise . all ( VOD_DOMAINS . map ( ( domain ) => {
14531444 const url = getVodUrl ( domain , fullVodPath , broadcastType , videoId ) ;
14541445 return fetch ( url , { method : "HEAD" } ) . catch ( ( ) => null ) ;
1455- } ) ) ;
1456- const vodDomainIdx = responses . findIndex ( ( res ) => res ?. ok ) ;
1446+ } ) ) ) . findIndex ( ( res ) => res ?. ok ) ;
14571447 if ( vodDomainIdx === - 1 ) return [ ] ;
14581448 return getAvailableFormats ( VOD_DOMAINS [ vodDomainIdx ] , fullVodPath , broadcastType , videoId ) ;
14591449} ;
@@ -1589,8 +1579,7 @@ const downloadClip = async (slug, args) => {
15891579 const res = await fetch ( dlFormat . url , { method : "HEAD" } ) ;
15901580 const size = Number . parseInt ( res . headers . get ( "content-length" ) || "0" ) ;
15911581 console . log ( `[download] Downloading clip (${ ( size / 1024 / 1024 ) . toFixed ( 2 ) } MB)` ) ;
1592- const result = await downloadFrag ( args . downloader , dlFormat . url , destPath , args [ "limit-rate" ] , void 0 , "mp4" ) ;
1593- if ( ! result ) throw new Error ( "[download] Download failed" ) ;
1582+ if ( ! await downloadFrag ( args . downloader , dlFormat . url , destPath , args [ "limit-rate" ] , void 0 , "mp4" ) ) throw new Error ( "[download] Download failed" ) ;
15941583 console . log ( "[download] Done" ) ;
15951584} ;
15961585
@@ -1657,13 +1646,11 @@ const mergeFragments = async (outputPath, args) => {
16571646//#region src/commands/showHelp.ts
16581647const showHelp = async ( ) => {
16591648 const readmePath = path . resolve ( import . meta. dirname , "README.md" ) ;
1660- const readme = await fsp . readFile ( readmePath , "utf8" ) ;
1661- const entries = readme . split ( / \s # # ( .* ) / g) . slice ( 1 ) ;
1649+ const entries = ( await fsp . readFile ( readmePath , "utf8" ) ) . split ( / \s # # ( .* ) / g) . slice ( 1 ) ;
16621650 const sections = { } ;
16631651 for ( let i = 0 ; i < entries . length ; i += 2 ) {
16641652 const header = entries [ i ] ;
1665- const content = entries [ i + 1 ] . trim ( ) ;
1666- sections [ header ] = content ;
1653+ sections [ header ] = entries [ i + 1 ] . trim ( ) ;
16671654 }
16681655 const help = [
16691656 "Options:" ,
0 commit comments