MarshalX / yandex-music-api

Неофициальная Python библиотека для работы с API сервиса Яндекс.Музыка
https://yandex-music.rtfd.io
GNU Lesser General Public License v3.0
956 stars 81 forks source link

Импорт треков #316

Open glebliutsko opened 4 years ago

glebliutsko commented 4 years ago

В приложении есть возможность имортировать треки с устройства в библиотеку ЯМ.

Скрин ![изображение](https://user-images.githubusercontent.com/40576167/81166116-3da73c00-8fa4-11ea-82bc-f7a828d1627b.png)

Как это работает

Иморт треков в приложении происходит в 2 этапа:

  1. Отправка списка треков. Запрос

    POST /import/playlist?title=QEMU%20Standard%20PC%20%28i440FX%20%2B%20PIIX
    
    IC3PEAK - Марш
    Imagine Dragons - Believer
    И так далее...

    В ответ приходит идентификатор импорта Пример ответа

    {"invocationInfo":{"hostname":"music-prestable-back-sas-1.sas.yp-c.yandex.net","req-id":"1588701663827583-1856380496783727601","exec-duration-millis":"27"},"result":{"importCode":"5eb1a9dfb47aeb145dbdcf88"}}
  2. Создание плейлиста Запрос

    GET /import/{id_import}/playlists

    В ответ приходит поле status. Возможны 2 значения in-progress и done. В первом случае запрос повторяется через несколько секунд. Во 2 случае, вместе с полем status приходит также и поле platlists

    Пример ответа

    Пример ответа ```json { "invocationInfo":{ "hostname":"music-stable-back-man-12.man.yp-c.yandex.net", "req-id":"1588701674059987-11068358653834619920", "exec-duration-millis":"12" }, "result":{ "status":"done", "playlists":[ { "owner":{ "uid":410060648, "login":"gleb.liutsko", "name":"Глеб Люцко", "sex":"male", "verified":false }, "available":false, "uid":410060648, "kind":1043, "title":"QEMU Standard PC (i440FX + PIIX, 1996)", "revision":1, "snapshot":1, "trackCount":2, "visibility":"public", "collective":false, "created":"2020-05-05T18:01:09+00:00", "modified":"2020-05-05T18:01:09+00:00", "isBanner":false, "isPremiere":false, "durationMs":358670, "cover":{ "type":"mosaic", "itemsUri":[ "avatars.yandex.net/get-music-content/2383988/0be6020b.a.9981618-1/%%", "avatars.yandex.net/get-music-content/38044/ec0212d9.a.4456609-1/%%" ], "custom":false }, "ogImage":"avatars.yandex.net/get-music-content/2383988/0be6020b.a.9981618-1/%%", "tracks":[ { "id":62989098, "albumId":9981618, "timestamp":"2020-05-05T18:01:09+00:00" }, { "id":33311009, "albumId":4456609, "timestamp":"2020-05-05T18:01:09+00:00" } ], "tags":[ ], "prerolls":[ ] } ] } } ```

P.S. Название трека скорей всего берется из ID3-тегов

GEkuL commented 4 years ago

т.е. ЯМ сам находит, совпадающие треки с импортироваыми и добавляет в Ваш плейлист из своей базы или берет трек и просто его загружаент в базу? Тогда не понятно, как платформа еще не накопила кучу копий одного и того же, как это происходит ВК

MarshalX commented 4 years ago

т.е. ЯМ сам находит, совпадающие треки с импортироваыми и добавляет в Ваш плейлист из своей базы или берет трек и просто его загружаент в базу? Тогда не понятно, как платформа еще не накопила кучу копий одного и того же, как это происходит ВК

ЯМ осуществляет поиск по названиям и исполнителям полученных из списка файлов в своей базе. Если находит такой трек - добавляет в плейлист. Выходными данными является плейлист с треками, которые удалось найти на ЯМ.

В ЯМ можно загружать и свои треки, но они доступны только аккаунту, который их загрузил. Для других пользователей они не сущетсвуют. Именно по этой причине ЯМ не такая мусорка как ВК

GEkuL commented 4 years ago

уточните пожалуйста информацию по запросу из приложения

GEkuL commented 4 years ago

Повторить код предложенный в шапке у меня не получилось. Но я по-разбирал web-версию и вот что вышло у меня:

Все также 2 запроса:

1) Первый запрос выглядит так

