Created
June 18, 2025 19:56
-
-
Save serg-yalosovetsky/8c48dce622476a559003c1e2ef2c393f to your computer and use it in GitHub Desktop.
function to copy from yt songs that i liked to my own liked playlist, to be able to download whole playlist
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /** Кладёт все лайкнутые видео (до 5k) в указанный плейлист. */ | |
| function addLikedVideosToPlaylist() { | |
| const targetPlaylistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; // куда кладём | |
| const likesPlaylistId = 'LL'; // системный плейлист «Liked videos» | |
| // 1. соберём уже лежащие в целевом плейлисте | |
| const inPlaylist = new Set(getExistingVideos(targetPlaylistId)); | |
| let next = ''; | |
| let checked = 0, added = 0; | |
| do { | |
| const resp = YouTube.PlaylistItems.list('contentDetails', { | |
| playlistId: likesPlaylistId, | |
| maxResults: 50, | |
| pageToken: next, | |
| }); | |
| if (!resp.items || !resp.items.length) break; | |
| for (const item of resp.items) { | |
| checked++; | |
| const vid = item.contentDetails.videoId; | |
| if (inPlaylist.has(vid)) continue; // уже там | |
| try { | |
| YouTube.PlaylistItems.insert({ | |
| snippet: { | |
| playlistId: targetPlaylistId, | |
| resourceId: { kind: 'youtube#video', videoId: vid } | |
| } | |
| }, 'snippet'); | |
| inPlaylist.add(vid); | |
| added++; | |
| } catch (e) { | |
| Logger.log(`! ошибка при добавлении ${vid}: ${e.message}`); | |
| } | |
| } | |
| next = resp.nextPageToken; | |
| } while (next); | |
| Logger.log(`Проверено: ${checked}, добавлено: ${added}`); | |
| } | |
| /** Возвращает id всех видео из плейлиста. */ | |
| function getExistingVideos(playlistId) { | |
| const ids = []; | |
| let next = ''; | |
| do { | |
| const resp = YouTube.PlaylistItems.list('snippet', { | |
| playlistId, | |
| maxResults: 50, | |
| pageToken: next, | |
| }); | |
| if (!resp.items) break; | |
| resp.items.forEach(it => ids.push(it.snippet.resourceId.videoId)); | |
| next = resp.nextPageToken; | |
| } while (next); | |
| return ids; | |
| } | |
| /** Добавляет ВСЕ понравившиеся видео (от новых к старым) в указанный плейлист. */ | |
| function addLikedVideosToPlaylistOld() { | |
| const playlistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; | |
| // ----------- соберём id уже лежащих в плейлисте ----------- | |
| const inPlaylist = new Set(getExistingVideos(playlistId)); | |
| let nextPageToken = ''; | |
| let added = 0, checked = 0; | |
| do { | |
| const resp = YouTube.Videos.list('snippet', { | |
| myRating: 'like', | |
| maxResults: 50, | |
| pageToken: nextPageToken, | |
| }); | |
| if (!resp.items || !resp.items.length) break; // лайков больше нет | |
| for (const v of resp.items) { | |
| checked++; | |
| const id = v.id; | |
| if (inPlaylist.has(id)) { // уже лежит | |
| Logger.log(`⇢ ${id} уже в плейлисте (пропускаю)`); | |
| continue; | |
| } | |
| try { | |
| YouTube.PlaylistItems.insert({ | |
| snippet: { | |
| playlistId: playlistId, | |
| resourceId: { kind: 'youtube#video', videoId: id } | |
| } | |
| }, 'snippet'); | |
| inPlaylist.add(id); | |
| added++; | |
| Logger.log(`+ добавлено ${id}`); | |
| } catch (e) { | |
| Logger.log(`! ошибка при добавлении ${id}: ${e.message}`); | |
| } | |
| } | |
| nextPageToken = resp.nextPageToken; | |
| } while (nextPageToken); | |
| Logger.log(`Проверено: ${checked}, добавлено: ${added}`); | |
| } | |
| /** Возвращает массив id всех видео из плейлиста. */ | |
| function getExistingVideosOld(playlistId) { | |
| const ids = []; | |
| let page = ''; | |
| do { | |
| const resp = YouTube.PlaylistItems.list('snippet', { | |
| playlistId, | |
| maxResults: 50, | |
| pageToken: page, | |
| }); | |
| if (!resp.items) break; | |
| for (const it of resp.items) { | |
| ids.push(it.snippet.resourceId.videoId); | |
| } | |
| page = resp.nextPageToken; | |
| } while (page); | |
| return ids; | |
| } | |
| /** Удаляет дубликаты внутри плейлиста (на всякий случай). */ | |
| function removeDuplicatesFromPlaylist() { | |
| const playlistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; | |
| const seen = new Set(); | |
| const toDelete = []; | |
| let page = ''; | |
| do { | |
| const resp = YouTube.PlaylistItems.list('snippet', { | |
| playlistId, | |
| maxResults: 50, | |
| pageToken: page, | |
| }); | |
| if (!resp.items) break; | |
| for (const it of resp.items) { | |
| const id = it.snippet.resourceId.videoId; | |
| if (seen.has(id)) { | |
| toDelete.push(it.id); // дубликат | |
| } else { | |
| seen.add(id); | |
| } | |
| } | |
| page = resp.nextPageToken; | |
| } while (page); | |
| for (const itemId of toDelete) { | |
| try { | |
| YouTube.PlaylistItems.remove(itemId); | |
| Logger.log(`- удалён дубликат ${itemId}`); | |
| } catch (e) { | |
| Logger.log(`! ошибка при удалении ${itemId}: ${e.message}`); | |
| } | |
| } | |
| Logger.log(`Всего удалено дубликатов: ${toDelete.length}`); | |
| } | |
| function addLikedVideosToPlaylistOldOld(skipCount = 900) { | |
| var playlistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; | |
| var nextPageToken = ''; | |
| var processedCount = 0; | |
| // Получаем все видео, уже находящиеся в плейлисте | |
| var existingVideos = getExistingVideosOld(playlistId); | |
| do { | |
| var likedVideos = YouTube.Videos.list('snippet', { | |
| myRating: 'like', | |
| maxResults: 50, | |
| pageToken: nextPageToken | |
| }); | |
| for (var i = 0; i < likedVideos.items.length; i++) { | |
| processedCount++; | |
| if (processedCount <= skipCount) { | |
| continue; | |
| } | |
| var videoId = likedVideos.items[i].id; | |
| // Проверяем, есть ли видео уже в плейлисте | |
| if (!existingVideos.includes(videoId)) { | |
| try { | |
| YouTube.PlaylistItems.insert( | |
| { | |
| snippet: { | |
| playlistId: playlistId, | |
| resourceId: { | |
| kind: 'youtube#video', | |
| videoId: videoId | |
| } | |
| } | |
| }, | |
| 'snippet' | |
| ); | |
| Logger.log('Добавлено видео #' + processedCount + ': ' + videoId); | |
| } catch (e) { | |
| Logger.log('Ошибка при добавлении видео ' + videoId + ': ' + e.message); | |
| } | |
| } else { | |
| Logger.log('Видео ' + videoId + ' уже существует в плейлисте'); | |
| } | |
| } | |
| nextPageToken = likedVideos.nextPageToken; | |
| } while (nextPageToken); | |
| Logger.log('Всего обработано видео: ' + processedCount); | |
| } | |
| // Функция для получения всех видео, уже находящихся в плейлисте | |
| function getExistingVideosOldOld(playlistId) { | |
| var existingVideos = []; | |
| var nextPageToken = ''; | |
| if (!playlistId) { | |
| playlistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; | |
| } | |
| do { | |
| var playlistItems = YouTube.PlaylistItems.list('snippet', { | |
| playlistId: playlistId, | |
| maxResults: 50, | |
| pageToken: nextPageToken | |
| }); | |
| for (var i = 0; i < playlistItems.items.length; i++) { | |
| existingVideos.push(playlistItems.items[i].snippet.resourceId.videoId); | |
| } | |
| nextPageToken = playlistItems.nextPageToken; | |
| } while (nextPageToken); | |
| return existingVideos; | |
| } | |
| function removeDuplicatesFromPlaylistOld() { | |
| var playlistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; | |
| var existingVideos = {}; | |
| var itemsToDelete = []; | |
| var nextPageToken = ''; | |
| do { | |
| var playlistItems = YouTube.PlaylistItems.list('snippet', { | |
| playlistId: playlistId, | |
| maxResults: 50, | |
| pageToken: nextPageToken | |
| }); | |
| for (var i = 0; i < playlistItems.items.length; i++) { | |
| var item = playlistItems.items[i]; | |
| var videoId = item.snippet.resourceId.videoId; | |
| if (existingVideos[videoId]) { | |
| // Это дубликат, добавляем его ID в список для удаления | |
| itemsToDelete.push(item.id); | |
| } else { | |
| // Это первое появление видео, отмечаем его как существующее | |
| existingVideos[videoId] = true; | |
| } | |
| } | |
| nextPageToken = playlistItems.nextPageToken; | |
| } while (nextPageToken); | |
| // Удаляем дубликаты | |
| for (var j = 0; j < itemsToDelete.length; j++) { | |
| try { | |
| YouTube.PlaylistItems.remove(itemsToDelete[j]); | |
| Logger.log('Удален дубликат: ' + itemsToDelete[j]); | |
| } catch (e) { | |
| Logger.log('Ошибка при удалении дубликата ' + itemsToDelete[j] + ': ' + e.message); | |
| } | |
| } | |
| Logger.log('Всего удалено дубликатов: ' + itemsToDelete.length); | |
| } | |
| // Пример использования: | |
| // var playlistId = 'PLEJYPrcLjkrViJpaliSuODRtJC0ILQzSA'; | |
| // removeDuplicatesFromPlaylist(playlistId); | |
| // addLikedVideosToPlaylist(200); // Пропустить первые 200 видео |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment