今回はpythonを使った動画・音楽をダウンロードする仕組みを作ってみました。
この記事の目次
環境
OS | mac OS Catalina 10.15 |
Python | 3.7.3 |
subprocess | 標準ライブラリ |
Kivy | 1.11.1 |
japanese-kivy | 0.1.1 |
youtube-dl | 2019.9.12.1 |
仮想空間を作ってKivy, japanese-kivy, youtube-dlをpipでインストールしました。
Kivy
Kivy - Open source Python library for rapid development of applications that make use of innovative user interfaces, such as multi-touch apps.
https://kivy.org/#home
結局何かというと、アプリケーションを作るために使うPythonのオープンソースライブラリだということです。
japanese-kivy
フォントをダウンロードする方法もありますが、今回はimportのみのjapanese-kivyを使いました。
youtube-dl
youtube-dlはコマンドラインから動画をダウンロードできるPythonのライブラリです。
なんと2019/10/22時点で対応サイトが1160サイトにのぼります。
コード
getia.py
import japanize_kivy # 日本語設定
import subprocess # pythonからコマンドを操作
import youtube_dl # 一番大切なもの
from kivy.app import App # 必須
from kivy.uix.boxlayout import BoxLayout # アプリのレイアウトに必要
from kivy.uix.textinput import TextInput # テキスト入力に必要
from kivy.uix.recycleview import RecycleView # リスト表示に必要
from kivy.uix.widget import Widget # 必須
from kivy.uix.spinner import Spinner # ドロップダウンメニュー
class GetiaWidget(Widget):
def reset(self):
self.ids.url.text = ''
self.ids.status.text = 'status:'
self.ids.url_lists.data = [{'text': ""}]
self.ids.service.text = 'YouTube'
self.ids.search_url.text = ''
self.ids.download_code.text = ''
self.ids.save_place.text = "%(title)s.%(ext)s"
self.ids.format_type.text = ''
self.ids.checkbox.active = False
def buttonClicked1(self):
try:
text = self.ids.search_url.text
self.ids.url.text = text
service = self.ids.service.text
format_list = subprocess.check_output("youtube-dl {} --list-format".format(text), shell=True).splitlines()
lists = []
for i in format_list:
str_i = i.decode("utf-8")
if service == 'YouTube':
if str.isdigit(str_i[0:3]) == True:
if str_i[24:34] == "audio only":
lists.append({'text': "MUSIC: " + str_i[0:3] + " | " + str_i[13:17] + " | " + str_i[41:45]})
else:
lists.append({'text': "VIDEO: " + str_i[0:3] + " | " + str_i[13:17] + " | " + str_i[24:34]})
elif service == 'ニコニコ動画':
if str.isdigit(str_i[1:4]) == True:
lists.append({'text': str_i[0:25] + " | " + str_i[27:30] + " | " + str_i[37:47]})
else:
lists.append({'text': str_i})
self.ids.url_lists.data = lists
self.ids.status.text = 'status: OK'
except:
self.ids.status.text = 'status: ERROR'
def buttonClicked2(self):
url = self.ids.url.text
download_code = self.ids.download_code.text
save_place = self.ids.save_place.text
checkbox = self.ids.checkbox.active
format_type = self.ids.format_type.text
try:
if checkbox == True:
subprocess.check_output("youtube-dl {} --format {} --output '{}' --merge-output-format {}".format(url, download_code, save_place, format_type), shell=True)
else:
subprocess.check_output("youtube-dl {} --format {} --output '{}'".format(url, download_code, save_place), shell=True)
self.ids.status.text = 'status: OK'
except: self.ids.status.text = 'status: ERROR'
class getiaApp(App):
def init(self, kwargs):
super(getiaApp, self).init(kwargs)
self.title = 'GETIA'
def build(self):
return GetiaWidget()
if name == 'main':
getiaApp().run()
getia.kv
###:kivy
:
BoxLayout:
size: root.size #重要!!!
BoxLayout:
orientation: 'vertical'#水平
ActionBar:
ActionView:
ActionPrevious:
title: "GETIA"
with_previous: False
ActionButton:
text: "リセット"
on_press: root.reset()
BoxLayout:
size_hint_y: 0.05 #y1
Label:
size_hint_x: 0.2 #y1x1
font_size: 68
text: "①"
Spinner:
size_hint_x: 0.2 #y1x2
text: 'YouTube'
values: 'YouTube', 'ニコニコ動画', 'その他'
id: service
TextInput:
size_hint_x: 0.5 #y1x3
id: search_url
Button:
size_hint_x: 0.1 #y1x4
text: "検索"
on_press: root.buttonClicked1()
BoxLayout:
size_hint_y: 0.7 #y2
Label:
size_hint_x: 0.2 #y2x1
font_size: 68
text: "②"
BoxLayout:
size_hint_x: 0.8 #y2x2
orientation: 'vertical'#水平
Label:
size_hint_y: 0.3 #y2x2y1
id: url
text: 'url'
RecycleView:
size_hint_y: 0.7 #y2x2y2
id: url_lists
viewclass: 'Label'
RecycleBoxLayout:
default_size: None, dp(56)
default_size_hint: 1, None
size_hint_y: None
height: self.minimum_height
orientation: 'vertical'
BoxLayout:
size_hint_y: 0.15 #y3
Label:
size_hint_x: 0.2 #y3x1
font_size: 68
text: "③"
BoxLayout:
size_hint_x: 0.6 #y3x2
orientation: 'vertical'#水平
BoxLayout:
Label:
size_hint_x: 0.8 #y3x2y1x1
text: "使う数字入力('動画'+ '音楽'),('動画'),('音楽')"
TextInput:
size_hint_x: 0.2 #y3x2y1x2
id: download_code
BoxLayout:
Label:
size_hint_x: 0.4 #y3x2y2x1
text: '写真とビデオを合体'
CheckBox:
size_hint_x: 0.1 #y3x2y2x2
id: checkbox
active: False
Label:
size_hint_x: 0.3 #y3x2y2x3
text: 'ビデオのタイプ'
TextInput:
size_hint_x: 0.2 #y3x2y2x4
id: format_type
BoxLayout:
Label:
size_hint_x: 0.25 #y3x2y3x1
text: '保存先'
TextInput:
size_hint_x: 0.75 #y3x2y3x2
id: save_place
text: "%(title)s.%(ext)s"
Button:
size_hint_x: 0.2 #y3x3
text: "GET!!"
on_press: root.buttonClicked2()
BoxLayout:
size_hint_y: 0.1 #y4
Label:
id: status
text: 'status:'
かなり粗い作りですが、今後に期待ということで。。。
使用方法
Visual Studio Codeなどを使って開いたらこんな感じの画面が出てくると思います。
①のYouTubeとあるところはダウンロードしたいサイトを選択できます。とりあえずYoutubeとニコニコ動画、それ以外はその他としてください。
空白のところにダウンロードしたいURLを入力してください。
検索を押すと②のところにいろいろ出てきます。
その際に一番したのところがstatus: OKとなっているか確認してください。
その後、③の一番上の空白にダウンロードしたいものの数字を入力してください。その後GETを押してください。成功すればstatus: OKのままです。
ダウンロード名は「動画のタイトル.フォーマット」となります。
ダウンロード先はファイルがあるところになります。変更したい場合はパスを入力すればいいです。
失敗しているとstatus: ERRORになります。大抵はURLが変だったりします。
もし、動画・音楽を一緒に合わせてダウンロードしたい場合は、「写真とビデオを合体」にチェックをいれ、ビデオのタイプを指定すれば同時にダウンロードできます。