# POST
url='https://music.yandex.ru/handlers/import.jsx'
song_to_import="""Putting Holes In Happiness Marilyn Manson
Urgent Foreigner"""
string_of_songs=song_to_import.replace(' ','+')
json_values={i
    'content':string_of_songs
}
r1_import=requests.post(url,json=json_values)

Ответ приходит в таком виде

{'importCode': '5efdb71c1efb3a6bb112a126', 'success': True}

2) Второй запрос отправляем так

# GET
id_import=json.loads(r1_import.text)['importCode']
url='https://music.yandex.ru/handlers/import.jsx'
params={
    'code':id_import
}
r2_import=requests.get(url=url, params=params)

И получаем: либо ответ, что плейлист еще собирается

{'status':` 'in-progress', 'success': True}

либо ответ с инфой о получившемся плейлисте (скажите как спрятать тело кода как сделано в заголовке - поправлю)

{'status': 'done',
 'success': True,
 'tracks': [{'albums': [{'artists': [{'composer': False,
       'cover': {'prefix': '0e0123aa.p.1404/',
        'type': 'from-artist-photos',
        'uri': 'avatars.yandex.net/get-music-content/49707/0e0123aa.p.1404/%%'},
       'genres': [],
       'id': 1404,
       'name': 'Marilyn Manson',
       'various': False}],
     'available': True,
     'availableForMobile': True,
     'availableForPremiumUsers': True,
     'availablePartially': False,
     'bests': [],
     'buy': [],
     'coverUri': 'avatars.yandex.net/get-music-content/63210/afd31873.a.6128-1/%%',
     'genre': 'alternative',
     'id': 6128,
     'labels': [{'id': 2004, 'name': 'Interscope'}],
     'metaType': 'music',
     'ogImage': 'avatars.yandex.net/get-music-content/63210/afd31873.a.6128-1/%%',
     'recent': False,
     'releaseDate': '2008-05-05T00:00:00+04:00',
     'title': 'Putting Holes In Happiness',
     'trackCount': 4,
     'trackPosition': {'index': 1, 'volume': 1},
     'type': 'single',
     'version': 'German Version',
     'veryImportant': False,
     'year': 2007}],
   'artists': [{'composer': False,
     'cover': {'prefix': '0e0123aa.p.1404/',
      'type': 'from-artist-photos',
      'uri': 'avatars.yandex.net/get-music-content/49707/0e0123aa.p.1404/%%'},
     'genres': [],
     'id': 1404,
     'name': 'Marilyn Manson',
     'various': False}],
   'available': True,
   'availableForPremiumUsers': True,
   'availableFullWithoutPermission': False,
   'coverUri': 'avatars.yandex.net/get-music-content/63210/afd31873.a.6128-1/%%',
   'durationMs': 271540,
   'embedPlayback': True,
   'fileSize': 0,
   'id': '64571',
   'lyricsAvailable': False,
   'major': {'id': 1, 'name': 'UNIVERSAL_MUSIC'},
   'normalization': {'gain': -10.13, 'peak': 32766},
   'ogImage': 'avatars.yandex.net/get-music-content/63210/afd31873.a.6128-1/%%',
   'prefix': '',
   'previewDurationMs': 30000,
   'realId': '64571',
   'rememberPosition': False,
   'storageDir': '9693_ca1a688f.32076763.64571',
   'title': 'Putting Holes In Happiness',
   'type': 'music'},
  {'albums': [{'artists': [{'composer': False,
       'cover': {'prefix': '29a8d841.p.36749/',
        'type': 'from-artist-photos',
        'uri': 'avatars.yandex.net/get-music-content/49876/29a8d841.p.36749/%%'},
       'genres': [],
       'id': 36749,
       'name': 'Foreigner',
       'various': False}],
     'available': True,
     'availableForMobile': True,
     'availableForPremiumUsers': True,
     'availablePartially': False,
     'bests': [95995, 122603],
     'buy': [],
     'contentWarning': 'clean',
     'coverUri': 'avatars.yandex.net/get-music-content/49707/e39b9286.a.11562-4/%%',
     'genre': 'rock',
     'id': 11562,
     'labels': [{'id': 31588, 'name': 'Atlantic'}],
     'metaType': 'music',
     'ogImage': 'avatars.yandex.net/get-music-content/49707/e39b9286.a.11562-4/%%',
     'recent': False,
     'releaseDate': '1982-11-17T00:00:00+03:00',
     'title': 'Records',
     'trackCount': 10,
     'trackPosition': {'index': 6, 'volume': 1},
     'veryImportant': False,
     'year': 1982}],
   'artists': [{'composer': False,
     'cover': {'prefix': '29a8d841.p.36749/',
      'type': 'from-artist-photos',
      'uri': 'avatars.yandex.net/get-music-content/49876/29a8d841.p.36749/%%'},
     'genres': [],
     'id': 36749,
     'name': 'Foreigner',
     'various': False}],
   'available': True,
   'availableForPremiumUsers': True,
   'availableFullWithoutPermission': False,
   'coverUri': 'avatars.yandex.net/get-music-content/49707/e39b9286.a.11562-4/%%',
   'durationMs': 237320,
   'embedPlayback': True,
   'fileSize': 0,
   'id': '122599',
   'lyricsAvailable': True,
   'major': {'id': 4, 'name': 'WARNER'},
   'normalization': {'gain': -6.83, 'peak': 32495},
   'ogImage': 'avatars.yandex.net/get-music-content/49707/e39b9286.a.11562-4/%%',
   'prefix': '',
   'previewDurationMs': 30000,
   'realId': '122599',
   'rememberPosition': False,
   'storageDir': '30632_48a8e581.51652851.1.122599',
   'title': 'Urgent',
   'type': 'music',
   'version': 'Single; Single Version'}
           ]
}

Хочется отметить, что скорее всего web-версия меняется чаще, чем приложение, поэтому эти запросы могут стать неактуальными. На момент написания они работают. Еще есть некоторые странности с тем, что одни и те же песни при разных запросах переводятся в разные аудио...

Надеюсь, мой коммент будет полезен)

Chimildic commented 2 years ago

Есть проблема с импортом. Локальный запуск из VS Code под Windows отрабатывает корректно. Находит указанные треки и создает плейлист с ними. Но этот же код в онлайн песочнице replit находит один и совершенно другой трек Fly The Enos (его нет в запросе). В чем может быть отличие? Они как-то по разному кодируют тело запроса.

import requests

url = "https://api.music.yandex.net/import/playlist/?title=test"
payload = "against the current paralyzed\r\nezi dancing in a room\r\nillenium afterlife feat echos\r\nflying decibels the road\r\nshinedown miracle\r\n"
headers = {
  'Authorization': 'OAuth token',
}

response = requests.request("POST", url, headers=headers, data=payload)
print(response.text)
MarshalX commented 2 years ago

@Chimildic проблема может быть в стране с которой выполняется запрос (IP адрес replit сервера вряд ли в СНГ). И вот если вы вСНГ, то в целом очевидно почему разное поведение

Chimildic commented 2 years ago

@MarshalX но передается же латиница, почему в СНГ она проходит правильно, а с других IP вдруг ломается до неузнаваемости. Другой запрос, на создание пустого плейлиста, проходит правильно (имя плейлиста не ломается).

MarshalX commented 2 years ago

@Chimildic Потому что Яндекс.Музыка работает только на территории СНГ? Аккаунт с премиумом используется?