Роздрукувати список відтворення з Google Play Music


43

Я хочу надрукувати список пісень (із виконавцем, альбомом, рейтингом та, якщо можливо, кількістю відтворень та тривалістю) з мого облікового запису Google Play Music .

Простий спосіб зробити це з програми не існує. Робити екрани друку, коли я переглядаю довгий список пісень, не піддаються.

Я був би задоволений експортом даних у стандартний формат (звичайний текст, CSV, XML тощо), яким я можу маніпулювати собою.

Будь-які пропозиції?


Відповіді:


17

Змінюючи відповідь darkliquid , я придумав таке, що дозволяє зберегти декілька списків відтворення відразу .

Інструкції:

  1. Перейдіть на сторінку Ваших списків відтворення .
  2. Вставте код JavaScript нижче в консоль.
  3. Клацніть на списку відтворення, який потрібно зберегти в тексті.
  4. Опинившись на сторінці списку відтворення, прокрутіть донизу відносно повільно.
  5. Після прокрутки вниз, поверніться до сторінки списків відтворення (так само, як на кроці 1.) за допомогою меню або кнопки повернення браузера.
  6. Повторіть кроки 3-5 для всіх списків відтворення, які ви хочете зберегти в тексті.
  7. Щойно ви зробите це для всіх списків відтворення, які ви хочете зберегти в тексті, ви можете або ввести JSON.stringify(tracklistObj, null, '\t')(змінити '\t'на, ' 'якщо ви хочете мінімального відступу), або tracklistObjякщо ви просто хочете, щоб об’єкт JavaScript маніпулював ним по-своєму. Якщо ви хочете його сортувати, запустіть команду Object.values(tracklistObj).forEach(a => a.sort()) перед тим, як викликати JSON.stringifyкоманду.

Будьте обережні, щоб не оновити сторінку до того, як ви завершите все, що хочете зробити, інакше доведеться перезапустити з кроку 1.

// Setup
var tracklistObj = {},
    currentPlaylist,
    checkIntervalTime = 100,
    lastTime;

// Process the visible tracks
function getVisibleTracks() {
    var playlist = document.querySelectorAll('.song-table tr.song-row');
    for(var i = 0; i < playlist.length ; i++) { 
        var l = playlist[i];

        var title = l.querySelector('td[data-col="title"] .column-content');
        if(title !== null)
            title = title.textContent;

        var artist = l.querySelector('td[data-col="artist"] .column-content');
        if(artist !== null)
            artist = artist.textContent;

        var duration = l.querySelector('td[data-col="duration"] span');
        if(duration !== null)
            duration = duration.textContent;

        var album = l.querySelector('td[data-col="album"] .column-content');
        if(album !== null)
            album = album.textContent;

        var playCount = l.querySelector('td[data-col="play-count"] span');
        if(playCount !== null)
            playCount = playCount.textContent;

        var rating = l.querySelector('td[data-col="rating"]');
        if(rating !== null)
            rating = rating.textContent;

        // Add it if it doesn't exist already
        if(tracklistObj[currentPlaylist] && !tracklistObj[currentPlaylist].includes(artist + " - " + title)) {
            tracklistObj[currentPlaylist].push(artist + " - " + title);

            if(printTracksToConsole) {
                console.log(artist + ' - ' + title);
            }
        }
    }
}

// Listen for page changes
window.onhashchange = function(e) {
    currentPlaylist = null; 

    var doneLoading = setInterval(function() {
        var playListName = document.querySelector('.gpm-detail-page-header h2[slot="title"]');
        if(playListName != null) {
            currentPlaylist = playListName.innerText;
            if(tracklistObj[currentPlaylist] === undefined) {
                tracklistObj[currentPlaylist] = [];
            }

            console.log("===================================");
            console.log("Adding to playlist " + currentPlaylist);

            getVisibleTracks();

            clearInterval(doneLoading);
        }
    }, 100);

}

