Как исправить файл .exe загрузчика CustomTkinter YT

Я сделал небольшой проект, используя CustomTkinter и Pytube, для загрузки видео с YouTube с помощью простого графического интерфейса.

Программа не имеет ошибок при запуске в виде файла .py в IDE и Windows, если я дважды щелкаю мышью или использую терминал.

Затем я приступил к использованию auto-py-to-exe для преобразования файла в файл .exe. Я следовал инструкциям на веб-сайте CustomTkinter, и, хотя у меня были некоторые проблемы, мне удалось пройти этот процесс.

Однако окончательный файл .exe запускается, но только на мгновение, прежде чем снова закрыться. Запустив .exe из терминала cmd, находящегося в каталоге файла, я смог получить сообщение об ошибке:

Traceback (most recent call last):
File "PyInstaller\hooks\rthooks\pyi_rth_pkgres.py", line 158, in <module>
File "PyInstaller\hooks\rthooks\pyi_rth_pkgres.py", line 36, in _pyi_rthook
File "PyInstaller\loader\pyimod02_importers.py", line 419, in exec_module
File "pkg_resources\__init__.py", line 77, in <module>
ModuleNotFoundError: No module named 'pkg_resources.extern'
[55288] Failed to execute script 'pyi_rth_pkgres' due to unhandled exception!

Я не смог найти решение этой проблемы и поэтому оказался здесь.

Знаете ли вы, что может быть причиной этой ошибки? или действительно ли это является причиной того, что программа не работает должным образом?

Полный код:

import tkinter
import customtkinter
#from pytubefix import YouTube
from tkinter import filedialog
from moviepy.editor import *
from pathvalidate import sanitize_filename
#from pytubefix import Playlist
#from pytubefix.cli import on_progress\
from pytube import *


app = customtkinter.CTk(fg_color = "black")
app.geometry("700x550")
app.title("YouTube Download")
app.after(201, lambda :app.iconbitmap("normally would show the path to the file but removed for privacy"))

font = customtkinter.CTkFont(family='Trade Gothic LT Bold Condensed No. 20', size=30)
font2 = customtkinter.CTkFont(family='Trade Gothic LT Bold Condensed No. 20', size=20)
menu = ''
currenttype = ''


def MainMenuGUI():
    menu = 'main'

    title.grid_forget()
    finishLabel.grid_forget()
    Vprogbar.grid_forget()
    link.grid_forget()
    download.grid_forget()
    backbutton.grid_forget()
    pPercent.grid_forget()

    app.grid_rowconfigure(0, weight=1)
    app.grid_rowconfigure(1, weight=1)
    app.grid_rowconfigure(2, weight=1)
    app.grid_columnconfigure(0, weight=1)
    app.grid_columnconfigure(1, weight=1)

    WhatLabel.grid(row=0, column=0, columnspan=2, padx=100, pady=50)
    Videobutton.grid(row=1, column=1, sticky=customtkinter.W, padx=50)
    AudioButton.grid(row=1, column=0, sticky=customtkinter.E, padx=50)
    PVideobutton.grid(row=2, column=1, sticky=customtkinter.W, padx=50, pady=50)
    PAudioButton.grid(row=2, column=0, sticky=customtkinter.E, padx=50, pady=50)

def mp4_to_mp3(mp4, mp3):
    mp4_without_frames = AudioFileClip(mp4)
    mp4_without_frames.write_audiofile(mp3)
    mp4_without_frames.close() # function call mp4_to_mp3("my_mp4_path.mp4", "audio.mp3")

