Closed6

pythonでyt-dlpのGUIソフトを作るメモ

samenokosamenoko

このスクラップは適当に書いていくのでわかりにくいところあっても知らん。
↓環境としては以下の通り↓

  • LinuxMint 22
  • Python3.10.9

普通にWindowsでも動きます。macは知らね。
あとffmpegが必須なのでaptなりwingetなりでインストールしておくように。

samenokosamenoko

使うライブラリについては以下の通り。

  • flet(GUI用)
  • yt-dlp
    これ以外はいらないです。

fletは適当に書いててもいい感じの見た目になるのでありがたいです。
インストールは

ターミナル
pip install yt-dlp flet

でOK。

samenokosamenoko

書いていきます。fletの基本については
https://flet.dev/docs/
を読んで頂くとして。(あんま難しくない)
まず適当な場所にディレクトリを作ってそこでエディタを開きます。
んでmain.pyとか適当な名前のpyファイルを作成。
中身はとりあえずで次にしておく。

import flet as ft

def main(page:ft.Page):
    page.title = "hello"

    page.add(
        ft.Text("Hello",size=24)
    )

ft.app(target=main)

これを実行すると

こんなウィンドウが出てきます。ここまでOKですか?

samenokosamenoko

では本格的に書いていきますか。機能としては「保存先の選択」と「動画+音声or音声のみの選択」くらいあれば十分でしょってことでそこに絞ります。
コードは次の通り。コメント書けない。。。

main.py
import flet as ft
import os
import re
from yt_dlp import YoutubeDL

# デフォルトの保存先
home = os.path.expanduser('~')
output_path = home+"/yt-dlp"

def main(page:ft.Page):
    page.title = "yt-dlpGUI"

    def select_output(e:ft.FilePickerResultEvent):
        global output_path
        before = output_path
        output_path = e.path if e.path else before
        path_input.value = output_path
        path_input.update()

    def download(e):
        url = url_input.value

        print(f'{mode_select.value}')

        if url:
            ydl_opts = {
                'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]',
                'outtmpl': f'{output_path}/%(title)s.%(ext)s',
                'color': 'no_color',
                'postprocessors': []
            }
            if mode_select.value == "video":
                ydl_opts["format"] = 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]'
            elif mode_select.value == 'audio':
                ydl_opts["format"] = "bestaudio"
                ydl_opts["postprocessors"] = [{
                    'key': 'FFmpegExtractAudio',
                    'preferredcodec': 'mp3'
                }]
            
            download_button.disabled = True
            download_button.text = "ダウンロード中"
            download_button.update()
            info_text.value = "ダウンロードを開始しています"
            info_text.update()

            try:
                with YoutubeDL(ydl_opts) as ydl:
                    info = ydl.extract_info(url,download=False)
                    title = info.get('title','タイトル取得できません')
                    info_text.value = f"{title}をダウンロード中"
                    info_text.update()
                    ydl.download([url])
                
                info_text.value = "完了しました"
                info_text.update()
            except Exception as e:
                info_text.value = f"エラーが発生しました: {e}"
                info_text.update()
            finally:
                download_button.disabled = False
                download_button.text = "ダウンロード"
                download_button.update()
        else:
            info_text.value = "URLを入力してください"
            info_text.update()

    
    path_dialog = ft.FilePicker(on_result=select_output)
    page.overlay.append(path_dialog)

    url_input = ft.TextField(hint_text="URLを入力",label="URL",icon=ft.icons.MOVIE)
    path_input = ft.TextField(value=output_path,hint_text="保存先を選択",label="保存先",icon=ft.icons.FOLDER,expand=True,read_only=True)
    path_button = ft.TextButton("選択",icon=ft.icons.FOLDER,on_click=lambda _:path_dialog.get_directory_path(dialog_title="保存先を選択"))
    mode_select = ft.Dropdown(label="モード",options=[ft.dropdown.Option(key="video",text="動画(mp4)"),ft.dropdown.Option(key="audio",text="音声のみ(mp3)")])
    info_text = ft.Text()
    download_button = ft.FloatingActionButton("ダウンロード",icon=ft.icons.DOWNLOAD,on_click=download)

    page.add(
        url_input,
        ft.Row([path_input,path_button]),
        mode_select,
        info_text,
        download_button
    )

ft.app(target=main)

見た目
見た目もこんな感じになります。

samenokosamenoko

実際にURLを入れてダウンロードボタンを押すと

ターミナルにはログが出てダウンロード中の動画タイトルが出てるはず。

ちゃんと保存されます。

こんなものです。

samenokosamenoko

以上

これに機能を付け加えて行けば画質・音質の選択だったりクッキー選択ができたりなんかもします。(今回はめんどくさいから省略)
自分用に適当に作っただけのものの更に省略版です。

著作権には気をつけてね。

このスクラップは1ヶ月前にクローズされました