{"id":335769,"date":"2022-07-16T09:00:09","date_gmt":"2022-07-16T09:00:09","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=335769"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=335769","title":{"rendered":"<span>\u041a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u043c\u0443\u0437\u044b\u043a\u0443 \u0438\u0437 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u0432 2022 \u0433\u043e\u0434\u0443<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043d\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0433\u043e discord \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/h3>\n<p>\u041f\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438. \u041f\u0435\u0440\u0432\u0430\u044f \u2014 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0443\u0437\u044b\u043a\u0438 \u0438\u0437 \u0412\u041a. \u0412\u0442\u043e\u0440\u0430\u044f \u2014 \u0441\u0430\u043c \u0431\u043e\u0442. \u0418 \u043d\u0430\u0447\u0430\u0442\u044c \u044f \u0440\u0435\u0448\u0438\u043b \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<p>\u041f\u043e\u0438\u0441\u043a \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0441\u0447\u0435\u0442 \u0438\u043b\u0438 \u0443\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u0443\u0441\u043a\u0430 \u043a\u043e\u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u0435\u0441 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0431\u044b\u043b\u043e \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0441\u0430\u043c\u043e\u043c\u0443.<\/p>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0447\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u0442\u0434\u0430\u0435\u0442 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u043f\u0440\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u043e\u043b\u0435\u0437 \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0443 network, \u0432\u043e\u0442 \u0447\u0442\u043e \u044f \u0442\u0430\u043c \u0443\u0432\u0438\u0434\u0435\u043b:<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u043e\u0442\u043e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ba6\/bcb\/774\/ba6bcb7746f090529cad64cc76822e42.png\" alt=\"\u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 index.m3u8\" title=\"\u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 index.m3u8\" width=\"1130\" height=\"781\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/ba6\/bcb\/774\/ba6bcb7746f090529cad64cc76822e42.png\"\/><figcaption>\u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 index.m3u8<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e62\/8df\/02e\/e628df02e40f0c503070c211fc708d80.png\" alt=\"\u041e\u0442\u043a\u0440\u044b\u0432 \u0435\u0433\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c GET \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 url\" title=\"\u041e\u0442\u043a\u0440\u044b\u0432 \u0435\u0433\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c GET \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 url\" width=\"1409\" height=\"538\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e62\/8df\/02e\/e628df02e40f0c503070c211fc708d80.png\"\/><figcaption>\u041e\u0442\u043a\u0440\u044b\u0432 \u0435\u0433\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c GET \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 url<\/figcaption><\/figure>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c84\/997\/8ce\/c849978cec6317dcea4b24a381ce20e7.png\" alt=\"\u0410 \u043e\u0442\u0432\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0441\u0442\u043e HLS \u0444\u043e\u0440\u043c\u0430\u0442, \u0441 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0438\u0445 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u044b\" title=\"\u0410 \u043e\u0442\u0432\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0441\u0442\u043e HLS \u0444\u043e\u0440\u043c\u0430\u0442, \u0441 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0438\u0445 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u044b\" width=\"1388\" height=\"711\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c84\/997\/8ce\/c849978cec6317dcea4b24a381ce20e7.png\"\/><figcaption>\u0410 \u043e\u0442\u0432\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0441\u0442\u043e HLS \u0444\u043e\u0440\u043c\u0430\u0442, \u0441 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0438\u0445 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u044b<\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u0441\u0442\u043e\u044f\u043b\u0430 \u043d\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0430\u0443\u0434\u0438\u043e \u043d\u0443\u0436\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 m3u8 \u0444\u0430\u0439\u043b \u0438 \u0443\u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u0435\u0433\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0432 \u0446\u0435\u043b\u044c\u043d\u044b\u043c mp3 \u0444\u0430\u0439\u043b.<\/p>\n<p>\u0412 \u0445\u043e\u0434\u0435 \u0440\u0430\u0437\u0434\u0443\u043c\u0438\u0439 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043f\u0438\u0442\u043e\u043d\u0430 vk_api \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u044d\u0442\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">from vk_api import VkApi from vk_api.audio import VkAudio  login = \"+7XXXXXXXXXX\" password = \"your_password\"  vk_session = VKApi(   login=login,   password=password,   api_version='5.81' ) vk_session.auth()  vk_audio = VKAudio(vk_session)  # \u0414\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0438\u0441\u043a \u0430\u0443\u0434\u0438\u043e \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e # \u0422\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0430\u0443\u0434\u0438\u043e \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 .get_iter(owner_id) # \u0433\u0434\u0435 owner_id \u044d\u0442\u043e \u0430\u0439\u0434\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b # \u0438\u043b\u0438 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0443\u0434\u0438\u043e \u0441 \u0430\u043b\u044c\u0431\u043e\u043c\u0430, \u0433\u0434\u0435 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0439\u0434\u0438 \u0430\u043b\u044c\u0431\u043e\u043c\u043e\u0432 # \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 .get_albums_iter() # \u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c .get_iter(owner_id, album_id), \u0433\u0434\u0435 album_id \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 # \u0430\u0439\u0434\u0438 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 q = \"audio name\" audio = next(vk_audio.search_iter(q=q)) url = audio['url'] # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0443 \u0434\u043b\u0438\u043d\u043d\u044e\u0449\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 m3u8 \u0444\u0430\u0439\u043b<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u043c\u044b \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0438 \u0432\u0441\u0442\u0430\u043b \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. \u042f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0437\u0430\u043f\u0438\u0445\u043d\u0443\u0442\u044c \u044d\u0442\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 \u0432 ffmpeg \u0438 \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u043e\u0431\u0440\u0430\u0434\u043e\u0432\u0430\u043b\u0441\u044f, \u0432\u0435\u0434\u044c \u043e\u043d \u0441\u043a\u0430\u0447\u0430\u043b \u043c\u043e\u0439 \u0437\u0430\u0432\u0435\u0442\u043d\u044b\u0439 \u0430\u0443\u0434\u0438\u043e\u0444\u0430\u0439\u043b \u0438 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u043b \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044e \u0432 mp3, \u043e\u0434\u043d\u0430\u043a\u043e, \u0441\u0447\u0430\u0441\u0442\u044c\u0435 \u043c\u043e\u0435 \u0434\u043b\u0438\u043b\u043e\u0441\u044c \u043d\u0435 \u0434\u043e\u043b\u0433\u043e, \u0432\u0435\u0434\u044c ffmpeg \u0445\u043e\u0442\u044c \u0438 \u0441\u043a\u0430\u0447\u0430\u043b \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b, \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u043b\u0435\u0438\u0432 \u0438\u0445, \u043d\u043e \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u043e\u043d \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 m3u8 \u0444\u0430\u0439\u043b\u0430<\/p>\n<pre><code>#EXTM3U #EXT-X-TARGETDURATION:25 #EXT-X-ALLOW-CACHE:YES #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-KEY:METHOD=AES-128,URI=\"https:\/\/cs1-66v4.vkuseraudio.net\/s\/v1\/ac\/wYaompMqHNQpBIH183wK68QVW45tvaJLaznkPiqES66JM-xzffiiM4KQx5WPS0Vg99U9ggCDronPKO8bzit3v_j8fH6LymN2pngBXYTv5uaDnFiAfc2aXv848bhRJEyFVB1gaJw1VR4BS9WnSb8jIMd0haPgfvJMcWC7FW7wpFkGU14\/key.pub\" #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:1 #EXTINF:2.000, seg-1-a1.ts #EXT-X-KEY:METHOD=NONE #EXTINF:4.000, seg-2-a1.ts #EXTINF:20.000, seg-3-a1.ts #EXT-X-KEY:METHOD=AES-128,URI=\"https:\/\/cs1-66v4.vkuseraudio.net\/s\/v1\/ac\/wYaompMqHNQpBIH183wK68QVW45tvaJLaznkPiqES66JM-xzffiiM4KQx5WPS0Vg99U9ggCDronPKO8bzit3v_j8fH6LymN2pngBXYTv5uaDnFiAfc2aXv848bhRJEyFVB1gaJw1VR4BS9WnSb8jIMd0haPgfvJMcWC7FW7wpFkGU14\/key.pub\" #EXTINF:20.000, seg-4-a1.ts #EXT-X-KEY:METHOD=NONE #EXTINF:25.444, seg-5-a1.ts #EXT-X-ENDLIST<\/code><\/pre>\n<p>\u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 EXT-X-KEY \u0443\u043a\u0430\u0437\u0430\u043d \u043c\u0435\u0442\u043e\u0434 \u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 AES-128 \u0438 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043a\u0430\u0447\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 m3u8 \u0438 pycryptodome:<\/p>\n<pre><code class=\"python\">import m3u8 import requests from Crypto.Cipher import AES from Crypto.Util.Padding import unpad  # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 m3u8 \u0444\u0430\u0439\u043b m3u8_data = m3u8.load(   url=\"\" # \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 url ) segments = m3u8.data.get(\"segments\")  # \u041f\u0430\u0440\u0441\u0438\u043c \u0444\u0430\u0439\u043b \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 segments_data = {}  for segment in segments:   segment_uri = segment.get(\"uri\")     extended_segment = {     \"segment_method\": None,     \"method_uri\": None   }   if segment.get(\"key\").get(\"method\") == \"AES-128\":     extended_segment[\"segment_method\"] = True     extended_segment[\"method_uri\"] = segment.get(\"key\").get(\"uri\")      segments_data[segment_uri] = extended_segment    # \u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 uris = segments_data.keys() for uri in uris:   # \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 url \u0433\u0434\u0435 \u043c\u044b \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0435\u043c index.m3u8 \u043d\u0430 \u043d\u0430\u0448 \u0441\u0435\u0433\u043c\u0435\u043d\u0442   audio = requests.get(url=index_url.replace(\"index.m3u8\", uri))   # \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c .ts \u0444\u0430\u0439\u043b   open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(audio.content)   # \u0415\u0441\u043b\u0438 \u0443 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e   if segments_data.get(uri).get(\"segment_method\") is not None:     # \u041a\u0430\u0447\u0430\u0435\u043c \u043a\u043b\u044e\u0447     key_uri = segments_data.get(uri).get(\"method_uri\")     key = requests.get(url=key_uri)     open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"wb\").write(key.content)         # \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c .ts \u0444\u0430\u0439\u043b     f = open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"rb\")     # \u0427\u0438\u0442\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0435 16 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438     iv = f.read(16)     # \u0427\u0438\u0442\u0430\u0435\u043c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435     ciphered_data = f.read()          # \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447     key = open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"rb\").read()     # \u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u043c     cipher = AES.new(       key,       AES.MODE.CBC,       iv=iv     )     data = unpad(cipher.decrypt(ciphered_data), AES.block_size)          # \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c .ts \u0444\u0430\u0439\u043b \u0432 \u0443\u0436\u0435 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043a\u043b\u044e\u0447 \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438     open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(data)     os.remove(f\"..\/m3u8_downloader\/keys\/key.pub\")   <\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0432 \u043e\u0434\u0438\u043d .ts \u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"python\"># \u043f\u0443\u0442\u044c \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0438 \u0444\u0430\u0439\u043b\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043f\u043a\u0438 segments_path = \"segments\/\" segments_file = os.listdir(segments_path)  for file in segments_file:   f = open(f\"..\/m3u8_downloader\/{segments_path}\/{file}\", \"rb\").read()   open(\"..\/m3u8_downloader\/mp3\/temp.ts\", \"ab\").write(f)<\/code><\/pre>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0432 mp3 \u0444\u043e\u0440\u043c\u0430\u0442, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 ffmpeg \u043d\u0430 \u041f\u041a.<\/p>\n<pre><code class=\"python\">import os  os.system('ffmpeg -i \"..\/m3u8_downloader\/mp3\/temp.ts\" \"..\/m3u8_downloader\/mp3\/temp.mp3\"') os.remove(\"..\/m3u8_downloader\/mp3\/temp.ts\")<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043c\u043e\u0436\u0435\u043c \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0443\u0436\u0435 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b.<\/p>\n<pre><code class=\"python\">segments_path = \"segments\/\" segments_file = os.listdir(segments_path) for file in segments_file: os.remove(segments_path + file)<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0431\u044b\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043e\u043f\u044b\u0442, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0432 \u0441\u0432\u043e\u0435\u0439 \u0436\u0438\u0437\u043d\u0438 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0438 HLS \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u043c, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0412\u0430\u043c \u0442\u043e\u0436\u0435 \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u043e. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u044f \u0441\u043c\u043e\u0433 \u043f\u043e\u043c\u043e\u0447\u044c \u0434\u0440\u0443\u0433\u0438\u043c \u043b\u044e\u0434\u044f\u043c, \u0432\u0435\u0434\u044c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u043f\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044e \u0430\u0443\u0434\u0438\u043e \u0441 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u043d\u0430 \u043f\u0438\u0442\u043e\u043d\u0435 \u0432 2022 \u0433\u043e\u0434\u0443 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b.<\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0432\u044b\u043b\u043e\u0436\u0443 \u0432\u0435\u0441\u044c \u043a\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import os import m3u8 import requests from vk_api import VkApi from vk_api.audio import VkAudio from Crypto.Cipher import AES from Crypto.Util.Padding import unpad   class M3U8Downloader:      def __init__(self, login: str, password: str):          self._vk_session = VkApi(             login=login,             password=password,             api_version='5.81'         )         self._vk_session.auth()          self._vk_audio = VkAudio(self._vk_session)      def download_audio(self, q: str):         url = self._get_audio_url(q=q)         segments = self._get_audio_segments(url=url)         segments_data = self._parse_segments(segments=segments)         self._download_segments(segments_data=segments_data, index_url=url)         self._compile_audio()         self._convert_ts_to_mp3()         self._delete_segments()      @staticmethod     def _delete_segments():         segments_path = \"segments\/\"         segments_file = os.listdir(segments_path)         for file in segments_file:             os.remove(segments_path + file)      @staticmethod     def _convert_ts_to_mp3():         os.system('ffmpeg -i \"..\/m3u8_downloader\/mp3\/temp.ts\" \"..\/m3u8_downloader\/mp3\/temp.mp3\"')         os.remove(\"..\/m3u8_downloader\/mp3\/temp.ts\")      @staticmethod     def _compile_audio():         segments_path = \"segments\/\"         segments_file = os.listdir(segments_path)         for file in segments_file:             f = open(f\"..\/m3u8_downloader\/{segments_path}\/{file}\", \"rb\").read()             open(\"..\/m3u8_downloader\/mp3\/temp.ts\", \"ab\").write(f)      def _get_audio_url(self, q: str):         self._vk_audio.get_albums_iter()         audio = next(self._vk_audio.search_iter(q=q))         url = audio['url']         return url      @staticmethod     def _get_audio_segments(url: str):         m3u8_data = m3u8.load(             uri=url         )         return m3u8_data.data.get(\"segments\")      @staticmethod     def _parse_segments(segments: list):         segments_data = {}          for segment in segments:             segment_uri = segment.get(\"uri\")              extended_segment = {                 \"segment_method\": None,                 \"method_uri\": None             }             if segment.get(\"key\").get(\"method\") == \"AES-128\":                 extended_segment[\"segment_method\"] = True                 extended_segment[\"method_uri\"] = segment.get(\"key\").get(\"uri\")             segments_data[segment_uri] = extended_segment         return segments_data      @staticmethod     def _download_segments(segments_data: dict, index_url: str):         uris = segments_data.keys()         for uri in uris:             audio = requests.get(url=index_url.replace(\"index.m3u8\", uri))             open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(audio.content)             if segments_data.get(uri).get(\"segment_method\") is not None:                 key_uri = segments_data.get(uri).get(\"method_uri\")                 M3U8Downloader._download_key(key_uri=key_uri)                  f = open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"rb\")                 iv = f.read(16)                 ciphered_data = f.read()                  key = open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"rb\").read()                 cipher = AES.new(                     key,                     AES.MODE_CBC,                     iv=iv                 )                 data = unpad(cipher.decrypt(ciphered_data), AES.block_size)                 open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(data)                 os.remove(f\"..\/m3u8_downloader\/keys\/key.pub\")      @staticmethod     def _download_key(key_uri: str):         key = requests.get(url=key_uri)         open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"wb\").write(key.content)                login = \"\" # phone password = \"\" # password md = M3U8Downloader(login=login, password=password)  q = \"\u0412\u043e\u043b\u043b\u043d\u044b \u0412\u043e\u043b\u043d\u044b\" # \u0417\u0430\u043f\u0440\u043e\u0441 \u043c\u0443\u0437\u044b\u043a\u0438 \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e md.download_audio()<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/677258\/\"> https:\/\/habr.com\/ru\/post\/677258\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<h3>\u041d\u0430\u0447\u0430\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441 \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043c\u043d\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u043c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0431\u043e\u0442\u0430 \u0434\u043b\u044f \u0441\u0432\u043e\u0435\u0433\u043e discord \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/h3>\n<p>\u041f\u0440\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u044f \u0440\u0435\u0448\u0438\u043b \u0440\u0430\u0437\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043d\u0430 \u0434\u0432\u0435 \u0447\u0430\u0441\u0442\u0438. \u041f\u0435\u0440\u0432\u0430\u044f \u2014 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u043c\u0443\u0437\u044b\u043a\u0438 \u0438\u0437 \u0412\u041a. \u0412\u0442\u043e\u0440\u0430\u044f \u2014 \u0441\u0430\u043c \u0431\u043e\u0442. \u0418 \u043d\u0430\u0447\u0430\u0442\u044c \u044f \u0440\u0435\u0448\u0438\u043b \u0441 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.<\/p>\n<p>\u041f\u043e\u0438\u0441\u043a \u043a\u0430\u043a\u043e\u0439-\u043b\u0438\u0431\u043e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0441\u0447\u0435\u0442 \u0438\u043b\u0438 \u0443\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0433\u043e\u0442\u043e\u0432\u043e\u0433\u043e \u043a\u0443\u0441\u043a\u0430 \u043a\u043e\u0434\u0430 \u043d\u0435 \u043f\u0440\u0438\u043d\u0435\u0441 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u0438\u0437-\u0437\u0430 \u0447\u0435\u0433\u043e \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u044b\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c \u0434\u0430\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0431\u044b\u043b\u043e \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c\u0441\u044f \u0441 \u044d\u0442\u0438\u043c \u0441\u0430\u043c\u043e\u043c\u0443.<\/p>\n<p>\u042f \u0440\u0435\u0448\u0438\u043b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0447\u0442\u043e \u0441\u0435\u0439\u0447\u0430\u0441 \u043e\u0442\u0434\u0430\u0435\u0442 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u043f\u0440\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0438 \u043f\u043e\u043b\u0435\u0437 \u0432\u043e \u0432\u043a\u043b\u0430\u0434\u043a\u0443 network, \u0432\u043e\u0442 \u0447\u0442\u043e \u044f \u0442\u0430\u043c \u0443\u0432\u0438\u0434\u0435\u043b:<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u043e\u0442\u043e<\/summary>\n<div class=\"spoiler__content\">\n<figure class=\"full-width\"><figcaption>\u041d\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 index.m3u8<\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption>\u041e\u0442\u043a\u0440\u044b\u0432 \u0435\u0433\u043e \u043c\u044b \u0432\u0438\u0434\u0438\u043c GET \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 url<\/figcaption><\/figure>\n<figure class=\"full-width\"><figcaption>\u0410 \u043e\u0442\u0432\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0438\u0437 \u0441\u0435\u0431\u044f \u043f\u0440\u043e\u0441\u0442\u043e HLS \u0444\u043e\u0440\u043c\u0430\u0442, \u0441 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0438 \u0438\u0445 \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0434\u0435\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0437\u0430\u043a\u043e\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u044b<\/figcaption><\/figure>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043f\u0435\u0440\u0435\u0434\u043e \u043c\u043d\u043e\u0439 \u0441\u0442\u043e\u044f\u043b\u0430 \u043d\u043e\u0432\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430, \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u0433\u043e \u0430\u0443\u0434\u0438\u043e \u043d\u0443\u0436\u043d\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 m3u8 \u0444\u0430\u0439\u043b \u0438 \u0443\u0436\u0435 \u043f\u043e\u0442\u043e\u043c \u0434\u0443\u043c\u0430\u0442\u044c \u043a\u0430\u043a \u0435\u0433\u043e \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u0442\u044c \u0438 \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c \u0432 \u0446\u0435\u043b\u044c\u043d\u044b\u043c mp3 \u0444\u0430\u0439\u043b.<\/p>\n<p>\u0412 \u0445\u043e\u0434\u0435 \u0440\u0430\u0437\u0434\u0443\u043c\u0438\u0439 \u0431\u044b\u043b \u043d\u0430\u0439\u0434\u0435\u043d \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432 \u0432\u0438\u0434\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u0434\u043b\u044f \u043f\u0438\u0442\u043e\u043d\u0430 vk_api \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438 \u0447\u0435\u0440\u0435\u0437 \u044d\u0442\u0443 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code class=\"python\">from vk_api import VkApi from vk_api.audio import VkAudio  login = \"+7XXXXXXXXXX\" password = \"your_password\"  vk_session = VKApi(   login=login,   password=password,   api_version='5.81' ) vk_session.auth()  vk_audio = VKAudio(vk_session)  # \u0414\u0435\u043b\u0430\u0435\u043c \u043f\u043e\u0438\u0441\u043a \u0430\u0443\u0434\u0438\u043e \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e # \u0422\u0430\u043a \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0430\u0443\u0434\u0438\u043e \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 .get_iter(owner_id) # \u0433\u0434\u0435 owner_id \u044d\u0442\u043e \u0430\u0439\u0434\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b # \u0438\u043b\u0438 \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0430\u0443\u0434\u0438\u043e \u0441 \u0430\u043b\u044c\u0431\u043e\u043c\u0430, \u0433\u0434\u0435 \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0430\u0439\u0434\u0438 \u0430\u043b\u044c\u0431\u043e\u043c\u043e\u0432 # \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 .get_albums_iter() # \u0438 \u043f\u043e\u0441\u043b\u0435 \u0441\u043d\u043e\u0432\u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c .get_iter(owner_id, album_id), \u0433\u0434\u0435 album_id \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 # \u0430\u0439\u0434\u0438 \u0430\u043b\u044c\u0431\u043e\u043c\u0430 q = \"audio name\" audio = next(vk_audio.search_iter(q=q)) url = audio['url'] # \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0443 \u0434\u043b\u0438\u043d\u043d\u044e\u0449\u0443\u044e \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 m3u8 \u0444\u0430\u0439\u043b<\/code><\/pre>\n<p>\u0412\u043e\u0442 \u043c\u044b \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0438 \u0432\u0441\u0442\u0430\u043b \u0432\u043e\u043f\u0440\u043e\u0441, \u0430 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435. \u042f \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b \u0437\u0430\u043f\u0438\u0445\u043d\u0443\u0442\u044c \u044d\u0442\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 \u0432 ffmpeg \u0438 \u0443\u0436\u0435 \u0431\u044b\u043b\u043e \u043e\u0431\u0440\u0430\u0434\u043e\u0432\u0430\u043b\u0441\u044f, \u0432\u0435\u0434\u044c \u043e\u043d \u0441\u043a\u0430\u0447\u0430\u043b \u043c\u043e\u0439 \u0437\u0430\u0432\u0435\u0442\u043d\u044b\u0439 \u0430\u0443\u0434\u0438\u043e\u0444\u0430\u0439\u043b \u0438 \u0441\u0440\u0430\u0437\u0443 \u0436\u0435 \u0441\u0434\u0435\u043b\u0430\u043b \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0430\u0446\u0438\u044e \u0432 mp3, \u043e\u0434\u043d\u0430\u043a\u043e, \u0441\u0447\u0430\u0441\u0442\u044c\u0435 \u043c\u043e\u0435 \u0434\u043b\u0438\u043b\u043e\u0441\u044c \u043d\u0435 \u0434\u043e\u043b\u0433\u043e, \u0432\u0435\u0434\u044c ffmpeg \u0445\u043e\u0442\u044c \u0438 \u0441\u043a\u0430\u0447\u0430\u043b \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b, \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043a\u043b\u0435\u0438\u0432 \u0438\u0445, \u043d\u043e \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u043e\u043d \u043d\u0435 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0435 \u0440\u0430\u0437 \u0432\u0437\u0433\u043b\u044f\u043d\u0435\u043c \u043d\u0430 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438 m3u8 \u0444\u0430\u0439\u043b\u0430<\/p>\n<pre><code>#EXTM3U #EXT-X-TARGETDURATION:25 #EXT-X-ALLOW-CACHE:YES #EXT-X-PLAYLIST-TYPE:VOD #EXT-X-KEY:METHOD=AES-128,URI=\"https:\/\/cs1-66v4.vkuseraudio.net\/s\/v1\/ac\/wYaompMqHNQpBIH183wK68QVW45tvaJLaznkPiqES66JM-xzffiiM4KQx5WPS0Vg99U9ggCDronPKO8bzit3v_j8fH6LymN2pngBXYTv5uaDnFiAfc2aXv848bhRJEyFVB1gaJw1VR4BS9WnSb8jIMd0haPgfvJMcWC7FW7wpFkGU14\/key.pub\" #EXT-X-VERSION:3 #EXT-X-MEDIA-SEQUENCE:1 #EXTINF:2.000, seg-1-a1.ts #EXT-X-KEY:METHOD=NONE #EXTINF:4.000, seg-2-a1.ts #EXTINF:20.000, seg-3-a1.ts #EXT-X-KEY:METHOD=AES-128,URI=\"https:\/\/cs1-66v4.vkuseraudio.net\/s\/v1\/ac\/wYaompMqHNQpBIH183wK68QVW45tvaJLaznkPiqES66JM-xzffiiM4KQx5WPS0Vg99U9ggCDronPKO8bzit3v_j8fH6LymN2pngBXYTv5uaDnFiAfc2aXv848bhRJEyFVB1gaJw1VR4BS9WnSb8jIMd0haPgfvJMcWC7FW7wpFkGU14\/key.pub\" #EXTINF:20.000, seg-4-a1.ts #EXT-X-KEY:METHOD=NONE #EXTINF:25.444, seg-5-a1.ts #EXT-X-ENDLIST<\/code><\/pre>\n<p>\u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u0432 EXT-X-KEY \u0443\u043a\u0430\u0437\u0430\u043d \u043c\u0435\u0442\u043e\u0434 \u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438 AES-128 \u0438 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u0441\u043a\u0430\u0447\u043a\u0443 \u043a\u043b\u044e\u0447\u0430 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438.<\/p>\n<p>\u0414\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u044d\u0442\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0431\u044b\u043b\u0430 \u043d\u0430\u0439\u0434\u0435\u043d\u0430 \u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u0430\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 m3u8 \u0438 pycryptodome:<\/p>\n<pre><code class=\"python\">import m3u8 import requests from Crypto.Cipher import AES from Crypto.Util.Padding import unpad  # \u041f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 m3u8 \u0444\u0430\u0439\u043b m3u8_data = m3u8.load(   url=\"\" # \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 url ) segments = m3u8.data.get(\"segments\")  # \u041f\u0430\u0440\u0441\u0438\u043c \u0444\u0430\u0439\u043b \u0432 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0444\u043e\u0440\u043c\u0430\u0442 segments_data = {}  for segment in segments:   segment_uri = segment.get(\"uri\")     extended_segment = {     \"segment_method\": None,     \"method_uri\": None   }   if segment.get(\"key\").get(\"method\") == \"AES-128\":     extended_segment[\"segment_method\"] = True     extended_segment[\"method_uri\"] = segment.get(\"key\").get(\"uri\")      segments_data[segment_uri] = extended_segment    # \u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043a\u0430\u0447\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0441 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u043e\u0439 uris = segments_data.keys() for uri in uris:   # \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 url \u0433\u0434\u0435 \u043c\u044b \u043f\u043e\u0434\u043c\u0435\u043d\u044f\u0435\u043c index.m3u8 \u043d\u0430 \u043d\u0430\u0448 \u0441\u0435\u0433\u043c\u0435\u043d\u0442   audio = requests.get(url=index_url.replace(\"index.m3u8\", uri))   # \u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c .ts \u0444\u0430\u0439\u043b   open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(audio.content)   # \u0415\u0441\u043b\u0438 \u0443 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0430 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434, \u0442\u043e \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u0435\u0433\u043e   if segments_data.get(uri).get(\"segment_method\") is not None:     # \u041a\u0430\u0447\u0430\u0435\u043c \u043a\u043b\u044e\u0447     key_uri = segments_data.get(uri).get(\"method_uri\")     key = requests.get(url=key_uri)     open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"wb\").write(key.content)         # \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c .ts \u0444\u0430\u0439\u043b     f = open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"rb\")     # \u0427\u0438\u0442\u0430\u0435\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0435\u0440\u0432\u044b\u0435 16 \u0441\u0438\u043c\u0432\u043e\u043b\u043e\u0432 \u0434\u043b\u044f \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u043a\u0438     iv = f.read(16)     # \u0427\u0438\u0442\u0430\u0435\u043c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u0435     ciphered_data = f.read()          # \u041e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044e\u0447     key = open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"rb\").read()     # \u0420\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u044b\u0432\u0430\u0435\u043c     cipher = AES.new(       key,       AES.MODE.CBC,       iv=iv     )     data = unpad(cipher.decrypt(ciphered_data), AES.block_size)          # \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c .ts \u0444\u0430\u0439\u043b \u0432 \u0443\u0436\u0435 \u0440\u0430\u0441\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043a\u043b\u044e\u0447 \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438     open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(data)     os.remove(f\"..\/m3u8_downloader\/keys\/key.pub\")   <\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0432 \u043e\u0434\u0438\u043d .ts \u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"python\"># \u043f\u0443\u0442\u044c \u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u043c \u0432\u0441\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b \u0438 \u0444\u0430\u0439\u043b\u044b \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u0430\u043f\u043a\u0438 segments_path = \"segments\/\" segments_file = os.listdir(segments_path)  for file in segments_file:   f = open(f\"..\/m3u8_downloader\/{segments_path}\/{file}\", \"rb\").read()   open(\"..\/m3u8_downloader\/mp3\/temp.ts\", \"ab\").write(f)<\/code><\/pre>\n<p>\u0418 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u043a\u043e\u043d\u0432\u0435\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u0432\u0441\u0435 \u0432 mp3 \u0444\u043e\u0440\u043c\u0430\u0442, \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 ffmpeg \u043d\u0430 \u041f\u041a.<\/p>\n<pre><code class=\"python\">import os  os.system('ffmpeg -i \"..\/m3u8_downloader\/mp3\/temp.ts\" \"..\/m3u8_downloader\/mp3\/temp.mp3\"') os.remove(\"..\/m3u8_downloader\/mp3\/temp.ts\")<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0447\u0435\u0433\u043e \u043c\u043e\u0436\u0435\u043c \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0443\u0434\u0430\u043b\u044f\u0442\u044c \u0443\u0436\u0435 \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0441\u0435\u0433\u043c\u0435\u043d\u0442\u044b.<\/p>\n<pre><code class=\"python\">segments_path = \"segments\/\" segments_file = os.listdir(segments_path) for file in segments_file: os.remove(segments_path + file)<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043c\u0435\u043d\u044f \u044d\u0442\u043e \u0431\u044b\u043b \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u044b\u0439 \u043e\u043f\u044b\u0442, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u044f \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u0434\u043e \u044d\u0442\u043e\u0433\u043e \u0432 \u0441\u0432\u043e\u0435\u0439 \u0436\u0438\u0437\u043d\u0438 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0441 \u0437\u0430\u0448\u0438\u0444\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u0438 HLS \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u043e\u043c, \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0412\u0430\u043c \u0442\u043e\u0436\u0435 \u0431\u044b\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u044d\u0442\u043e. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u044f \u0441\u043c\u043e\u0433 \u043f\u043e\u043c\u043e\u0447\u044c \u0434\u0440\u0443\u0433\u0438\u043c \u043b\u044e\u0434\u044f\u043c, \u0432\u0435\u0434\u044c \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0440\u0435\u0448\u0435\u043d\u0438\u0439 \u043f\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u043d\u0438\u044e \u0430\u0443\u0434\u0438\u043e \u0441 \u0412\u041a\u043e\u043d\u0442\u0430\u043a\u0442\u0435 \u043d\u0430 \u043f\u0438\u0442\u043e\u043d\u0435 \u0432 2022 \u0433\u043e\u0434\u0443 \u044f \u043d\u0435 \u043d\u0430\u0448\u0435\u043b.<\/p>\n<p>\u0422\u0430\u043a \u0436\u0435 \u0432\u044b\u043b\u043e\u0436\u0443 \u0432\u0435\u0441\u044c \u043a\u043e\u0434:<\/p>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import os import m3u8 import requests from vk_api import VkApi from vk_api.audio import VkAudio from Crypto.Cipher import AES from Crypto.Util.Padding import unpad   class M3U8Downloader:      def __init__(self, login: str, password: str):          self._vk_session = VkApi(             login=login,             password=password,             api_version='5.81'         )         self._vk_session.auth()          self._vk_audio = VkAudio(self._vk_session)      def download_audio(self, q: str):         url = self._get_audio_url(q=q)         segments = self._get_audio_segments(url=url)         segments_data = self._parse_segments(segments=segments)         self._download_segments(segments_data=segments_data, index_url=url)         self._compile_audio()         self._convert_ts_to_mp3()         self._delete_segments()      @staticmethod     def _delete_segments():         segments_path = \"segments\/\"         segments_file = os.listdir(segments_path)         for file in segments_file:             os.remove(segments_path + file)      @staticmethod     def _convert_ts_to_mp3():         os.system('ffmpeg -i \"..\/m3u8_downloader\/mp3\/temp.ts\" \"..\/m3u8_downloader\/mp3\/temp.mp3\"')         os.remove(\"..\/m3u8_downloader\/mp3\/temp.ts\")      @staticmethod     def _compile_audio():         segments_path = \"segments\/\"         segments_file = os.listdir(segments_path)         for file in segments_file:             f = open(f\"..\/m3u8_downloader\/{segments_path}\/{file}\", \"rb\").read()             open(\"..\/m3u8_downloader\/mp3\/temp.ts\", \"ab\").write(f)      def _get_audio_url(self, q: str):         self._vk_audio.get_albums_iter()         audio = next(self._vk_audio.search_iter(q=q))         url = audio['url']         return url      @staticmethod     def _get_audio_segments(url: str):         m3u8_data = m3u8.load(             uri=url         )         return m3u8_data.data.get(\"segments\")      @staticmethod     def _parse_segments(segments: list):         segments_data = {}          for segment in segments:             segment_uri = segment.get(\"uri\")              extended_segment = {                 \"segment_method\": None,                 \"method_uri\": None             }             if segment.get(\"key\").get(\"method\") == \"AES-128\":                 extended_segment[\"segment_method\"] = True                 extended_segment[\"method_uri\"] = segment.get(\"key\").get(\"uri\")             segments_data[segment_uri] = extended_segment         return segments_data      @staticmethod     def _download_segments(segments_data: dict, index_url: str):         uris = segments_data.keys()         for uri in uris:             audio = requests.get(url=index_url.replace(\"index.m3u8\", uri))             open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(audio.content)             if segments_data.get(uri).get(\"segment_method\") is not None:                 key_uri = segments_data.get(uri).get(\"method_uri\")                 M3U8Downloader._download_key(key_uri=key_uri)                  f = open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"rb\")                 iv = f.read(16)                 ciphered_data = f.read()                  key = open(f\"..\/m3u8_downloader\/keys\/key.pub\", \"rb\").read()                 cipher = AES.new(                     key,                     AES.MODE_CBC,                     iv=iv                 )                 data = unpad(cipher.decrypt(ciphered_data), AES.block_size)                 open(f\"..\/m3u8_downloader\/segments\/{uri}\", \"wb\").write(data)                 os.remove(f\"..\/m3u8_downloader\/keys\/key.pub\")      @staticmethod     def _download_key(key_uri: str):         key = requests.get(url=key_uri)<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-335769","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/335769","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=335769"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/335769\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=335769"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=335769"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=335769"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}