-
-
Notifications
You must be signed in to change notification settings - Fork 82
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Получение FLAC'ов #656
Comments
Пример запроса на питоне с генерацией подписи #!/usr/bin/python3
from datetime import datetime
import hmac
import hashlib
import base64
import requests
SECRET = 'kzqU4XhfCaY6B6JTHODeq5'
TRACK_ID = '117708948'
TIMESTAMP = int(datetime.now().timestamp())
hmac_sign = hmac.new(SECRET.encode('utf-8'), f'{TIMESTAMP}{TRACK_ID}losslessflacaache-aacmp3raw'.encode('utf-8'), hashlib.sha256)
sign = base64.b64encode(hmac_sign.digest()).decode('utf-8')[:-1]
print(TIMESTAMP)
print(sign)
print('-' * 15)
p = {'ts': TIMESTAMP, 'trackId': TRACK_ID, 'quality': 'lossless', 'codecs': 'flac,aac,he-aac,mp3', 'transports': 'raw', 'sign': sign}
h = {
'Authorization': 'TOP SECRET',
'X-Yandex-Music-Client': 'YandexMusicDesktopAppWindows/5.13.2'
}
resp = requests.get(f'https://api.music.yandex.net/get-file-info', params=p, headers=h)
print(resp.text) Значение в переменной SECRET статично, но не исключаю факт что оно может со временем измениться. Получалось кровью и потом из десктопного приложения ЯМ |
OAuth в токене обязателен. Если использовать токен который получается этим способом, то хедер авторизации должен выглядеть вот так |
Привет) а если не секрет, какой прогой трафик слушал? |
mitm proxy, но вообще просто через дев тулсы в десктопной версии яндекс музыки (которая новая на электроне). Оттуда я все штуки и вытянул типа секрета и принципа создания подписи |
Если кто-то готов одолжить мне свой аккаунт Plus, я могу написать инструмент для скачивания музыки с Яндекса с поддержкой lossless. Я не могу получить Plus, потому что британские кредитные карты не принимаются. Проверьте мои репозитории, если у вас есть подозрения, у меня большой опыт написания музыкальных инструментов и реинжиниринга музыкальных стриминговых сервисов. Если вы готовы, напишите мне в Telegram. Спасибо. Извините за плохой русский, я использовал сервис перевода. |
Я уже сделал для себя, можешь исправить/дописать некоторые моменты (Как посмотрел, стоит только переписать получение плейлистов и исправить говнокод с кучей условий. Я тогда не особо разбирался с тем как оно работает, просто взял ссылку которую мне выдал яндекс в приложении) |
Я пишу свой инструмент на языке Rust. Да, я планирую реализовать поддержку плейлистов. Моя проблема в том, что единственный способ получить токен - это перехватить приложение для Android и Windows. Я хочу автоматизировать получение токена. Куки здесь не разрешают lossless: https://yandex-music.readthedocs.io/en/main/token.html |
Мне больше не нужна учетная запись Plus, чтобы я мог пронюхать о приложениях Windows. Я публично поделюсь своим инструментом, когда он будет готов. |
Может кому пригодится. import base64
import hashlib
import hmac
import typing
from dataclasses import dataclass
from datetime import datetime
from yandex_music import Track
from yandex_music.utils.sign_request import DEFAULT_SIGN_KEY
@dataclass
class LosslessDownloadInfo:
quality: str
codec: str
urls: list[str]
bitrate: int
def get_lossless_info(track: Track) -> LosslessDownloadInfo:
client = track.client
assert client
timestamp = int(datetime.now().timestamp())
params = {
"ts": timestamp,
"trackId": track.id,
"quality": "lossless",
"codecs": "flac,aac,he-aac,mp3",
"transports": "raw",
}
res = "".join(str(e) for e in params.values()).replace(",", "")
hmac_sign = hmac.new(
DEFAULT_SIGN_KEY.encode(),
res.encode(),
hashlib.sha256,
)
sign = base64.b64encode(hmac_sign.digest()).decode()[:-1]
params["sign"] = sign
resp = client.request.get(
"https://api.music.yandex.net/get-file-info", params=params
)
resp = typing.cast(dict, resp)
e = resp["download_info"]
return LosslessDownloadInfo(
quality=e["quality"], codec=e["codec"], urls=e["urls"], bitrate=e["bitrate"]
) |
Метод генерации подписи я тоже нашел, а вто как получить secretKey я, так и не допер) ...
generateSign: async function (secretKey, data) {
const encoder = new TextEncoder();
const keyData = encoder.encode(secretKey);
const cryptoKey = await crypto.subtle.importKey(
'raw',
keyData,
{name: 'HMAC', hash: {name: 'SHA-256'}},
false,
['sign']
);
const dataEncoded = encoder.encode(data);
const signature = await crypto.subtle.sign(
'HMAC',
cryptoKey,
dataEncoded
);
return btoa(String.fromCharCode(...new Uint8Array(signature))).slice(0, -1);
},
fetchFileInfo: async function (trackId) {
const secretKey = 'kzqU4XhfCaY6B6JTHODeq5';
const timestamp = Math.floor(Date.now() / 1000);
const dataToSign = `${timestamp}${trackId}losslessflacaache-aacmp3raw`;
const sign = await appYa.generateSign(secretKey, dataToSign);
console.log(timestamp);
console.log(sign);
console.log('-'.repeat(15));
const params = new URLSearchParams({
ts: timestamp,
trackId: trackId,
quality: 'lossless',
codecs: 'flac,aac,he-aac,mp3',
transports: 'raw',
sign: sign
});
const headers = new Headers({
'Authorization': 'TOP SECRET',
'X-Yandex-Music-Client': 'YandexMusicDesktopAppWindows/5.13.2'
});
const url = `https://api.music.yandex.net/get-file-info?${params.toString()}`;
try {
const response = await fetch(url, {headers});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.text();
console.log(data);
return data;
} catch (error) {
console.error('Error fetching file info:', error);
}
},
...``` |
Эндпоинт
Параметры
GET-параметры
Ответ
Массив из объектов
Пример запроса
Запрос
Ответ
Ответ
The text was updated successfully, but these errors were encountered: