UNPKG

youtube-stream-url

Version:
143 lines (137 loc) 5.7 kB
var $gXNCa$axios = require("axios"); var $gXNCa$m3u8fileparser = require("m3u8-file-parser"); const $4fa36e821943b400$var$m3u8Parser = new $gXNCa$m3u8fileparser(); const $4fa36e821943b400$var$getRemoteFile = async (url)=>{ try { let { data: data } = await $gXNCa$axios.get(url); return data; } catch (e) { return null; } }; const $4fa36e821943b400$var$resolvePlayerResponse = (watchHtml)=>{ if (!watchHtml) return ""; let matches = watchHtml.match(/ytInitialPlayerResponse = (.*)}}};/); return matches ? matches[1] + "}}}" : ""; }; const $4fa36e821943b400$var$resoleM3U8Link = (watchHtml)=>{ if (!watchHtml) return null; let matches = watchHtml.match(/hlsManifestUrl":"(.*\/file\/index\.m3u8)/); return matches ? matches[1] : null; }; const $4fa36e821943b400$var$buildDecoder = async (watchHtml)=>{ if (!watchHtml) return null; let jsFileUrlMatches = watchHtml.match(/\/s\/player\/[A-Za-z0-9]+\/[A-Za-z0-9_.]+\/[A-Za-z0-9_]+\/base\.js/); if (!jsFileUrlMatches) return null; let jsFileContent = await $4fa36e821943b400$var$getRemoteFile(`https://www.youtube.com${jsFileUrlMatches[0]}`); let decodeFunctionMatches = jsFileContent.match(/function.*\.split\(\"\"\).*\.join\(\"\"\)}/); if (!decodeFunctionMatches) return null; let decodeFunction = decodeFunctionMatches[0]; let varNameMatches = decodeFunction.match(/\.split\(\"\"\);([a-zA-Z0-9]+)\./); if (!varNameMatches) return null; let varStartIndex = jsFileContent.indexOf(`var ${varNameMatches[1]}={`); if (varStartIndex < 0) return null; let varEndIndex = jsFileContent.indexOf("}};", varStartIndex); if (varEndIndex < 0) return null; let varDeclares = jsFileContent.substring(varStartIndex, varEndIndex + 3); if (!varDeclares) return null; return function(signatureCipher) { let params = new URLSearchParams(signatureCipher); let { s: signature , sp: signatureParam = "signature" , url: url } = Object.fromEntries(params); let decodedSignature = new Function(` "use strict"; ${varDeclares} return (${decodeFunction})("${signature}"); `)(); return `${url}&${signatureParam}=${encodeURIComponent(decodedSignature)}`; }; }; const $4fa36e821943b400$var$getInfo = async ({ url: url , throwOnError: throwOnError = false })=>{ let videoId = $4fa36e821943b400$var$getVideoId({ url: url }); if (!videoId) return false; let ytApi = "https://www.youtube.com/watch"; try { const response = await $gXNCa$axios.get(ytApi, { params: { v: videoId } }); if (!response || response.status != 200 || !response.data) { const error = new Error("Cannot get youtube video response"); error.response = response; throw error; } let ytInitialPlayerResponse = $4fa36e821943b400$var$resolvePlayerResponse(response.data); let parsedResponse = JSON.parse(ytInitialPlayerResponse); let streamingData = parsedResponse.streamingData || {}; let formats = (streamingData.formats || []).concat(streamingData.adaptiveFormats || []); let isEncryptedVideo = !!formats.find((it)=>!!it.signatureCipher); if (isEncryptedVideo) { let decoder = await $4fa36e821943b400$var$buildDecoder(response.data); if (decoder) formats = formats.map((it)=>{ if (it.url || !it.signatureCipher) return it; it.url = decoder(it.signatureCipher); delete it.signatureCipher; return it; }); } let result = { videoDetails: parsedResponse.videoDetails || {}, formats: formats.filter((format)=>format.url) }; if (result.videoDetails.isLiveContent) try { let m3u8Link = $4fa36e821943b400$var$resoleM3U8Link(response.data); if (m3u8Link) { let m3u8FileContent = await $4fa36e821943b400$var$getRemoteFile(m3u8Link); $4fa36e821943b400$var$m3u8Parser.read(m3u8FileContent); result.liveData = { manifestUrl: m3u8Link, data: $4fa36e821943b400$var$m3u8Parser.getResult() }; $4fa36e821943b400$var$m3u8Parser.reset(); } } catch (e) { if (throwOnError) throw e; } return result; } catch (e1) { if (throwOnError) throw e1; return false; } }; const $4fa36e821943b400$var$getVideoId = ({ url: url })=>{ let opts = { fuzzy: true }; if (/youtu\.?be/.test(url)) { // Look first for known patterns let i; let patterns = [ /youtu\.be\/([^#\&\?]{11})/, /\?v=([^#\&\?]{11})/, /\&v=([^#\&\?]{11})/, /embed\/([^#\&\?]{11})/, /\/v\/([^#\&\?]{11})/ // /v/<id> ]; // If any pattern matches, return the ID for(i = 0; i < patterns.length; ++i){ if (patterns[i].test(url)) return patterns[i].exec(url)[1]; } if (opts.fuzzy) { // If that fails, break it apart by certain characters and look // for the 11 character key let tokens = url.split(/[\/\&\?=#\.\s]/g); for(i = 0; i < tokens.length; ++i){ if (/^[^#\&\?]{11}$/.test(tokens[i])) return tokens[i]; } } } return null; }; module.exports = { getInfo: $4fa36e821943b400$var$getInfo, getVideoId: $4fa36e821943b400$var$getVideoId }; //# sourceMappingURL=index.js.map