【無料】いろんなサイトの動画・音楽をダウンロードするアプリ作ったよ(python)
スポンサーリンク

今回はpythonを使った動画・音楽をダウンロードする仕組みを作ってみました。

スポンサーリンク

環境

OSmac OS Catalina 10.15
Python3.7.3
subprocess標準ライブラリ
Kivy1.11.1
japanese-kivy0.1.1
youtube-dl2019.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

python コピー

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

kv コピー

###:kivy
<GetiaWidget>:
    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が変だったりします。

もし、動画・音楽を一緒に合わせてダウンロードしたい場合は、「写真とビデオを合体」にチェックをいれ、ビデオのタイプを指定すれば同時にダウンロードできます。

スポンサーリンク

Twitterでフォローしよう

おすすめの記事