def DownloadGUI(dtype):
    global menu
    menu = dtype
    global currenttype
    currenttype = dtype

    WhatLabel.grid_forget()
    Videobutton.grid_forget()
    AudioButton.grid_forget()
    PVideobutton.grid_forget()
    PAudioButton.grid_forget()
    Vprogbar.grid_forget()
    pPercent.grid_forget()
    Pprogbar.grid_forget()

    app.grid_rowconfigure(0, weight=100)
    app.grid_rowconfigure(1, weight=10)
    app.grid_rowconfigure(2, weight=1)
    app.grid_rowconfigure(3, weight=100)

    title.grid(row=0, column=0, columnspan=2, sticky=customtkinter.S)
    link.grid(row=1, column=0, columnspan=2)
    download.grid(row=2, column=0, columnspan=2, sticky=customtkinter.N)
    finishLabel.grid(row=3, column=0, columnspan=2, sticky=customtkinter.N)
    backbutton.grid(row=3, column=1, columnspan=1)

    finishLabel.configure(text='')
    if currenttype == "Video" or currenttype == "Audio":
        title.configure(text = "Insert a YouTube link")
        download.configure(command=lambda: startdownload(dtype=currenttype))
    else:
        title.configure(text = "Insert a playlist link")
        download.configure(command=lambda: startdownloadP(dtype=currenttype))

    link.delete(0, customtkinter.END)

def startdownload(dtype):
    try:
        ytlink = link.get()
        ytobject = YouTube(ytlink, on_progress_callback=Vprog)

        title.configure(text=ytobject.title)
        finishLabel.configure(text = "")

        global menu
        menu = str(dtype) + 'Download'

        path = tkinter.filedialog.askdirectory(initialdir = "/", mustexist=True, parent=app)

        pPercent.grid(row=1, column=0, columnspan=2, sticky=customtkinter.S)
        link.grid_forget()
        download.grid_forget()
        Vprogbar.grid(row=2, column=0, columnspan=2, sticky=customtkinter.N)

        if dtype == "Video":
            video = ytobject.streams.get_highest_resolution()
            video.download(output_path=str(path))

        elif dtype == "Audio":
            audio = ytobject.streams.get_audio_only()

            if os.path.exists(str(path) + "/" + sanitize_filename(audio.title) + ".mp4"):
                audio.download(output_path=str(path), filename=sanitize_filename(audio.title) + "1" + ".mp4")
                clip = AudioFileClip(str(path) + "/" + sanitize_filename(audio.title) + "1" + ".mp4")
                clip.write_audiofile(str(path) + "/" + sanitize_filename(audio.title) + ".mp4"[:-4] + ".mp3")
                clip.close()
                if os.path.exists(str(path)+"/"+sanitize_filename(audio.title) + "1" + ".mp4"):
                    os.remove(str(path)+"/"+sanitize_filename(audio.title) + "1" + ".mp4")
            else:
                audio.download(output_path=str(path), filename=sanitize_filename(audio.title)+".mp4")
                clip = AudioFileClip(str(path)+"/"+sanitize_filename(audio.title)+".mp4")
                clip.write_audiofile(str(path)+"/"+sanitize_filename(audio.title)+".mp4"[:-4] + ".mp3")
                clip.close()
                if os.path.exists(str(path)+"/"+sanitize_filename(audio.title)+".mp4"):
                    os.remove(str(path)+"/"+sanitize_filename(audio.title)+".mp4")



        finishLabel.configure(text = "downloaded", text_color = "white")

    except:
        finishLabel.configure(text = "Download has failed", text_color = "red")
        title.configure(text = "Insert a YouTube link")
        Vprogbar.grid_forget()
        link.grid(row=1, column=0, columnspan=2)

