UNPKG

3.11 kBJavaScriptView Raw
1const miniget = require('miniget')
2
3module.exports = async (query, options = {}) => {
4 const response = await miniget(
5 'https://www.youtube.com/results?search_query=' + encodeURIComponent(query), options
6 ).text()
7 const line = response.match(/window\["ytInitialData"]\s*=\s*(.*);+\n/)[0]
8 const json = JSON.parse(line.substring(line.indexOf('{'), line.length - 2))
9 const result = json
10 ['contents']['twoColumnSearchResultsRenderer']['primaryContents']['sectionListRenderer']
11 ['contents'][0]['itemSectionRenderer']['contents']
12 return result.filter(video => {
13 const type = Object.keys(video)[0].replace('Renderer', '')
14 return ['video', 'playlist'].includes(type)
15 }).map(video => {
16 const type = Object.keys(video)[0].replace('Renderer', '')
17 const data = video[type + 'Renderer']
18 const identifier = data[type + 'Id']
19 if (type === 'video') {
20 const isStream = !Object.keys(data).includes('lengthText')
21 let length = Number.MAX_VALUE
22 if (!isStream) {
23 length = 0
24 data['lengthText']['simpleText'].split(':').reverse().forEach((value, index) => {
25 const i = Number(value)
26 length += (index === 0 ? i : i * (60 ** index))
27 })
28 }
29 return {
30 type: type,
31 identifier: identifier,
32 uri: 'https://www.youtube.com/watch?v=' + identifier,
33 title: data['title']['runs'][0]['text'],
34 author: {
35 name: data['ownerText']['runs'][0]['text'],
36 profile: data['channelThumbnailSupportedRenderers']['channelThumbnailWithLinkRenderer']
37 ['thumbnail']['thumbnails'][0]['url'],
38 uri: 'https://www.youtube.com' + data['ownerText']['runs'][0]['navigationEndpoint']
39 ['commandMetadata']['webCommandMetadata']['url']
40 },
41 length: {
42 ms: isStream ? length : length * 1000,
43 sec: length
44 },
45 isStream: isStream,
46 thumbnails: data['thumbnail']['thumbnails']
47 }
48 } else return {
49 type: type,
50 identifier: identifier,
51 uri: 'https://www.youtube.com/playlist?list=' + identifier,
52 title: data['title']['simpleText'],
53 author: {
54 name: data['longBylineText']['runs'][0]['text'],
55 uri: 'https://www.youtube.com' + data['longBylineText']['runs'][0]['navigationEndpoint']
56 ['commandMetadata']['webCommandMetadata']['url']
57 },
58 count: Number(data['videoCount']),
59 thumbnails: data['thumbnails']
60 }
61 }).filter(it => {
62 if (options.filter === 'video') return it.type === 'video'
63 else if (options.filter === 'playlist') return it.type === 'playlist'
64 else return true
65 })
66}