// Check for new tracks every so often
setInterval(function() {
    getVisibleTracks();
}, checkIntervalTime);

// Whether or not to print the tracks obtained to the console
var printTracksToConsole = false;

Ви також можете надрукувати на консолі імена доріжок, переходячи до пункту ( перейдіть printTracksToConsoleдо цього true(слід зробити це до кроку 3).

Зауважте, що, ймовірно, ви можете ігнорувати всі помилки GET і POST в консолі (вони генеруються самим Play Music, а не цим сценарієм).

Також відзначимо , що в даний час це установка тільки дати Artist - Track name, але ви можете легко змінити рядок , яка має tracklistObj[currentPlaylist].push(artist + " - " + title);з album, playCount, durationабо rating, і / або будь-який інший форматуванням ви хочете (включаючи формат CSV , якщо ви так , будь ласка).

Приклад виводу (усі списки відтворення в Google Play, які я зараз маю) із налаштуваннями за замовчуванням. Щоб перейти до кожного з 32 списків відтворення, прокрутити їх вниз, а потім перетворити результат у текст, знадобилося приблизно 5 хвилин.

PS Можливо, вам буде цікаво використовувати сайт, який я знайшов під назвою Tune My Music, щоб створювати списки відтворення YouTube (але YouTube обмежує створення списків відтворення до 10 на день), щоб ваші друзі могли слухати ваші списки відтворення Google. Якщо ви це зробите, ви, ймовірно, хочете використовувати щось на зразок TextMechanic для видалення лапок і .mp3зі списку, що виводиться.


1
Якби тільки був кращий спосіб зробити це, ніж вставити JavaScript в консоль. (У мене також було трохи гикавки, оскільки Ublock Origin заблокував сценарій.) Але це робить все, що мені потрібно.
але

Я боюся, що він застарів зараз :( TypeError: Неможливо прочитати властивість "включає" невизначений на getVisibleTracks (<анонімний>: 20: 43) в <anonymous>: 49: 5 в c ( play-music.gstatic.com/ fe / 6..e / прослухати__en_gb.js: 1190: 211 )
FloriOn

4
@FloriOn Дякую за коментар! Я оновив код, щоб він знову працював.
Зак Сосьє

2
@ale Є. Ви можете перетворити код у закладку.
Девід Меткалф

Помилки консолі з’являються під час запуску цього коду, але він, схоже, не блокує його запуск
Отей

31

(Оновлено 09.05.2016, надійніше, ніж поточна відповідь)

Якщо вам просто потрібно зберегти кілька списків відтворення, ви можете просто скористатися моїм фрагментом Javascript нижче. Цей фрагмент може зберегти кожен список, як його відображено на веб-сторінці, тому він також працює для всіх переглядів пісень / альбомів / виконавців у бібліотеці. Я перерахував ще два варіанти в кінці цієї відповіді.

  1. Перейдіть на сторінку: https://play.google.com/music/listen#/all (або ваш список відтворення)

  2. Відкрийте консоль розробника (F12 для Chrome). Вставте код нижче в консоль.

  3. Усі скребковані пісні зберігаються в allsongsоб’єкті, а текстова версія списку копіюється у буфер обміну. Рекомендую songsToText("all",true)після цього запустити повну інформацію про CSV. Запустити copy(outText)вручну, якщо копіювання буфера обміну не спрацювало з першої спроби.

Код (остання версія 10 травня 2016 р., Rev 30):

var allsongs = []
var outText = "";
var songsToText = function(style, csv, likedonly){
  if (style === undefined){
    console.log("style is undefined.");
    return;
  }
  var csv = csv || false; // defaults to false
  var likedonly = likedonly || false; // defaults to false
  if (likedonly) {
    console.log("Only selecting liked songs");
  }
  if (style == "all" && !csv){
    console.log("Duration, ratings, and playcount will only be exported with the CSV flag");
  }
  outText = "";
  if (csv) {
    if (style == "all") {
      //extra line
      outText = "artist,album,title,duration,playcount,rating,rating_interpretation" + "\n";
    } else if (style == "artist") {
    } else if (style == "artistsong") {
    } else if (style == "artistalbum") {
    } else if (style == "artistalbumsong") {
    } else {
      console.log("style not defined");
    }
  }
  var numEntries = 0;
  var seen = {};
  for (var i = 0; i < allsongs.length; i++) {
    var curr = "";
    var properTitle = allsongs[i].title.replace(/[\n\r!]/g, '').trim();
    if (!likedonly || (likedonly && allsongs[i].rating >= 5)){
      if (csv) {
        if (style == "all") {
          //extra line
          curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].album.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + properTitle.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].duration.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].playcount.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].rating.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].rating_interpretation.replace(/"/g, '""').trim() + '"';
        } else if (style == "artist") {
          curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"';
        } else if (style == "artistsong") {
          curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + properTitle.replace(/"/g, '""').trim() + '"';
        } else if (style == "artistalbum") {
          curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].album.replace(/"/g, '""').trim() + '"';
        } else if (style == "artistalbumsong") {
          curr += '"' + allsongs[i].artist.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + allsongs[i].album.replace(/"/g, '""').trim() + '"' + ",";
          curr += '"' + properTitle.replace(/"/g, '""').trim() + '"';
        } else {
          console.log("style not defined");
        }
      } else {
        if (style == "all"){
          curr = allsongs[i].artist + " - " + allsongs[i].album + " - " + properTitle + " [[playcount: " + allsongs[i].playcount + ", rating: " + allsongs[i].rating_interpretation + "]]" ;
        } else if (style == "artist"){
          curr = allsongs[i].artist;
        } else if (style == "artistalbum"){
          curr = allsongs[i].artist + " - " + allsongs[i].album;
        } else if (style == "artistsong"){
          curr = allsongs[i].artist + " - " + properTitle;
        } else if (style == "artistalbumsong"){
          curr = allsongs[i].artist + " - " + allsongs[i].album + " - " + properTitle;
        } else {
          console.log("style not defined");
        }
      }
      if (!seen.hasOwnProperty(curr)){ // hashset
        outText = outText + curr + "\n";
        numEntries++;
        seen[curr] = true;
      } else {
        //console.log("Skipping (duplicate) " + curr);
      }
    }
  }
  console.log("=============================================================");
  console.log(outText);
  console.log("=============================================================");
  try {
    copy(outText);
    console.log("copy(outText) to clipboard succeeded.");
  } catch (e) {
    console.log(e);
    console.log("copy(outText) to clipboard failed, please type copy(outText) on the console or copy the log output above.");
  }
  console.log("Done! " + numEntries + " lines in output. Used " + numEntries + " unique entries out of " + allsongs.length + ".");
};
var scrapeSongs = function(){
  var intervalms = 1; //in ms
  var timeoutms = 3000; //in ms
  var retries = timeoutms / intervalms;
  var total = [];
  var seen = {};
  var topId = "";
  document.querySelector("#mainContainer").scrollTop = 0; //scroll to top
  var interval = setInterval(function(){
    var songs = document.querySelectorAll("table.song-table tbody tr.song-row");
    if (songs.length > 0) {
      // detect order
      var colNames = {
        index: -1,
        title: -1,
        duration: -1,
        artist: -1,
        album: -1,
        playcount: -1,
        rating: -1
        };
      for (var i = 0; i < songs[0].childNodes.length; i++) {
        colNames.index = songs[0].childNodes[i].getAttribute("data-col") == "index" ? i : colNames.index;
        colNames.title = songs[0].childNodes[i].getAttribute("data-col") == "title" ? i : colNames.title;
        colNames.duration = songs[0].childNodes[i].getAttribute("data-col") == "duration" ? i : colNames.duration;
        colNames.artist = songs[0].childNodes[i].getAttribute("data-col") == "artist" ? i : colNames.artist;
        colNames.album = songs[0].childNodes[i].getAttribute("data-col") == "album" ? i : colNames.album;
        colNames.playcount = songs[0].childNodes[i].getAttribute("data-col") == "play-count" ? i : colNames.playcount;
        colNames.rating = songs[0].childNodes[i].getAttribute("data-col") == "rating" ? i : colNames.rating;
      }
      // check if page has updated/scrolled
      var currId = songs[0].getAttribute("data-id");
      if (currId == topId){ // page has not yet changed
        retries--;
        scrollDiv = document.querySelector("#mainContainer");
        isAtBottom = scrollDiv.scrollTop == (scrollDiv.scrollHeight - scrollDiv.offsetHeight)
        if (isAtBottom || retries <= 0) {
          clearInterval(interval); //done
          allsongs = total;
          console.log("Got " + total.length + " songs and stored them in the allsongs variable.");
          console.log("Calling songsToText with style all, csv flag true, likedonly false: songsToText(\"all\", false).");
          songsToText("artistalbumsong", false, false);
        }
      } else {
        retries = timeoutms / intervalms;
        topId = currId;
        // read page
        for (var i = 0; i < songs.length; i++) {
          var curr = {
            dataid: songs[i].getAttribute("data-id"),
            index: (colNames.index != -1 ? songs[i].childNodes[colNames.index].textContent : ""),
            title: (colNames.title != -1 ? songs[i].childNodes[colNames.title].textContent : ""),
            duration: (colNames.duration != -1 ? songs[i].childNodes[colNames.duration].textContent : ""),
            artist: (colNames.artist != -1 ? songs[i].childNodes[colNames.artist].textContent : ""),
            album: (colNames.album != -1 ? songs[i].childNodes[colNames.album].textContent : ""),
            playcount: (colNames.playcount != -1 ? songs[i].childNodes[colNames.playcount].textContent : ""),
            rating: (colNames.rating != -1 ? songs[i].childNodes[colNames.rating].getAttribute("data-rating") : ""),
            rating_interpretation: "",
            }
          if(curr.rating == "undefined") {
            curr.rating_interpretation = "never-rated"
          }
          if(curr.rating == "0") {
            curr.rating_interpretation = "not-rated"
          }
          if(curr.rating == "1") {
            curr.rating_interpretation = "thumbs-down"
          }
          if(curr.rating == "5") {
            curr.rating_interpretation = "thumbs-up"
          }
          if (!seen.hasOwnProperty(curr.dataid)){ // hashset
            total.push(curr);
            seen[curr.dataid] = true;
          }
        }
        songs[songs.length-1].scrollIntoView(true); // go to next page
      }
    }
  }, intervalms);
};
scrapeSongs();
// for the full CSV version you can now call songsToText("all", true);

Останній код на Github (Gist) тут: https://gist.github.com/jmiserez/c9a9a0f41e867e5ebb75

  • Якщо ви хочете, щоб вихід був у текстовому форматі, можете зателефонувати на функцію songsToText (). Ви можете вибрати стиль, вибрати формат, і якщо потрібно експортувати лише вподобані / обдумані пісні. Потім отриманий список буде вставлений у буфер обміну. Стилі all, artist, artistalbum, artistsong, artistalbumsong. CSV призведе до файлу CSV і його можна буде залишити (за замовчуванням до значення false). Likedonly може бути залишений (за замовчуванням до false) або встановлено значення true, і буде фільтрувати всі пісні з рейтингами, більшими або рівними 5. Наприклад:

    • songsToText("all",true,false) експортує всі пісні у форматі CSV.
    • songsToText("all",true,true) експортуватиме лише улюблені пісні у форматі csv.
    • songsToText("artistsong",false,false) експортує всі пісні як текст.
  • Потім ви можете вставити дані куди завгодно, наприклад, http://www.ivyishere.org/, якщо ви хочете додати пісні або альбоми до свого облікового запису Spotify. Щоб Ivy розпізнав цілі альбоми, використовуйте стиль "artistalbum". Для пісень використовуйте стиль "виконавців".

Про фрагмент: Це засновано на оригінальній відповіді Майкла Сміта, але є трохи більш надійною. Я вніс такі вдосконалення:

  • Працює в списках відтворення, а також у бібліотеці. Будь-які стовпці, що відсутні, ігноруються, і порядок з’ясовується, тому він повинен працювати майже на будь-якому списку пісень у Google Music.

  • Він зупиняється або після досягнення нижньої частини (виявляє положення прокрутки), або після вказаного часу. Час очікування є для запобігання нескінченного циклу у випадку, якщо код виявлення прокрутки вимкнений на кілька пікселів.

  • Це набагато швидше (інтервал кожні 1 мс), але чекає, якщо дані не будуть готові (до вказаного часу, в даний час 3 секунди).

  • Робить дедуплікацію під час роботи та на виході.

  • Збирає рейтинги: "невизначений" ніколи не оцінюється, "0" не оцінюється (тобто один раз оцінюється, а потім видаляється), "1" є великими пальцями вниз, а "5" - великими пальцями вгору (подобається).

Окрім основних вдосконалень, він також добре форматує текст і копіює його у буфер обміну. Ви також можете отримати дані як CSV, якщо бажаєте, запустивши songsToTextфункцію вдруге.

Альтернативи:

  1. Якщо вам потрібен API Python, перегляньте неофіційний проект Google Music API .

  2. Якщо у вас є багато списків відтворення, і ви хочете експортувати їх за один раз, спробуйте експортер плейлистів gmusic-script, який може це зробити (Python, використовує неофіційний проект API).


Гей, лише подальший допис за кодом: в результаті копіюються лише останні 30 пісень, а коли я виконую пісніToText ("виконавці"), він виводить довжину в хвилинах: секундах та номер треку в списку відтворення. подробиці пісні все-таки є у всіх співах, але їх лише 30 (у мене плейлисти із сотнями)
mkln

ніколи не пам’ятайте про кількість пісень, вона не застрягла на 30. Але в іншому плейлисті зі 130 піснями експортується лише перші 117.
mkln

@mkln Я оновив код, тепер він обробляє бібліотеку, списки відтворення, а також усі інші списки пісень у Google Music. Просто запустіть усе, і він скопіює список відтворення / бібліотеку / список як список тексту у буфер обміну. Якщо вам потрібна версія CSV, яка включає все (кількість відтворень, тривалість, рейтинг), запустіть songsToText("all", true)потім.
jmiserez

це чудово працює, дякую. Я намагаюся написати сценарій пітона, який зберігає всі списки відтворення. як би ви натискали на різні списки відтворення через javascript? чи можна було мати селектор списку відтворення на початку функції?
mkln

1
@mkln Ну, цей хлопець вже зробив це: github.com/soulfx/gmusic-playlist Напевно, найпростіше, якщо ви просто використовуєте його сценарій Python! Я, чесно кажучи, досі цього не бачив, але, мабуть, кращий варіант, якщо вам потрібно більше одного списку відтворення.
jmiserez

18

Якщо ви не заперечуєте, щоб у консолі розробника браузера було трохи коду javascript, ви можете витягнути інформацію зі сторінки на зразок такої (лише перевірена в Chrome):

var playlist = document.querySelectorAll('.song-table tr.song-row');
for(var i =0; i<playlist.length ; i++) { 
  var l = playlist[i]; 
  var title = l.querySelector('td[data-col="title"] .column-content').textContent;
  var artist = l.querySelector('td[data-col="artist"] .column-content').textContent;
  var album = l.querySelector('td[data-col="album"] .column-content').textContent;
  console.log(artist + ' --- ' + title + ' --- ' + album); 
}

Це дозволить роздрукувати на консолі список більшості пісень, які зараз бачать у вікні. Вам потрібно буде прокрутити вниз і повторно запустити його, щоб отримати більше. Наразі я ще не придумав гідного способу захоплення інформації в повному обсязі, але цей швидкий 5-хвилинний злом кращий, ніж нічого.


Це виглядає перспективно. Я піду.
але

2
Дякую ТАК велике за цю відповідь. Ти врятував мені години та години. Що я зробив, це запускати ваш сценарій знову і знову в списку відтворення, який я хотів скопіювати. Вставте результати у програму Mac під назвою Text Soap. Перетворився в ",". Видалено дублікати та експортується у вигляді txt. Потім змінив його на CSV, викреслив необрізані стовпці та імпортував їх у Spotify за допомогою: ivyishere.org Всього зайняв у мене близько 8 хвилин, я отримав повісити,

Без проблем, із задоволенням допоможу.
темна рідина

Це схоже, що це зробить трюк. Моя найбільша проблема - розмір моїх списків відтворення - 180 у тому, що я намагаюся експортувати. Я трохи подолав це, збільшивши вікно Chrome, а потім зменшив масштаб, наскільки міг. Якби я міг просто переконати Chrome в масштабі на 10%, я мав би це все на одному екрані ... на 25%, це знадобилося два раунди плюс трохи більше. (У вас є можливість збільшити масштаб із JS?)
RobertB

1
FYI, якщо ви лише один елемент, використовуйте querySelector(...)замістьquerySelectorAll(...)[0]
ThiefMaster

3

Використовуючи верхню відповідь (на той час) і бажаючи повного рішення, я створив наступний код, який прокручує список музики і додає об’єкти JSON до масиву, як йде.

Через те, що не знають, які саме пісні видно, код додає їх усі, а потім наприкінці дедублює. (Тестується лише в Chrome.)

Для використання: перейдіть до своєї бібліотеки, де ви бачите повний список пісень, і запустіть

var total = [];
var interval = setInterval(function(){
    var songs = document.querySelectorAll("table.song-table tbody tr.song-row");
    for (var i = 0; i < songs.length; i++) {
        total.push({name: songs[i].childNodes[0].textContent,
        length: songs[i].childNodes[1].textContent,
        artist: songs[i].childNodes[2].textContent,
        album: songs[i].childNodes[3].textContent,
        plays: songs[i].childNodes[4].textContent
        });
        songs[i].scrollIntoView(true);
    }
}, 800);

Коли це потрапить у нижню частину сторінки, запустіть це, щоб зупинити прокрутку, дедублювати масив та скопіювати JSON у буфер обміну.

clearInterval(interval);
for (var i = 0; i < total.length; i++) {
    for (var j = i + 1; j < total.length; j++) {
        if (total.hasOwnProperty(i) && total.hasOwnProperty(j) && total[i].name == total[j].name && total[j].artist == total[i].artist) {
            total.splice(j,1);
        }
    }
}
copy(total);

3

У мене є набагато коротший JavaScript, який ви можете вставити в консоль. Замість повторного запуску коду ви можете просто прокрутити вниз, і всі альбоми, які переглядаються, додаються. Потім ви можете завантажити список відтворення у вигляді електронної таблиці.

Інструкції

  1. Перейдіть сюди: https://play.google.com/music/listen#/ap/auto-playlist-thumbs-up

  2. Відкрийте Інструменти для розробників (F12) та вставте код нижче на вкладку Консоль

  3. Прокрутіть, щоб кожен альбом у списку відтворення був видно хоча б раз

  4. Двічі клацніть десь на сторінці для завантаження export-google-play.csv

  5. Відкрити export-google-play.csvв Excel.

Код

alert("Please scroll through the playlist so that each album is visible once.\n" + 
      "Then double-click the page to export a spreadsheet.");
var albums = ["Artist,Album,Purchased"];

var addVisibleAlbums = function(){
    [].forEach.call(document.querySelectorAll(".song-row"), function(e){ 
        var albumNodes = [e.querySelector("td[data-col='artist']"), 
              e.querySelector("td[data-col='album']"),
              e.querySelector("td[data-col='title'] .title-right-items")];

        var albumString = albumNodes.map(function(s){ 
            return s.innerText.trim().replace(/,/g,""); 
        }).join(",");

        if(albums.indexOf(albumString) === -1){
            albums.push(albumString); console.log("Added: " + albumString)
        }
    });
}

var createCsv = function(){
    var csv = "data:text/csv;charset=utf-8,";
    albums.forEach(function(row){ csv += row + "\n"; }); 

    var uri = encodeURI(csv);
    var link = document.createElement("a");
    link.setAttribute("href", uri);
    link.setAttribute("download", "export-google-play.csv");
    document.body.appendChild(link);
    link.click(); 
    alert("Download beginning!")
}

document.body.addEventListener("DOMNodeInserted", addVisibleAlbums, false);
document.body.addEventListener("dblclick", createCsv, false);

Вихідні дані

введіть тут опис зображення

GitHub


2

Я трохи змінив підхід верхньої відповіді. Для мене це краще працювало методом копіювання / вставки Ivy ( http://www.ivyishere.org/ivy ):

Крок 1. Відкрийте потрібний список відтворення з Google Music в Chrome і вставте його в консоль:

document.querySelector('body.material').style.height = (document.querySelector('table.song-table tbody').getAttribute('data-count') * 100) + 'px';

Це має спричинити показ всього списку відтворення, а не лише його частину.

Крок 2 Вставте цей скрипт у консоль:

var i, j, playlistString = '', playlist = document.querySelectorAll('.song-table tr.song-row');
for (i = 0, j = playlist.length; i < j; i++) {
    var track = playlist[i]; 
    var artist = track.querySelector('[href][aria-label]').textContent;
    var title = track.querySelector('td[data-col="title"]').textContent;
    playlistString += ('"' + artist + '", "' + title + '"\n');
}
console.log(playlistString);

Крок 3 Перейдіть до Ivy і, перейшовши на крок 2 там, виберіть вкладку Copy / Paste Copy / Paste та вставте туди консольний вихід.

EDIT

Оновлений сценарій, запропонований Алексом Педерсеном

Поміркувавши над вишуканістю самурауретицьких (я ще не маю достатньо репутації, щоб коментувати його повідомлення). Я думаю, що стиль Googleplay оновився, тому сценарій нижче знову дає неабиякі результати.

var i, j, playlistString = '', playlist = document.querySelectorAll('.song-table tr.song-row');
for (i = 0, j = playlist.length; i < j; i++) {
    var track = playlist[i]; 
    var artist = track.querySelector('[href][aria-label]').textContent;
    var title = track.querySelector('span[class="column-content fade-out tooltip"]').textContent;
    playlistString += ('"' + artist + '", "' + title + '"\n');
}
console.log(playlistString);


-2

Я просто натрапив на це питання, шукаючи щось подібне.

Я думаю, ваш найкращий варіант:

  1. встановіть додаток на кшталт "Резервне копіювання списку відтворення"
  2. Експортуйте список відтворення музики Google до текстового файлу за допомогою цієї програми.
  3. Перейменуйте його на .m3u за допомогою програми FileManager (наприклад, Ghost Commander)
  4. Відкрийте список відтворення за допомогою іншого додатка, який має більше можливостей (наприклад, MusiXMatch).

1
Я припускаю, що ви маєте на увазі це додаток . Не добре. Хоча у мене є пристрій Android, я не шукаю рішення для Android. Крім того, я спробував це додаток, і він не може експортувати дані про доріжки, які відсутні на пристрої, тому мені це марно.
але

1
Олівер, будучи веб-додатками, ми віддаємо перевагу відповідям, які не потребують нативних програм.
Відар С. Рамдал
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.