Skip to content

Instantly share code, notes, and snippets.

@jalamprea
Created August 6, 2019 14:32
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 jalamprea/6908ceebed3e2f1a61b77a7272da0e86 to your computer and use it in GitHub Desktop.
Save jalamprea/6908ceebed3e2f1a61b77a7272da0e86 to your computer and use it in GitHub Desktop.
Implementation of Youtube Search API with Pure Javascript
var YoutubeSearcher = (function() {
function YoutubeSearcher() {
this.configuration = {};
this.dependencies = {};
}
YoutubeSearcher.prototype.searchSongs = function(query) {
var dependencies = this.dependencies;
var q = dependencies.q;
var rootScope = dependencies.rootScope;
var httpService = dependencies.httpService;
var defered = q.defer();
var promise = defered.promise;
//-----------------First request-----------------
var apiKey = this.configuration.api_key;
var urlRequest = 'https://www.googleapis.com/youtube/v3/search?videoEmbeddable=true&order=relevance&part=id&q=' + query + '&type=video&maxResults=50&key=' + apiKey;
var errorCallback = function(data) {
var message = 'GENERAL_ERROR';
if (data.status === 0) {
message = 'NETWORK_ERROR';
}
rootScope.$broadcast('showSongsSearchResults', new RequestResponse('Error', message, {}));
};
var successCallback = function(data) {
var songsId = YoutubeSearcher.prototype.getResourcesIdFromYoutubeResponse(data.data.items, 'searches-songs');
if (songsId === '') {
rootScope.$broadcast('showSongsSearchResults', new RequestResponse('Error', 'SEARCH_SONGS_NOT_FOUND', {
results_not_found: true
}));
} else {
defered.resolve(songsId);
}
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
//-----------------Second request-----------------
var resolveCallback = function(songsId) {
urlRequest = 'https://www.googleapis.com/youtube/v3/videos?part=snippet%2C+contentDetails%2C+statistics&id=' + songsId + '&key=' + apiKey;
var successCallback = function(data) {
var songsList = YoutubeSearcher.prototype.getSongsListFromYoutubeResponse(data.data.items, dependencies, true);
songsList.toArray().sort(SongUtilities.sortByViews);
var response = {
songs: songsList,
query: query
};
if (songsList.size() === 0) {
response = new RequestResponse('Error', 'SEARCH_SONGS_NOT_FOUND', response);
} else {
response = new RequestResponse('Success', '', response);
}
rootScope.$broadcast('showSongsSearchResults', response);
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
};
promise.then(resolveCallback);
};
YoutubeSearcher.prototype.getSuggestedSongs = function(songSourceId) {
var dependencies = this.dependencies;
var q = dependencies.q;
var rootScope = dependencies.rootScope;
var httpService = dependencies.httpService;
var defered = q.defer();
var promise = defered.promise;
//-----------------First request-----------------
var apiKey = this.configuration.api_key;
var urlRequest = 'https://www.googleapis.com/youtube/v3/search?part=snippet&&maxResults=10&relatedToVideoId=' + songSourceId + '&type=video&key=' + apiKey;
var errorCallback = function(data) {
var message = 'GENERAL_ERROR';
if (data.status === 0) {
message = 'NETWORK_ERROR';
}
rootScope.$broadcast('updateSuggestedSongs', new RequestResponse('Error', message, {}));
};
var successCallback = function(data) {
var songsId = YoutubeSearcher.prototype.getResourcesIdFromYoutubeResponse(data.data.items, 'suggested-songs');
if (songsId === '') {
rootScope.$broadcast('updateSuggestedSongs', new RequestResponse('Error', 'RELATED_SONGS_NOT_FOUND', {}));
} else {
defered.resolve(songsId);
}
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
//-----------------Second request-----------------
var resolveCallback = function(songsId) {
urlRequest = 'https://www.googleapis.com/youtube/v3/videos?part=snippet%2C+contentDetails%2C+statistics&id=' + songsId + '&key=' + apiKey;
var successCallback = function(data) {
var songsList = YoutubeSearcher.prototype.getSongsListFromYoutubeResponse(data.data.items, dependencies, true);
songsList.toArray().sort(SongUtilities.sortByViews);
var response = {
songs: songsList
};
if (songsList.size() === 0) {
response = new RequestResponse('Error', 'RELATED_SONGS_NOT_FOUND', response);
} else {
response = new RequestResponse('Success', '', response);
}
rootScope.$broadcast('updateSuggestedSongs', response);
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
};
promise.then(resolveCallback);
};
YoutubeSearcher.prototype.searchPlaylists = function(query) {
var dependencies = this.dependencies;
var q = dependencies.q;
var rootScope = dependencies.rootScope;
var httpService = dependencies.httpService;
var defered = q.defer();
var promise = defered.promise;
//-----------------First request-----------------
var apiKey = this.configuration.api_key;
var urlRequest = 'https://www.googleapis.com/youtube/v3/search?part=snippet&q=' + query + '&type=playlist&fields=items%2Fid&maxResults=3&key=' + apiKey;
var errorCallback = function(data) {
var message = 'GENERAL_ERROR';
if (data.status === 0) {
message = 'NETWORK_ERROR';
}
rootScope.$broadcast('showPlaylistsSearchResults', new RequestResponse('Error', message, {}));
};
var successCallback = function(data) {
var playlistsId = YoutubeSearcher.prototype.getResourcesIdFromYoutubeResponse(data.data.items, 'searches-playlists');
if (playlistsId === '') {
rootScope.$broadcast('showPlaylistsSearchResults', new RequestResponse('Error', 'SEARCH_PLAYLISTS_NOT_FOUND', {
results_not_found: true
}));
} else {
defered.resolve(playlistsId);
}
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
//-----------------Second request-----------------
var resolveCallback = function(playlistsId) {
urlRequest = 'https://www.googleapis.com/youtube/v3/playlists?part=contentDetails%2C+snippet&fields=items(contentDetails%2Cid%2Csnippet)&id=' + playlistsId + '&key=' + apiKey;
var successCallback = function(data) {
var playlists = new List();
var responseData = data.data.items;
var numberResults = responseData.length;
for (var i = 0; i < numberResults; i++) {
var item = responseData[i];
var playlist = new Playlist();
playlist.index = i;
playlist.source = 'Youtube';
playlist.source_id = item.id;
playlist.thumbnail = item.snippet.thumbnails && item.snippet.thumbnails.default ? item.snippet.thumbnails.default.url : 'https://i.ytimg.com/vi/6F4BU6OakHY/mqdefault.jpg';
playlist.title = item.snippet.title;
playlists.add(playlist);
}
var response = new RequestResponse('Success', '', {
playlists: playlists
});
rootScope.$broadcast('showPlaylistsSearchResults', response);
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
};
promise.then(resolveCallback);
};
YoutubeSearcher.prototype.getPlaylistSongs = function(playlist) {
var dependencies = this.dependencies;
var q = dependencies.q;
var rootScope = dependencies.rootScope;
var httpService = dependencies.httpService;
var defered = q.defer();
var promise = defered.promise;
//-----------------First request-----------------
var apiKey = this.configuration.api_key;
var urlRequest = 'https://www.googleapis.com/youtube/v3/playlistItems?part=contentDetails&playlistId=' + playlist.source_id + '&maxResults=50&key=' + apiKey;
var errorCallback = function(data) {
var message = 'GENERAL_ERROR';
if (data.status === 0) {
message = 'NETWORK_ERROR';
}
rootScope.$broadcast('getPlaylistSongs', new RequestResponse('Error', message, {
playlist: playlist
}));
};
var successCallback = function(data) {
var songsId = YoutubeSearcher.prototype.getResourcesIdFromYoutubeResponse(data.data.items, 'get-playlist-songs');
if (songsId === '') {
rootScope.$broadcast('getPlaylistSongs', new RequestResponse('Error', 'PLAYLIST_SONGS_NOT_FOUND', {
playlist: playlist
}));
} else {
defered.resolve(songsId);
}
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
//-----------------Second request-----------------
var resolveCallback = function(songsId) {
urlRequest = 'https://www.googleapis.com/youtube/v3/videos?videoEmbeddable=true&part=snippet%2C+contentDetails&id=' + songsId + '&key=' + apiKey;
var successCallback = function(data) {
var songsList = YoutubeSearcher.prototype.getSongsListFromYoutubeResponse(data.data.items, dependencies);
var response = {
playlist: playlist,
songs: songsList
};
if (songsList.size() === 0) {
response = new RequestResponse('Error', 'PLAYLIST_SONGS_NOT_FOUND', response);
} else {
response = new RequestResponse('Success', '', response);
}
rootScope.$broadcast('getPlaylistSongs', response);
};
httpService.get(urlRequest, {}, successCallback, errorCallback);
};
promise.then(resolveCallback);
};
YoutubeSearcher.prototype.getResourcesIdFromYoutubeResponse = function(items, source) {
var resourcesId = '';
var numberSongs = items.length;
if (numberSongs > 0) {
var i;
if (source === 'suggested-songs') {
numberSongs = (numberSongs > 5 ? 5 : numberSongs);
}
if (source === 'searches-songs' || source === 'suggested-songs') {
for (i = 0; i < numberSongs; i++) {
resourcesId += items[i].id.videoId + ',';
}
} else if (source === 'searches-playlists') {
for (i = 0; i < numberSongs; i++) {
resourcesId += items[i].id.playlistId + ',';
}
} else if (source === 'get-playlist-songs') {
for (i = 0; i < numberSongs; i++) {
resourcesId += items[i].contentDetails.videoId + ',';
}
}
resourcesId = resourcesId.substring(0, resourcesId.length - 1);
}
return resourcesId;
};
YoutubeSearcher.prototype.getSongsListFromYoutubeResponse = function(items, dependencies, getStatistics) {
var maxDurationSongs = dependencies.maxDurationSongs;
var blacklistConfig = {};
var songsList = new List();
var numberSongs = items.length;
if (dependencies.rootScope.blacklistConfig) {
blacklistConfig = dependencies.rootScope.blacklistConfig;
}
for (var i = 0; i < numberSongs; i++) {
var item = items[i];
var song = new Song();
song.source = 'Youtube';
song.source_id = item.id;
song.thumbnail = item.snippet.thumbnails && item.snippet.thumbnails.medium ? item.snippet.thumbnails.medium.url : 'https://i.ytimg.com/vi/6F4BU6OakHY/mqdefault.jpg';
song.title = item.snippet.title;
var blackListValidation = blacklistConfig.is_enabled && blacklistConfig.words !== '' ? SongUtilities.areKeywordsContainedInTitle(song.title, blacklistConfig.words) : false;
if (song.title.toLowerCase().indexOf('cover') !== -1 || song.title.toLowerCase().indexOf('tutorial') !== -1 || blackListValidation) {
continue;
}
if (item.snippet.categoryId === '10') {
var duration = item.contentDetails.duration;
duration = SongUtilities.normalizeDuration(duration, maxDurationSongs);
if (duration !== null) {
song.duration = duration;
if (getStatistics) {
if (item.statistics && item.statistics.viewCount) {
song.views = parseInt(item.statistics.viewCount);
} else {
song.views = numberSongs - i;
}
}
songsList.add(song);
}
}
}
return songsList;
};
return YoutubeSearcher;
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment