Сегодня ночью услужливый Youtube следуя какой-то своей логике включил в режиме автовоспроизведения трек «‘Back To The 80’s’ | Best of Synthwave And Retro Electro Music Mix for 2 Hours | Vol. 9«, который как-то уж очень хорошо «зашел» — причем настолько, что я задумался, как загрузить mp3 с YouTube? Погуглил варианты, и наткнулся на вот это решение — однако, как оказалось позже — оно платное, а в бесплатной версии рассчитано на одну загрузку. Беда-печаль, подумал я, а потом вспомнил что вопрос загрузки видео с Youtube решал когда-то давно, а переконвертировать видео в аудио — не так и сложно 😉 Давайте разберемся как.
Собственно, в основе лежат две библиотеки: PyTube и Moviepy, каждая из которых решает свою задачу: скачивание с Youtube, и — конвертацию mp4 в mp3. Осталось привести это в порядок 🙂
-
#Подключаем нужные библиотеки
-
from pytube import YouTube
-
from moviepy.editor import *
-
import re
-
import os
-
-
#Получаем ссылку на видео
-
link = str(input('Введите ссылку на видео: '))
-
-
#Получаем ссылку - куда сохранять видео
-
save_link = input('Куда сохранять видео?: ')
-
-
#Создаем регулярку, которая будет разбивать введенный адрес сохранения
-
regxp = '[\w-]+[\w:]'
-
result = re.findall(regxp, save_link) #Разбиваем адрес, куда сохраняем видео на составляющие без обратного слеша
-
-
#И конвертируем адрес сохранения под требования Python - с двумя слешами
-
final_link = '\\\\'.join(result) #Добавляем двойной слеш после каждой папки (под формат Python)
-
name = YouTube(link).title
-
print('Сохраняем видео...', name)
-
video_for = YouTube(link).streams.first()
-
video_for.download(final_link)
-
print('Видео сохранено... \n Конвертируем в .mp3')
-
video = VideoFileClip(os.path.join(save_link, name + '.mp4'))
-
video.audio.write_audiofile(os.path.join(final_link, final_link, name + '.mp3'))
-
-
print(name + '.mp3 готов :)')
Важно!
Если в процессе использования библиотеки у вас возникнет ошибка в стиле:
Traceback (most recent call last): File "C:\Users\oleks\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\extract.py", line 299, in apply_descrambler for format_item in formats File "C:\Users\oleks\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\extract.py", line 299, in <listcomp> for format_item in formats KeyError: 'url' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "C:/Users/oleks/Desktop/Git/Netology/From Youtube to mp3/from_youtube_to_mp3.py", line 3, in <module> yt = YouTube('http://youtube.com/watch?v=9bZkp7q19f0') File "C:\Users\oleks\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\__main__.py", line 92, in init self.descramble() File "C:\Users\oleks\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\__main__.py", line 132, in descramble apply_descrambler(self.player_config_args, fmt) File "C:\Users\oleks\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\extract.py", line 303, in apply_descrambler parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats) File "C:\Users\oleks\AppData\Local\Programs\Python\Python37-32\lib\site-packages\pytube\extract.py", line 303, in <listcomp> parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats) KeyError: 'cipher'
не паникуйте, а просто исправьте файл extract.py. Строку 279 с текстом:
parse_qs(formats[i]["cipher"]) for i, data in enumerate(formats)
комментируем, а вместо нее пишем:
parse_qs(formats[i]["signatureCipher"]) for i, data in enumerate(formats) if "signatureCipher" in formats[i]
после чего ошибка исчезает 😉
Если вам лениво ковыряться в коде — можете скачать скорректированный файл по ссылке и вставить его по адресу: c:\Users\user_name\appdata\Local\Programs\Python\Python37-32\Lib\site-packages\pytube\
Спасибо за внимание. По вопросу, который звучит как «загрузить mp3 с YouTube» — все 🙂 Как всегда — вопросы можно задавать на почту или в Telegram 🙂
UPF: библиотека Pytube иногда глючит в определении имени получаемого с Youtube файла, а потом код иногда дает сбой. Переработал код — теперь мы сохраняем файл с Youtube под временным именем, после чего конвертируем в .mp3 и переименовываем — опять таки, в какое-то общее имя (в данном случае: «Youtube_music»). Кроме этого добавил проверку на существование файла с подобным именем — если имя есть, добавляем в конец случайное число. Получилось грубовато, но в результате нескольких сотен проверок не было ни одного сбоя, что по своему радует 🙂 И да — обновленный код — ниже:
-
from pytube import YouTube
-
from moviepy.editor import *
-
import re
-
import os.path
-
import random
-
-
link = str(input('Введите ссылку на видео: '))
-
save_link = input('Куда сохранять видео?: ')
-
-
regxp = '[\w-]+[\w:]'
-
result = re.findall(regxp, save_link) #Разбиваем адрес, куда сохраняем видео на составляющие без обратного слеша
-
-
#И конвертируем адрес сохранения под требования Python - с двумя слешами
-
final_link = '\\\\'.join(result) #Добавляем двойной слеш после каждой папки (под формат Python)
-
#name = str(youtube_video)
-
#filename = str(Youtube_video)
-
name = YouTube(link).title
-
print('Сохраняем видео...', name)
-
video_for = YouTube(link).streams.first()
-
video_for.download(final_link)
-
video_for.download(output_path=final_link, filename='Youtube_video')
-
print('Видео сохранено... \n Конвертируем в .mp3')
-
-
video = VideoFileClip(os.path.join(save_link, 'Youtube_video.mp4'))
-
-
if os.path.isfile('Youtube_music.mp3')== True:
-
random_number = int(random.randrange(1, 10000))
-
new_name = str('Youtube_music') + str(random_number) + str('.mp3')
-
video.audio.write_audiofile(os.path.join(final_link, final_link, new_name))
-
else:
-
video.audio.write_audiofile(os.path.join(final_link, final_link, 'Youtube_music' + '.mp3'))
-
print('Все готово :) ')