youtube-dl到exe不起作用

时间:2017-10-26 17:40:36

标签: python python-3.x cx-freeze youtube-dl

这是代码

from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
import youtube_dl
import os



class f(object):
    def __init__(self, finestra):
        self.finestra = finestra
        self.top = ttk.Frame(self.finestra, padding="10 10 10 10")
        self.top.grid(column=5, row=5)
        self.top.columnconfigure(1, weight=1)
        self.top.rowconfigure(1, weight=1)

        self.finestra.bind("<Return>",self.esegui_query)

        self.link = StringVar()
        self.esito = StringVar()
        self.bitrate = StringVar()
        self.esito.set("In Attesa")

        ttk.Label(self.top, text="Link:").grid(column=0,row=0)
        ttk.Entry(self.top, textvariable=self.link).grid(column=1,row=0)
        ttk.Button(self.top, text="Scarica", command=self.esegui_query).grid(column=2,row=0)

        ttk.Label(self.top, text="Bitrate:").grid(column=0,row=1)
        r1 = Radiobutton(self.top, text="192", variable=self.bitrate, value="192", cursor="dot")
        r1.grid(column=1,row=1)
        r2 = Radiobutton(self.top, text="320", variable=self.bitrate, value="320", cursor="dot")
        r2.grid(column=2,row=1)
        r1.select()
        ttk.Label(self.top, textvariable=self.esito).grid(column=3,row=1)

    def esegui_query(self,*argv):
        link = self.link.get()
        bitrate=self.bitrate.get()
        ydl_opts = {
        #'format': 'bestaudio/best',
        'postprocessors': [{
            'key': 'FFmpegExtractAudio',
            'preferredcodec': 'mp3',
            'preferredquality': bitrate,
                        }],
                    }
        self.esito.set("Downloading...")
        try:
            with youtube_dl.YoutubeDL(ydl_opts) as ydl:
                ydl.download([link])
            self.esito.set("Encoding...")
            for file in (os.listdir('.')):
                if file.endswith('.mp3') or file.endswith('.m4a') or file.endswith('.mp4'):
                    file2 = file[::-1][16:][::-1]
                    break
            self.esito.set("Download Completato")
        except Exception as e:
            self.esito.set("ERRORE")
            messagebox.showwarning("ERRORE",e)



finestra = Tk()
finestra.title("Download Youtube")
f = f(finestra)
finestra.mainloop()

此代码适用于我的IDLE python 3.6 x86,但如果我使用cx_Freeze将其转换为.exe

这是要转换的setup.py的代码

from cx_Freeze import setup, Executable
import os,sys
os.environ['TCL_LIBRARY'] = r'C:\Program Files (x86)\Python36-32\tcl\tcl8.6'
os.environ['TK_LIBRARY'] = r'C:\Program Files (x86)\Python36-32\tcl\tk8.6'

#includes = ["youtube_dl","tkinter","os"]
include_files = [r'C:\Program Files (x86)\Python36-32\DLLs\tcl86t.dll',\
             r'C:\Program Files (x86)\Python36-32\DLLs\tk86t.dll']

base = 'Win32GUI' if sys.platform == 'win32' else None


executables = [Executable("youtube.py", base=base)]

packages = ["youtube_dl","tkinter","os"]
options = {
    'build_exe': {

        #'packages':packages,
        #'includes':includes,
        'include_files':include_files,
    },

}

setup(
    name = "youtube",
    options = options,
    version = "1.0",
    description = 'download from youtube',
    executables = executables
)

可执行文件返回给我这个错误:“'NoneType'对象没有属性'write'” 当代码执行此行时会发生这种情况:

with youtube_dl.YoutubeDL(ydl_opts) as ydl:
    ydl.download([link])  <-----

我认为是因为youtube_dl首先下载了一首mp4版本的歌曲并在进行转换后。它首先下载并写入mp4版本中的歌曲文件夹,我认为有问题,将其转换为mp3并删除mp4版本。

我认为该错误在该行中,因为已经插入了一些像这样的消息框:

try:
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        messagebox.showwarning("ERRORE",'1') <--- this is showed
        ydl.download([link])
        messagebox.showwarning("ERRORE",'2') <--- this is not showed
    self.esito.set("Encoding...")
    for file in (os.listdir('.')):
        if file.endswith('.mp3') or file.endswith('.m4a') or file.endswith('.mp4'):
            file2 = file[::-1][16:][::-1]
            break
    self.esito.set("Download Completato")
except Exception as e:
    self.esito.set("ERRORE")
    messagebox.showwarning("ERRORE",e)

当我执行.exe时,脚本启动但是在我点击下载一首歌后,脚本只显示

messagebox.showwarning("ERRORE",'1')

和错误

'NoneType' object has no attribute 'write'

所以他似乎停在那条线上

ydl.download([link])

1 个答案:

答案 0 :(得分:0)

我解决了下载youtube-dl.exe for windows并使用它下载歌曲

cmd = [d+r'\bin\youtube-dl.exe', '-x', '--audio-format=mp3', 
       r'-o'+d+'\download\%(title)s.%(ext)s',
       '--audio-quality=%s' % (bitrate),
       '%s' % (link)
      ] 

subprocess.call(cmd, shell=mshell)