def startdownloadP(dtype):
    vcount = 0
    vccount = 0
    playlink = Playlist(link.get())
    path = tkinter.filedialog.askdirectory(initialdir = "/", mustexist=True, parent=app)

    pPercent.grid(row=1, column=0, columnspan=2, sticky=customtkinter.S)
    ppPercent.grid(row=3, column=0, columnspan=2, sticky=customtkinter.N, pady=20)
    link.grid_forget()
    download.grid_forget()
    Vprogbar.grid(row=2, column=0, columnspan=2, sticky=customtkinter.N)
    Pprogbar.grid(row=3, column=0, columnspan=2, sticky=customtkinter.N, pady=10)

    for _ in playlink.videos:
        vcount += 1

    Pprog(vcount, 0)

    for vid in playlink.videos:
        vccount += 1
        Pprog(vcount, vccount)
        vid.register_on_progress_callback(Vprog)
        title.configure(text=vid.title)

        global menu
        menu = str(dtype) + 'Download'

        if dtype == "VideoPlaylist":
            video = vid.streams.get_highest_resolution()
            video.download(output_path=str(path))

        elif dtype == "AudioPlaylist":
            audio = vid.streams.get_audio_only()

            if os.path.exists(str(path) + "/" + sanitize_filename(audio.title) + ".mp4"):
                audio.download(output_path=str(path), filename=sanitize_filename(audio.title) + "1" + ".mp4")
                clip = AudioFileClip(str(path) + "/" + sanitize_filename(audio.title) + "1" + ".mp4")
                clip.write_audiofile(str(path) + "/" + sanitize_filename(audio.title) + ".mp4"[:-4] + ".mp3")
                clip.close()
                if os.path.exists(str(path) + "/" + sanitize_filename(audio.title) + "1" + ".mp4"):
                    os.remove(str(path) + "/" + sanitize_filename(audio.title) + "1" + ".mp4")
            else:
                audio.download(output_path=str(path), filename=sanitize_filename(audio.title) + ".mp4")
                clip = AudioFileClip(str(path) + "/" + sanitize_filename(audio.title) + ".mp4")
                clip.write_audiofile(str(path) + "/" + sanitize_filename(audio.title) + ".mp4"[:-4] + ".mp3")
                clip.close()
                if os.path.exists(str(path) + "/" + sanitize_filename(audio.title) + ".mp4"):
                    os.remove(str(path) + "/" + sanitize_filename(audio.title) + ".mp4")

    pPercent.grid_forget()
    ppPercent.grid_forget()
    Vprogbar.grid_forget()
    Pprogbar.grid_forget()

    finishLabel.grid(row=2, column=0, columnspan=2, sticky=customtkinter.N)
    finishLabel.configure(text = "All videos downloaded", text_color = "white")


def Vprog(stream, chunk, bytes_remaining):
    total_size = stream.filesize
    bytes_downloaded = total_size - bytes_remaining
    percentage_complete = bytes_downloaded / total_size * 100
    per = str(int(percentage_complete))
    pPercent.configure(text=per + "%")
    pPercent.update()

    Vprogbar.set(float(percentage_complete / 100))

    pPercent.update()
    Vprogbar.update()
def Pprog(total, current):
    percentage_done = current / total * 100
    per = str(int(percentage_done))
    ppPercent.configure(text=per + "%")
    Pprogbar.set(float(percentage_done / 100))
    Pprogbar.update()


def Back():
    if 'Download' in menu:
        DownloadGUI(menu[:-8])
    else:
        MainMenuGUI()



urlvar = tkinter.StringVar()

title = customtkinter.CTkLabel(app, text = "Insert a YouTube link", fg_color='White',corner_radius=10, padx=50, font=font)
link = customtkinter.CTkEntry(app, width=350, height=40, textvariable=urlvar)
finishLabel = customtkinter.CTkLabel(app, text = "", text_color = "white")
pPercent = customtkinter.CTkLabel(app, text = "0%", text_color = "white")
ppPercent = customtkinter.CTkLabel(app, text = "0%", text_color = "white")
Vprogbar = customtkinter.CTkProgressBar(app, width=400, progress_color = "red")
Pprogbar = customtkinter.CTkProgressBar(app, width=400, progress_color = "red")
download = customtkinter.CTkButton(app, text = "Download", command=lambda: startdownload(dtype=currenttype), fg_color = "#e8e6e6", text_color = "black", hover_color='#c0c0c0')
Vprogbar.set(0)
Pprogbar.set(0)

