diff --git a/lib/Constants.js b/lib/Constants.js index 0412592d..8328cf9a 100644 --- a/lib/Constants.js +++ b/lib/Constants.js @@ -192,81 +192,5 @@ module.exports = { video_details.metadata = metadata; } return video_details; - }, - filters: (order) => { - return (({ - 'any,any,relevance': 'EgIQAQ%3D%3D', - 'hour,any,relevance': 'EgIIAQ%3D%3D', - 'day,any,relevance': 'EgQIAhAB', - 'week,any,relevance': 'EgQIAxAB', - 'month,any,relevance': 'EgQIBBAB', - 'year,any,relevance': 'EgQIBRAB', - 'any,short,relevance': 'EgQQARgB', - 'hour,short,relevance': 'EgYIARABGAE%3D', - 'day,short,relevance': 'EgYIAhABGAE%3D', - 'week,short,relevance': 'EgYIAxABGAE%3D', - 'month,short,relevance': 'EgYIBBABGAE%3D', - 'year,short,relevance': 'EgYIBRABGAE%3D', - 'any,long,relevance': 'EgQQARgC', - 'hour,long,relevance': 'EgYIARABGAI%3D', - 'day,long,relevance': 'EgYIAhABGAI%3D', - 'week,long,relevance': 'EgYIAxABGAI%3D', - 'month,long,relevance': 'EgYIBBABGAI%3D', - 'year,long,relevance': 'EgYIBRABGAI%3D', - 'any,any,age': 'CAISAhAB', - 'hour,any,age': 'CAISBAgBEAE%3D', - 'day,any,age': 'CAISBAgCEAE%3D', - 'week,any,age': 'CAISBAgDEAE%3D', - 'month,any,age': 'CAISBAgEEAE%3D', - 'year,any,age': 'CAISBAgFEAE%3D', - 'any,short,age': 'CAISBBABGAE%3D', - 'hour,short,age': 'CAISBggBEAEYAQ%3D%3D', - 'day,short,age': 'CAISBggCEAEYAQ%3D%3D', - 'week,short,age': 'CAISBggDEAEYAQ%3D%3D', - 'month,short,age': 'CAISBggEEAEYAQ%3D%3D', - 'year,short,age': 'CAISBggFEAEYAQ%3D%3D', - 'any,long,age': 'CAISBBABGAI%3D', - 'hour,long,age': 'CAISBggBEAEYAg%3D%3D', - 'day,long,age': 'CAISBggCEAEYAg%3D%3D', - 'week,long,age': 'CAISBggDEAEYAg%3D%3D', - 'month,long,age': 'CAISBggEEAEYAg%3D%3D', - 'year,long,age': 'CAISBggFEAEYAg%3D%3D', - 'any,any,views': 'CAMSAhAB', - 'hour,any,views': 'CAMSBAgBEAE%3D', - 'day,any,views': 'CAMSBAgCEAE%3D', - 'week,any,views': 'CAMSBAgDEAE%3D', - 'month,any,views': 'CAMSBAgEEAE%3D', - 'year,any,views': 'CAMSBAgFEAE%3D', - 'any,short,views': 'CAMSBBABGAE%3D', - 'hour,short,views': 'CAMSBggBEAEYAQ%3D%3D', - 'day,short,views': 'CAMSBggCEAEYAQ%3D%3D', - 'week,short,views': 'CAMSBggDEAEYAQ%3D%3D', - 'month,short,views': 'CAMSBggEEAEYAQ%3D%3D', - 'year,short,views': 'CAMSBggFEAEYAQ%3D%3D', - 'any,long,views': 'CAMSBBABGAI%3D', - 'hour,long,views': 'CAMSBggBEAEYAg%3D%3D', - 'day,long,views': 'CAMSBggCEAEYAg%3D%3D', - 'week,long,views': 'CAMSBggDEAEYAg%3D%3D', - 'month,long,views': 'CAMSBggEEAEYAg%3D%3D', - 'year,long,views': 'CAMSBggFEAEYAg%3D%3D', - 'any,any,rating': 'CAESAhAB', - 'hour,any,rating': 'CAESBAgBEAE%3D', - 'day,any,rating': 'CAESBAgCEAE%3D', - 'week,any,rating': 'CAESBAgDEAE%3D', - 'month,any,rating': 'CAESBAgEEAE%3D', - 'year,any,rating': 'CAESBAgFEAE%3D', - 'any,short,rating': 'CAESBBABGAE%3D', - 'hour,short,rating': 'CAESBggBEAEYAQ%3D%3D', - 'day,short,rating': 'CAESBggCEAEYAQ%3D%3D', - 'week,short,rating': 'CAESBggDEAEYAQ%3D%3D', - 'month,short,rating': 'CAESBggEEAEYAQ%3D%3D', - 'year,short,rating': 'CAESBggFEAEYAQ%3D%3D', - 'any,long,rating': 'CAESBBABGAI%3D', - 'hour,long,rating': 'CAESBggBEAEYAg%3D%3D', - 'day,long,rating': 'CAESBggCEAEYAg%3D%3D', - 'week,long,rating': 'CAESBggDEAEYAg%3D%3D', - 'month,long,rating': 'CAESBggEEAEYAg%3D%3D', - 'year,long,rating': 'CAESBggFEAEYAg%3D%3D' - })[order] || 'EgIQAQ%3D%3D'); } }; \ No newline at end of file diff --git a/lib/Innertube.js b/lib/Innertube.js index d76c11a0..2f8ba4db 100644 --- a/lib/Innertube.js +++ b/lib/Innertube.js @@ -116,7 +116,7 @@ class Innertube extends EventEmitter { async search(query, options = { period: 'any', order: 'relevance', duration: 'any' }) { if (!query) throw new Error('No query was provided'); - const response = await Axios.post(`${Constants.URLS.YT_BASE_URL}/youtubei/v1/search${this.logged_in && this.cookie.length < 1 ? '' : `?key=${this.key}`}`, JSON.stringify({ context: this.context, params: Constants.filters(options.period + ',' + options.duration + ',' + options.order), query }), Constants.INNERTUBE_REQOPTS({ session: this })).catch((error) => error); + const response = await Axios.post(`${Constants.URLS.YT_BASE_URL}/youtubei/v1/search${this.logged_in && this.cookie.length < 1 ? '' : `?key=${this.key}`}`, JSON.stringify({ context: this.context, params: Utils.encodeFilter(options.period, options.duration, options.order), query }), Constants.INNERTUBE_REQOPTS({ session: this })).catch((error) => error); if (response instanceof Error) throw new Error(`Could not search on YouTube: ${response.message}`); let content = response.data.contents.twoColumnSearchResultsRenderer.primaryContents.sectionListRenderer.contents[0].itemSectionRenderer.contents; @@ -401,19 +401,17 @@ class Innertube extends EventEmitter { } let downloaded_size = 0; + response.data.on('data', (chunk) => { downloaded_size += chunk.length; - let size = (response.headers['content-length'] / 1024 / 1024).toFixed(2); - let percentage = Math.floor((downloaded_size / response.headers['content-length']) * 100); + const size = (response.headers['content-length'] / 1024 / 1024).toFixed(2); + const percentage = Math.floor((downloaded_size / response.headers['content-length']) * 100); stream.emit('progress', { chunk_size: chunk.length, downloaded_size: (downloaded_size / 1024 / 1024).toFixed(2), percentage, size, raw_data: { chunk_size: chunk.length, downloaded: downloaded_size, size: response.headers['content-length'] } }); }); response.data.on('error', (err) => { - if (cancelled) { - stream.emit('error', { message: 'The download was cancelled.', type: 'DOWNLOAD_CANCELLED' }); - } else { + cancelled && stream.emit('error', { message: 'The download was cancelled.', type: 'DOWNLOAD_CANCELLED' }) || stream.emit('error', { message: err.message, type: 'DOWNLOAD_ABORTED' }); - } }); response.data.pipe(stream, { end: true }); @@ -450,11 +448,8 @@ class Innertube extends EventEmitter { }); response.data.on('error', (err) => { - if (cancelled) { - stream.emit('error', { message: 'The download was cancelled.', type: 'DOWNLOAD_CANCELLED' }); - } else { + cancelled && stream.emit('error', { message: 'The download was cancelled.', type: 'DOWNLOAD_CANCELLED' }) || stream.emit('error', { message: err.message, type: 'DOWNLOAD_ABORTED' }); - } }); response.data.on('end', () => { diff --git a/lib/Utils.js b/lib/Utils.js index 7cb8cd89..d6a4d149 100644 --- a/lib/Utils.js +++ b/lib/Utils.js @@ -83,4 +83,23 @@ function generateCommentParams(video_id) { return encodeURIComponent(Buffer.from(buf).toString('base64')); } -module.exports = { getRandomUserAgent, generateSidAuth, getStringBetweenStrings, generateMessageParams, generateCommentParams, encodeNotificationPref }; \ No newline at end of file +function encodeFilter(period, duration, order) { + const youtube_proto = Proto(Fs.readFileSync(`${__dirname}/proto/youtube.proto`)); + + const periods = { 'any': null, 'hour': 1, 'day': 2, 'week': 3, 'month': 4, 'year': 5 }; + const durations = { 'any': null, 'short': 1, 'long': 2 }; + const orders = { 'relevance': null, 'rating': 1, 'age': 2, 'views': 3 }; + + const search_filter_buff = youtube_proto.SearchFilter.encode({ + number: orders[order], + filter: { + param_0: periods[period], + param_1: (period == 'hour' && order == 'relevance') ? null : 1, + param_2: durations[duration] + } + }); + + return encodeURIComponent(Buffer.from(search_filter_buff).toString('base64')); +} + +module.exports = { getRandomUserAgent, generateSidAuth, getStringBetweenStrings, generateMessageParams, generateCommentParams, encodeNotificationPref, encodeFilter }; \ No newline at end of file