MarshalX / yandex-music-api

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

Загрузка собственных треков #582

Open efinskiy opened 1 year ago

efinskiy commented 1 year ago

Загрузка собственных треков с аутентификацией через cookie

Запрос эндпоинта для загрузки трека


curl 'https://music.yandex.ru/handlers/ugc-upload.jsx?filename=musicfile.mp3&kind=1014&visibility=private&lang=ru&external-domain=music.yandex.ru&overembed=false&ncrnd=0.024180625568828384' \
  -H 'Accept: application/json, text/javascript, */*; q=0.01' \
  -H 'Accept-Language: ru,ru-RU;q=0.9,en-US;q=0.8,en;q=0.7' \
  -H 'Connection: keep-alive' \
  -H $'Cookie: Session_id=yandex_coookie_grabbed_from_browser '

Данные запроса

Ответ

{
    "poll-result": "https://music-stable-loader-vla-2.music.yandex.ru:8443/request-status/20230102T211219.566.utd.3fc1g2pqlv0pblicalwokrm96-music-stable-loader-vla-2.vla.yp-c.yandex.net.147453",
    "post-target": "https://music-stable-loader-vla-2.music.yandex.ru:443/upload-target/20230102T211219.566.utd.3fc1g2pqlv0pblicalwokrm96-music-stable-loader-vla-2.vla.yp-c.yandex.net.147453",
    "ugc-track-id": "9a9706da-ea99-4c4c-9afb-e50ae7e2bcaa"
}

Объекты ответа

Загрузка трека


curl -X POST 'POST-TARGET_URL_TAKEN_FROM_UGC_UPLOAD_RESPONSE' \
  -H 'Accept: */*' \
  -H 'Accept-Language: ru,ru-RU;q=0.9,en-US;q=0.8,en;q=0.7' \
  -H 'Connection: keep-alive' \
  -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryBtAcAImh7wW0KBtN' \
  --data-raw $'------WebKitFormBoundaryBtAcAImh7wW0KBtN\r\nContent-Disposition: form-data; name="file"; filename="track_name.mp3"\r\nContent-Type: audio/mpeg\r\n\r\n\r\n------WebKitFormBoundaryBtAcAImh7wW0KBtN--\r\n' \
  --compressed

Данные запроса

Ответ

{
    "result": "CREATED"
}

Реализация функционала


# Запрашивает и возвращает ссылку на загрузку
def ugc_upload(self,
                filename: str, kind: Union[str, int], cookies: dict, lang: str = None, overembed: bool = None,
                ncrnd: Union[int, float] = None, external_domain: str = None, visibility: str = None
) -> str:

    if not lang:
        lang = 'ru'
    if not overembed:
        overembed = 'false'
    if not ncrnd:
        ncrnd = 0.5703991544386358
    if not external_domain:
        external_domain = 'music.yandex.ru'
    if not visibility:
        visibility = 'private'

    url = f'https://music.yandex.ru/handlers/ugc-upload.jsx'
    params = {'filename': filename, 'kind': kind, 'visibility': visibility,
                'lang': lang, 'external-domain': external_domain, 'overembed': overembed, 'ncrnd': ncrnd}
    result = self._request.get(url, params, cookies=cookies)
    return result['post_target']

# Загружает трек
def upload_track(self, file: bytes, post_target: str, cookies: dict) -> bool:
    payload = {'file': file}
    result = self._request.post(url=post_target, files=payload, cookies=cookies, timeout=120)
    return True

ALBUM_ID = 1014 # ID пользовательского альбома
file = open('path_to_file.mp3', 'rb')
cookies = {'Session_id': 'yandex_session_cookie_grabbed_from_browser'}
ugc = client.ugc_upload(filename=file.name, kind=ALBUM_ID, cookies=cookies)
client.upload_track(file=file, post_target=ugc, cookies=cookies)
MarshalX commented 1 year ago

Спасибо! Будем искать альтернативу в АПИ для приложений