Posted at

YouTubeから動画をダウンロードしてくるGUIツール(Python)


概要

YouTubeから動画をダウンロードしてくる簡単なツールを作りました。

URLを指定するだけで、簡単に動画をmp4形式で保存できます。

このツールではオプションとして、ダウロード先が選択できることだけでなく、音声のみのダウンロードもできます。

以下の画面の左側が、今回作成したツールです。「ダウンロード」ボタンを押した後、右側のフォルダに動画ファイルが追加されているのが見て取れます。

final.gif


用いたツール

GUIの部分は、Tkinterを用いて作成しました。

Tkinterとは簡単に言うと、PythonからGUIを構築し操作するためのライブラリです。

このライブラリについてはこちらの記事を読むとどのようなものかなんとなくつかめると思います。

YouTubeから動画をダウンロードしてくる部分は、pytubeというライブラリを用いて作成しました。

このライブラリは、その名前の通りYouTubeから動画をダウンロードするためのライブラリです。

これに関しては、こちらの記事を見て存在を知り、興味を持ちました。


コード

コードについて記していきます。

今回の作成物のコードは、主に画面表示のための部分と動画ダウンロードのための部分に分けられるため、別々に説明していきます。


画面表示に関わる部分


youtube.py

#画面の表示

def main():
root = Tk()
#タイトル
root.title('Youtube Downloader')
root.minsize(600, 400)

#url記入ボックスのラベル
label1 = Label(text="YoutubeのURL")
label1.pack(pady=10)

#url記入ボックス
y_url_box = Entry(width=50)
y_url_box.pack()

#ダウンロード先記入ボックスのラベル
label2 = Label(text="ダウンロード先のフォルダ(省略可)")
label2.pack(pady=10)

#ダウンロード先記入ボックス
download_location_box = Entry(width=50)
download_location_box.pack()

#音声のみボタン
chk_state = BooleanVar()
chk_state.set(False)
chk = Checkbutton(text='音声のみ', var=chk_state)
chk.pack(pady=10)

#ダウンロードボタン
InputButton = Button(text="ダウンロード",command = lambda : get_youtube(y_url_box.get(),download_location_box.get(),chk_state.get()))
InputButton.pack(pady=20)

#エラーメッセージ表示欄
label2 = Label(text=__ERROR_MESSAGE__)
label2.pack(pady=30)

root.mainloop()

if __name__ == "__main__":
main()


この部分を記述するだけで、以下の画像のような画面が出来上がります。

Screen Shot 2018-10-06 at 2.24.48.png


動画ダウンロードに関わる部分

続いて、動画ダウンロードのためのコードを載せます。


youtube.py

#エラーメッセージ

__ERROR_MESSAGE__ = None

#Youtubeの動画をダウンロードする
def get_youtube(y_url,download_location,audio_only_flg):
#一旦エラーメッセージをクリア
__ERROR_MESSAGE__ = None

#URLの入力に関する例外処理
if type(y_url) != str or y_url == "":
__ERROR_MESSAGE__ = "URLには文字列を入れてください"

#「http://」が省略されて入れば付け加える
if not (y_url.startswith("http://") or y_url.startswith("https://")):
y_url = "http://" + y_url

#ダウンロード先フォルダが省略されて入れば、カレントディレクトリに設定
if download_location == "" or download_location == None:
download_location = "./"

#エラーメッセージが出ていなければ動画を取得する
if __ERROR_MESSAGE__ == None:
youtube = YouTube(y_url)
#動画をダウンロードするとき
if audio_only_flg == False:
youtube.streams.filter(subtype='mp4').first().download(download_location)
#音声のみをダウンロードするとき
else:
youtube.streams.filter(only_audio=True,subtype='mp4').first().download(download_location)



コード全体

上記の二つをまとめると、以下のようになります。


youtube.py

# -*- coding: utf-8 -*-


from pytube import YouTube
import sys
import tkinter
from tkinter import *

#エラーメッセージ
__ERROR_MESSAGE__ = None

#Youtubeの動画をダウンロードする
def get_youtube(y_url,download_location,audio_only_flg):
#一旦エラーメッセージをクリア
__ERROR_MESSAGE__ = None

#URLの入力に関する例外処理
if type(y_url) != str or y_url == "":
__ERROR_MESSAGE__ = "URLには文字列を入れてください"

#「http://」が省略されて入れば付け加える
if not (y_url.startswith("http://") or y_url.startswith("https://")):
y_url = "http://" + y_url

#ダウンロード先フォルダが省略されて入れば、カレントディレクトリに設定
if download_location == "" or download_location == None:
download_location = "./"

#エラーメッセージが出ていなければ動画を取得する
if __ERROR_MESSAGE__ == None:
youtube = YouTube(y_url)
#動画をダウンロードするとき
if audio_only_flg == False:
youtube.streams.filter(subtype='mp4').first().download(download_location)
#音声をダウンロードするとき
else:
youtube.streams.filter(only_audio=True,subtype='mp4').first().download(download_location)

#画面の表示
def main():
root = Tk()
#タイトル
root.title('Youtube Downloader')
root.minsize(600, 400)

#urlボックスのラベル
label1 = Label(text="YoutubeのURL")
label1.pack(pady=10)

#urlボックス
y_url_box = Entry(width=50)
y_url_box.pack()

#ロケーションボックスのラベル
label2 = Label(text="ダウンロード先のフォルダ(省略可)")
label2.pack(pady=10)

#ロケーションボックス
download_location_box = Entry(width=50)
download_location_box.pack()

#オーディオボタン
chk_state = BooleanVar()
chk_state.set(False)
chk = Checkbutton(text='音声のみ', var=chk_state)
chk.pack(pady=10)

#ダウンロードボタン
InputButton = Button(text="ダウンロード",command = lambda : get_youtube(y_url_box.get(),download_location_box.get(),chk_state.get()))
InputButton.pack(pady=20)

#エラーメッセージ表示欄
label2 = Label(text=__ERROR_MESSAGE__)
label2.pack(pady=30)

root.mainloop()

if __name__ == "__main__":
main()



まとめ

ライブラリを活用して、簡単に実用性のあるツールができました。

他にも面白そうなライブラリを見つけたら、また何か物を作って投稿したいと思います。