Skip to content

Instantly share code, notes, and snippets.

@morkin1792
Last active May 19, 2020 23:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save morkin1792/bd3eae1a533b48918455424d5d3e02cc to your computer and use it in GitHub Desktop.
Save morkin1792/bd3eae1a533b48918455424d5d3e02cc to your computer and use it in GitHub Desktop.
download audio from youtube channels
const axios = require('axios')
const fs = require('fs')
const req = async (url) => {
return await axios.get(url, { headers: { 'X-YouTube-Client-Name': 1, 'X-YouTube-Client-Version': '2.20200514.05.00', 'X-YouTube-Page-CL': 311468061 } })
}
const getAudio = async (url) => {
const resp = await req('https://youtube.com' + url + '&pbj=1')
if (resp.status == 200 && resp.data[2]?.player) {
let data = JSON.parse(resp.data[2].player.args.player_response)
let rawFormats = data.streamingData.adaptiveFormats.filter(o => o.audioQuality?.indexOf('AUDIO_QUALITY') == 0)
let rawFormat = rawFormats[0]
rawFormats.forEach(r => {
if (r.contentLength < rawFormat.contentLength && r.url)
rawFormat = r
});
// console.log(r)
let audioUrl = rawFormat.url
let title = data.videoDetails.title
if (!audioUrl) {
console.log(' [-] missing url to ' + title + ' ' + url)
return
}
// let lastModified = new Date(Number(rawFormat.lastModified.substr(0,13)))
// let quality = rawFormat.audioQuality
let publishDate = data.microformat.playerMicroformatRenderer.publishDate
console.log(' [*] Downloading ' + (rawFormat.contentLength/(1024*1024)).toFixed(2) + 'MB from ' + title)
let audio = await axios.get(audioUrl, {responseType: 'arraybuffer'})
let fileName = publishDate + ' ' + title
fileName = fileName.replace(/\//g,'')
fs.writeFileSync(fileName, audio.data)
} else {
console.error(resp.status)
console.error(resp.data)
}
}
(async () => {
const channelId = 'UCwSxSJqGpSRpEsq5-YUbM8g'
let loadAllUrls = false
let resp = await req('https://youtube.com/channel/' + channelId + '/videos?pbj=1')
let data = resp.data[1]?.response?.contents?.twoColumnBrowseResultsRenderer?.tabs[1]?.tabRenderer?.content?.sectionListRenderer?.contents[0]?.itemSectionRenderer?.contents[0]?.gridRenderer
let countVideos = 0
while (!loadAllUrls) {
let videos = data?.items
videos.forEach(v => {
countVideos += 1
let title = v.gridVideoRenderer.title.simpleText
let info = v.gridVideoRenderer.publishedTimeText.simpleText
let url = v.gridVideoRenderer.navigationEndpoint.commandMetadata.webCommandMetadata.url
console.log('[' + countVideos + '] ' + title + ' ' + info + ' ' + url)
getAudio(url)
});
if (resp.status != 200 || !data) {
console.error(resp.status)
console.error(resp.data)
return
}
let continuation = data.continuations?.[0].nextContinuationData?.continuation
if (videos.length < 30 || !continuation) {
loadAllUrls = true
} else {
resp = await req('https://www.youtube.com/browse_ajax?continuation=' + continuation)
data = resp.data[1]?.response?.continuationContents?.gridContinuation
}
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment