Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save serg-yalosovetsky/8c48dce622476a559003c1e2ef2c393f to your computer and use it in GitHub Desktop.
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
/** Кладёт все лайкнутые видео (до 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