You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Наряду с задачей фильтрации по местоположению появился запрос на фильтр по языку. Сначала я подумал, что это невозможно. Потому что первым на ум приходит звук, волны, анализ. Одним словом дебри... Но ведь есть текст! С этим уже можно работать.
В качестве источника текстов выбрал musixmatch. Дает бесплатное API на 2 тысячи запросов в день с доступом к 30% текста от песни. Платная версия даже язык показывает. Но это не наш случай.
Как идентифицировать язык? Нужен переводчик. Он даже есть в Apps Script. Но не дает функции для получения языка, только перевод. Напрямую идти к API переводчика нельзя, потому что так или иначе придем к оплате. Есть интересный сервис DetectLanguage. Однако уже на первой тройке треков стало понятно, что качество идентификации очень низкое даже с английским языком. Локальные библиотеки тоже не подходят.
Apps Script не перестает меня удивлять. В Google Таблицах есть встроенная функция DETECTLANGUAGE, а Apps Script дает API для таблиц. Пазл сошелся.
Суммируем
Крупный источник текстов с лимитов 2 тысячи запросов в день
Нативная идентификация языка без дополнительных лимитов
Однако текст явно будет не у всех, имейте ввиду
Установка
Зайдите на сайт developer.musixmatch.com, чтобы зарегистрироваться и получить ключ. Телефон и адрес заполните произвольно (123 и World, к примеру). Почта реальная, попросит подтвердить.
После подтверждения почты зайдите в дэшборд приложений. Тут ключ, который понадобится дальше.
Скопируйте следующий код к себе в проект. Например, в файл addons. И подставьте ключ в константу MUSIXMATCH_API_KEY вместо 123.
functionmatchLanguage(tracks,params){constMUSIXMATCH_API_KEY='123';constFOLDER_NAME='Goofy Data';constrootFolder=getRootFolder(FOLDER_NAME);letisError=getLyrics();if(!isError){detectLanguage();match();}functionmatch(){Combiner.replace(tracks,tracks.filter(track=>{if(![undefined,'und','#ERROR!'].includes(track.lyrics.lang)){returnRangeTracks.isBelongGenres([track.lyrics.lang],params.include)&&!RangeTracks.isBelongBanGenres([track.lyrics.lang],params.exclude)}return!params.isRemoveUnknown;}));}functiongetLyrics(){consturl='https://api.musixmatch.com/ws/1.1/matcher.lyrics.get?';letunknownLyrics=tracks.filter(t=>!t.lyrics||!t.lyrics.lang);leturls=unknownLyrics.reduce((urls,track)=>{letqueryObj={q_track: track.name.formatName(),q_artist: track.artists[0].name.formatName(),apikey: MUSIXMATCH_API_KEY,}urls.push(url+CustomUrlFetchApp.parseQuery(queryObj));returnurls;},[]);returnCustomUrlFetchApp.fetchAll(urls).some((r,i)=>{letjson=parseJSON(r);lettext=json.message.body.lyrics
? json.message.body.lyrics.lyrics_body.split(' ').slice(10,25).join(' ')
: '';unknownLyrics[i].lyrics={text: text.formatName().replace(/["']/g,'').replace(/\n/g,' ')}if(json.message.header.status_code==404){console.log('Не найден текст для',`${unknownLyrics[i].artists[0].name} - ${unknownLyrics[i].name}`);unknownLyrics[i].lyrics.lang='und';}elseif(json.message.header.status_code!=200){console.error('Ошибка при получении текста','Возможно превышен лимит от musixmatch.','Код:',json.message.header.status_code);returntrue;}});}functiondetectLanguage(){constFILENAME='DetectLanguage';letunknownLang=tracks.filter(t=>!t.lyrics.lang);letrow=unknownLang.map(t=>`=DETECTLANGUAGE("${t.lyrics.text}")`);if(!row||row.length==0){console.log('Ноль треков для распознования языка среди',tracks.length,'треков');return;}letspreadsheet;letfiles=rootFolder.getFilesByName(FILENAME);if(files.hasNext()){spreadsheet=SpreadsheetApp.open(files.next());}else{spreadsheet=SpreadsheetApp.create(FILENAME);letfile=DriveApp.getFileById(spreadsheet.getId());file.moveTo(rootFolder);}letsheet=spreadsheet.getActiveSheet();sheet.clear();sheet.appendRow(row);SpreadsheetApp.flush();sheet.getDataRange().getValues()[0].forEach((c,i)=>{if(c=='#ERROR!'){console.log('Ошибка при попытки идентификации языка:',unknownLang[i].lyrics.text);}unknownLang[i].lyrics.lang=c;});}functionparseJSON(response){letcontent=response.getContentText();returncontent.length>0 ? tryParseJSON(content) : {msg: 'Пустое тело ответа',status: response.getResponseCode()};}functiontryParseJSON(content){try{returnJSON.parse(content);}catch(e){console.error('Не удалось перевести строку JSON в объект. ',e,e.stack,content);return[];}}functiongetRootFolder(){letfolders=DriveApp.getFoldersByName(FOLDER_NAME);if(folders.hasNext()){returnfolders.next();}returnDriveApp.createFolder(FOLDER_NAME);}}
Использование
Функция matchLanguage - оставляет только треки с указанным языком. Стандартная рекомендация: используйте последним в списке фильтров, чтобы сократить количество запросов.
Аргументы
(массив) tracks - перечень треков.
(объект) params - параметры фильтрации.
(бул) isRemoveUnknown - при false оставляет треки с неизвестным языком, при true удаляет. Трек без языка - когда нет в базе musixmatch или он полностью танцевальный.
(массив) include - перечень языков, которые нужно оставлять.
(массив) exclude - перечень языков, которые нужно удалять.
Принимаются двухбуквенные обозначения языка в нижнем регистре. Список доступен здесь.
Пример 1 - Берем топ Германии и оставляем только немецкий.
При тестах столкнулся с такой ситуацией. Автоперевод от Яндекса определял язык как немецкий. Тогда как Google реализация говорила люксембургский. Исполнитель был не столь популярным, чтобы найти истину. Просто имейте ввиду.
аддондополнительные возможностиархивнеактуально или не работает в свежих версиях
1 participant
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Включено в основную версию.
Описание
Наряду с задачей фильтрации по местоположению появился запрос на фильтр по языку. Сначала я подумал, что это невозможно. Потому что первым на ум приходит звук, волны, анализ. Одним словом дебри... Но ведь есть текст! С этим уже можно работать.
В качестве источника текстов выбрал musixmatch. Дает бесплатное API на 2 тысячи запросов в день с доступом к 30% текста от песни. Платная версия даже язык показывает. Но это не наш случай.
Как идентифицировать язык? Нужен переводчик. Он даже есть в Apps Script. Но не дает функции для получения языка, только перевод. Напрямую идти к API переводчика нельзя, потому что так или иначе придем к оплате. Есть интересный сервис DetectLanguage. Однако уже на первой тройке треков стало понятно, что качество идентификации очень низкое даже с английским языком. Локальные библиотеки тоже не подходят.
Apps Script не перестает меня удивлять. В Google Таблицах есть встроенная функция DETECTLANGUAGE, а Apps Script дает API для таблиц. Пазл сошелся.
Суммируем
Установка
addons
. И подставьте ключ в константуMUSIXMATCH_API_KEY
вместо123
.Использование
Функция
matchLanguage
- оставляет только треки с указанным языком. Стандартная рекомендация: используйте последним в списке фильтров, чтобы сократить количество запросов.Аргументы
tracks
- перечень треков.params
- параметры фильтрации.isRemoveUnknown
- приfalse
оставляет треки с неизвестным языком, приtrue
удаляет. Трек без языка - когда нет в базеmusixmatch
или он полностью танцевальный.include
- перечень языков, которые нужно оставлять.exclude
- перечень языков, которые нужно удалять.Пример 1 - Берем топ Германии и оставляем только немецкий.
При тестах столкнулся с такой ситуацией. Автоперевод от Яндекса определял язык как немецкий. Тогда как Google реализация говорила люксембургский. Исполнитель был не столь популярным, чтобы найти истину. Просто имейте ввиду.
Пример 2 - Схожая ситуация, исключаем русский.
Пример 3 - Узнать какие языки есть в массиве.
Beta Was this translation helpful? Give feedback.
All reactions