backbutton = customtkinter.CTkButton(app, text_color='black', text = "back", width=50, height=50, fg_color='#333333', hover_color='#c0c0c0', command=Back)

WhatLabel = customtkinter.CTkLabel(app, text = "What would you like to download?", fg_color='White',corner_radius=10, padx=50, font=font)
Videobutton = customtkinter.CTkButton(app, text='Video', width=250, height=150, font=font2, fg_color='#b01214', hover_color='#590404', command=lambda: DownloadGUI(dtype='Video'))
AudioButton = customtkinter.CTkButton(app, text='Audio', width=250, height=150, font=font2, fg_color='#b01214', hover_color='#590404', command=lambda: DownloadGUI(dtype='Audio'))
PVideobutton = customtkinter.CTkButton(app, text='Video Playlist', width=250, height=150, font=font2, fg_color='#b01214', hover_color='#590404', command=lambda: DownloadGUI(dtype='VideoPlaylist'))
PAudioButton = customtkinter.CTkButton(app, text='Audio Playlist', width=250, height=150, font=font2, fg_color='#b01214', hover_color='#590404', command=lambda: DownloadGUI(dtype='AudioPlaylist'))

#https://thewikihow.com/video_cPAlmXHMktA

#https://www.youtube.com/playlist?list=PLpi4n5vOXXFkJxTSD8VRuZ9phHmojXaP1

#https://thewikihow.com/video_Ga2PA-vEiFk

#https://thewikihow.com/video_QU8pe3dhz8s&list=PLpi4n5vOXXFkJxTSD8VRuZ9phHmojXaP1&index=10

MainMenuGUI()

app.mainloop()

Я не знаю, что делать, потому что, честно говоря, у меня не так много знаний о том, что происходит в фоновом режиме библиотек, которые я использую, и поиск в Google проблемы, похоже, не дает ответов.

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
86
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Согласно этому сообщению в блоге, исправить это должно быть легко. Это либо это:

ModuleNotFoundError: нет модуля с именем x / ImportError: нет модуля с именем x

Это означает, что конкретный модуль (в данном случае «x») не был добавлен в пакет. Я видел, как это происходило с пакетами в библиотеке pandas и win32api; если вы можете идентифицировать пакет (например, «x»), его очень легко исправить.

Чтобы исправить это в пользовательском интерфейсе, откройте вкладку «Дополнительно» и найдите входные данные --hidden-import. Просто вставьте имя модуля в это поле ввода, а затем переупакуйте. Если исходная ошибка все еще появляется, вы сделали это неправильно.

Например, если вам не хватает pandas._libs.tslib, добавьте «pandas._libs.tslib» во входные данные с помощью --hidden-import. Дополнительно вы можете добавить более одного модуля, например pandas._libs.tslib, win32api. (Для получения дополнительной информации см. знак вопроса рядом с входными данными).

Или это:

Альтернативно вы можете установить auto-py-to-exe в одной среде Python (одна установка или venv) и установить зависимый пакет в другой среде Python. Ознакомьтесь с «Как управлять несколькими дистрибутивами Python», чтобы узнать, делали ли вы это.

https://nitratine.net/blog/post/issues-when-using-auto-py-to-exe/?utm_source=auto_py_to_exe&utm_medium=readme_link&utm_campaign=auto_py_to_exe_help#modulenotfounderror-no-module-named-x-importerror-no -модуль с именем-x

Спасибо, это мне помогло. поскольку я сделал это в Pycharm, у меня уже была папка Venv с Python и все, что было установлено. все, что мне нужно было сделать, это запустить auto-py-to-exe оттуда, и вуаля, все заработало! Единственная проблема заключается в том, что пока графический интерфейс остается открытым и работает нормально, загрузка не происходит. Думаю, в следующий раз я это исправлю :/

user25175333 23.05.2024 15:42

Другие вопросы по теме