Pull to refresh

Comments 17

Большое спасибо за код, хорошо когда есть пример. Но он требует доработок. Я попробовал его запустить и мне пришлось добавить несколько исправлений:

  1. в compile_audio сегменты могут склеиваться в неправильном порядке. Надо их как-то сортировать и не надеяться, что os.listdir() вернёт файлы в том же порядке, в котором их создали

  2. в нескольких местах стоит добавить os.makedirs(..., exist_ok=True), так как при первом запуске никаких этих папок нет

  3. download_segments кладёт их не туда, где они ожидаются в compile_audio и в delete_segments

Замечания по стилю кода:

  1. Лучше вместо open("").write(...) ипользовать конструкцию with open("") as f: f.write(...), чтобы файл автоматически закрывался при выходе из блока.

  2. Вместе с типами аргументов можно ещё указывать типы возвращаемых значений

  3. вместо 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))

А ещё по-умолчанию ffmpeg перекодирует с битрейтом 128 кбит/с. С опцией "-acodec copy" вроде получше - ничего не перекодируется, данные просто копируются.

Спасибо большое за замечания! для меня это очень важный опыт и очень важные замечания. Я учту их, так же подправлю код!

Я обычно качаю без кода торрентом, но ваш вариант тоже не плох:)

Зачем получать музыку из вконтакте, если есть рутрекер?

В целом как я и написал, изначальная идея — это написание музыкального бота для дискорда. Посмотрев что уже есть в интернете я пришел к выводу, что подобную реализацию еще никто не осуществлял, а похожие реализации уже устарели. Поэтому я решил попробовать сделать ее самостоятельно и заодно подарить другим людям, которые возможно столкнуться с подобной проблемой.

Придётся пользователей бота просить создать vk-аккаунт и вписать его логин/пароль.
Если вся толпа юзеров будет входить через один акк, вероятно, этот акк скоро забанят.

Ну моя идея скорее заключалась в том, чтобы дать людям такого бота на открытом коде и вообще изначально она возникла потому что меня раздражал уже написанный кем-то вариант на javascript, люди требовали премиум подписку за банальный шафл треков, который делается случайным перемешиванием списка, бред же?
Поэтому я написал своего бота, все исходники выложил на гитхаб, и те, кто заинтересован в таком боте могут спокойно найти его, поставить к себе на ПК или возможно даже на хост и пользоваться им в кругу друзей, для огромных серверов это конечно наверное и будет проблемой(я про бан аккаунта), однако, для простеньких серверов для своих это классное решение наверное.
Кстати сам бот:
https://github.com/tachycardiazxc/DiscordBot

Материал хороший, за анализ и подготовку - только уважение.

В целом, складывается ощущение, что не очень то эту музыку vk и хотели прятать. Защита от скачивания это требование "правообладателей" прочих мутных контор (в т.ч. международных). Сам vk и рад бы с этим не связываться, как не связывался долгое время. Компромисс: музыка лицензирована для некоторых регионов к нахождению на сайте, но скачивать ее нельзя. Плюс подписочная модель, и в конторы что-то идет, и сам vk на этом может подзаработать.

Формально требования соблюдены, по факту же фича скачивания музыки остается на поверхности, программы и скрипты для скачивания продолжают работать.

Но как уязвимость расходится, например на хабре, поставят таск, багофичу поправят. Такое уже практиковалось.

Пожалуй да, но скорее всего снова найдется человек, который поймет как обойти это.

Ну widevine l1 вроде как до сих пор не обошли, по крайне мере публично ничего не выложено чтобы подампить медиаконтент им защищенный

Кому надо знают (а узнать из не проблема вообще) секреты доверенных приложений через которые 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, думаю, для других языков аналоги тоже есть

Sign up to leave a comment.

Articles