import * as tokenizer from "@tokenizer/http" ; import * as metadata from "music-metadata" ; import LimitedReadWriteStream from "../util/LimitedReadWriteStream" ; import Util from "../util/Util" ; const mimeRegex = /^(audio|video)\/(.+)$|^application\/(ogg)$/ ; async function getHTTPAsSource ( resource ) { type ExtraData = { title ? : string ; author ? : string ; stream : boolean ; probe : string ; } ; let parsed ; let headers = undefined ; try { const stream = await Util . request ( resource ) ; const readwrite = new LimitedReadWriteStream ( 50 ) ; headers = stream . headers ; parsed = await metadata . parseStream ( stream . pipe ( readwrite ) , { mimeType : stream . headers [ "content-type" ] , size : stream . headers [ "content-length" ] ? Number ( stream . headers [ "content-length" ] ) : undefined } ) ; stream . destroy ( ) ; } catch { try { const toke = await tokenizer . makeTokenizer ( resource , { timeoutInSec : 10 } , { resolveUrl : true } ) ; headers = { "content-type" : toke . fileInfo . mimeType , "content-length" : String ( toke . fileInfo . size ) } ; const timer = new Promise < import ( "music-metadata" ) . IAudioMetadata > ( ( _ , rej ) => setTimeout ( ( ) => rej ( new Error ( "Timeout reached" ) ) , 7500 ) ) ; parsed = await Promise . race < Promise < import ( "music-metadata" ) . IAudioMetadata > > ( [ timer , metadata . parseFromTokenizer ( toke ) ] ) . then ( d => d [ 1 ] ) ; } catch { if ( ! headers ) throw new Error ( "MISSING_HEADERS" ) ; if ( headers [ "content-type" ] ?. match ( mimeRegex ) ) { parsed = { common : { } , format : { } } ; } else parsed = undefined ; } } if ( ! parsed ) throw new Error ( "NO_PARSED" ) ; const mimeMatch = headers [ "content-type" ] ?. match ( mimeRegex ) ; const chunked = ! ! ( headers [ "transfer-encoding" ] && headers [ "transfer-encoding" ] . includes ( "chunked" ) ) ; const extra = { stream : chunked , probe : mimeMatch ? ( mimeMatch [ 3 ] ? mimeMatch [ 3 ] : mimeMatch [ 2 ] ) : parsed . format . container ! . toLowerCase ( ) } ; if ( headers [ "icy-description" ] ) extra . title = headers [ "icy-description" ] as string ; if ( headers [ "icy-name" ] ) extra . author = headers [ "icy-name" ] as string ; return { parsed , extra } ; } export = getHTTPAsSource ;