Comments 17
Большое спасибо за код, хорошо когда есть пример. Но он требует доработок. Я попробовал его запустить и мне пришлось добавить несколько исправлений:
в compile_audio сегменты могут склеиваться в неправильном порядке. Надо их как-то сортировать и не надеяться, что os.listdir() вернёт файлы в том же порядке, в котором их создали
в нескольких местах стоит добавить os.makedirs(..., exist_ok=True), так как при первом запуске никаких этих папок нет
download_segments кладёт их не туда, где они ожидаются в compile_audio и в delete_segments
Замечания по стилю кода:
Лучше вместо open("").write(...) ипользовать конструкцию with open("") as f: f.write(...), чтобы файл автоматически закрывался при выходе из блока.
Вместе с типами аргументов можно ещё указывать типы возвращаемых значений
вместо list и dict лучше из typing указывать что-то вроде List[Dict[str, Any]]
Можно вообще не сохранять ключи и сегменты во временные файлы, код сильно упростится.
def download_key(key_uri: str) -> bin:
return requests.get(url=key_uri).content
def download_m3u8(segments_data: dict, index_url: str) -> bin:
downloaded_segments = []
for uri in segments_data.keys():
audio = requests.get(url=index_url.replace("index.m3u8", uri))
downloaded_segments.append(audio.content)
if segments_data.get(uri).get("segment_method") is not None:
key_uri = segments_data.get(uri).get("method_uri")
key = download_key(key_uri=key_uri)
iv = downloaded_segments[-1][0:16]
ciphered_data = downloaded_segments[-1][16:]
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
data = unpad(cipher.decrypt(ciphered_data), AES.block_size)
downloaded_segments[-1] = data
return b''.join(downloaded_segments)
и потом при необходимости сохранить в файл:
with open(save_path, "w+b") as f:
f.write(download_m3u8(segments_data, url))
Спасибо большое за замечания! для меня это очень важный опыт и очень важные замечания. Я учту их, так же подправлю код!
3 совет дурной, смотри документацию
Я обычно качаю без кода торрентом, но ваш вариант тоже не плох:)
Зачем получать музыку из вконтакте, если есть рутрекер?
В целом как я и написал, изначальная идея — это написание музыкального бота для дискорда. Посмотрев что уже есть в интернете я пришел к выводу, что подобную реализацию еще никто не осуществлял, а похожие реализации уже устарели. Поэтому я решил попробовать сделать ее самостоятельно и заодно подарить другим людям, которые возможно столкнуться с подобной проблемой.
Если вся толпа юзеров будет входить через один акк, вероятно, этот акк скоро забанят.
Ну моя идея скорее заключалась в том, чтобы дать людям такого бота на открытом коде и вообще изначально она возникла потому что меня раздражал уже написанный кем-то вариант на javascript, люди требовали премиум подписку за банальный шафл треков, который делается случайным перемешиванием списка, бред же?
Поэтому я написал своего бота, все исходники выложил на гитхаб, и те, кто заинтересован в таком боте могут спокойно найти его, поставить к себе на ПК или возможно даже на хост и пользоваться им в кругу друзей, для огромных серверов это конечно наверное и будет проблемой(я про бан аккаунта), однако, для простеньких серверов для своих это классное решение наверное.
Кстати сам бот:
https://github.com/tachycardiazxc/DiscordBot
Материал хороший, за анализ и подготовку - только уважение.
В целом, складывается ощущение, что не очень то эту музыку vk и хотели прятать. Защита от скачивания это требование "правообладателей" прочих мутных контор (в т.ч. международных). Сам vk и рад бы с этим не связываться, как не связывался долгое время. Компромисс: музыка лицензирована для некоторых регионов к нахождению на сайте, но скачивать ее нельзя. Плюс подписочная модель, и в конторы что-то идет, и сам vk на этом может подзаработать.
Формально требования соблюдены, по факту же фича скачивания музыки остается на поверхности, программы и скрипты для скачивания продолжают работать.
Но как уязвимость расходится, например на хабре, поставят таск, багофичу поправят. Такое уже практиковалось.
Пожалуй да, но скорее всего снова найдется человек, который поймет как обойти это.
Кому надо знают (а узнать из не проблема вообще) секреты доверенных приложений через которые api получения музыки прекрасно работает и без парсинга html
os.system('ffmpeg -i "../m3u8_downloader/mp3/temp.ts" "../m3u8_downloader/mp3/temp.mp3"')
Скачал такой сегмент, внутри mp3. Не лучше будет минимизировать реенкод, добавив -c copy
к флагам ffmpeg? Неизвестно, сколько уже раз файл перекодировался на стороне самого vk (при загрузке, при нарезке в HLS). Конечно, если среди сегментов не только mp3 попадаются, нужно будет перекодировать, но это легко проверить тем же ffmpeg/ffprobe.
зачем использовать ffmpeg, по сути стороннюю прогу? если можно не использовать.
На golang для Demux юзал go-astits, думаю, для других языков аналоги тоже есть
Как получать музыку из ВКонтакте в 2022 году