kelvinkuoch
kelvinkuoch

Reputation: 11

Trouble finding path to mp4 file

I started a project a day ago where you can choose to download any Youtube video using the pytube library, problem is that it does not support mp3 files, so I tried using moviepy and it was not successful.

Here's my code,

def download_video():
    link = url.get()
    yt = YouTube(link)
    if audio_download.get() == 1:
        t=yt.streams.filter(only_audio=True)
        t[0].download(dir)
        mp4_file = (dir + yt.title + '.mp4')
        mp3_file = (dir + yt.title + '.mp3')
        video = VideoFileClip(mp4_file)
        audioclip = video.audio
        audioclip.write_audiofile(mp3_file)
        video.close()
        audioclip.close()

And here is the project error,

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Users\kelvi\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
    return self.func(*args)
  File "c:\Users\kelvi\Documents\Code\youtubedownloader.py", line 28, in download_video
    video = VideoFileClip(mp4_file)
  File "C:\Users\kelvi\AppData\Local\Programs\Python\Python39\lib\site-packages\moviepy\video\io\VideoFileClip.py", line 88, in __init__
    self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt,
  File "C:\Users\kelvi\AppData\Local\Programs\Python\Python39\lib\site-packages\moviepy\video\io\ffmpeg_reader.py", line 35, in __init__
    infos = ffmpeg_parse_infos(filename, print_infos, check_duration,
  File "C:\Users\kelvi\AppData\Local\Programs\Python\Python39\lib\site-packages\moviepy\video\io\ffmpeg_reader.py", line 270, in ffmpeg_parse_infos
    raise IOError(("MoviePy error: the file %s could not be found!\n"
OSError: MoviePy error: the file C:/Users/kelvi/Documents/Video/Alicia Keys - If I Ain't Got You (Official Video).mp4 could not be found!
Please check that you entered the correct path.

Here is the full code

from tkinter import *
from tkinter import filedialog
from pytube import YouTube
import time
from moviepy.editor import *

# Setup
root = Tk()
root.title("Youtube Downloader")
root.resizable(0,0)
audio_download = IntVar()
root.iconbitmap("logo.ico")

with open("directory.txt", 'r') as File:
    dir = File.read()
    File.close()

# Functions

def download_video():
    link = url.get()
    yt = YouTube(link)
    if audio_download.get() == 1:
        t=yt.streams.filter(only_audio=True)
        t[0].download(dir)
        mp4_file = (dir + yt.title + '.mp4')
        mp3_file = (dir + yt.title + '.mp3')
        video = VideoFileClip(mp4_file)
        audioclip = video.audio
        audioclip.write_audiofile(mp3_file)
        video.close()
        audioclip.close()
    else:
        t=yt.streams.get_highest_resolution()
        t.download(dir)

def browse_file():
    global dir
    dir = filedialog.askdirectory()
    with open("directory.txt", 'w') as File:
        File.write(dir + '/')
        File.close()

# Layout
header = Label(root,text="Youtube Downloader", font="Arial 28 bold",) 
header.grid(row=0,column=0)
url = Entry(root, width=60)
url.grid(row=1,column=0)
audio_only = Checkbutton(root, text="Audio Only?", variable=audio_download, onvalue=1, offvalue=0)
audio_only.grid(row=1, column=1)
browse = Button(root,text="Browse", width=10,command=browse_file)
browse.grid(row=2, column=1)
button = Button(root, text="Download", width=30,command=download_video)
button.grid(row=2,column=0)
root.mainloop()

Upvotes: 0

Views: 511

Answers (1)

Stepan
Stepan

Reputation: 619

Problem: yt.title is not equal to the saved filename because pytube uses function safe_filename() on the video title before saving. In your case safe_filename() deleted apostrophe ' from the filename.

Solution

add

from pytube.helpers import safe_filename

change

yt.streams.filter(only_audio=True)

mp4_file = (dir + yt.title + '.mp4')
mp3_file = (dir + yt.title + '.mp3') 

to

yt.streams.filter()

mp4_file = (r"{}{}{}".format(dir, safe_filename(yt.title), '.mp4'))
mp3_file = (r"{}{}{}".format(dir, safe_filename(yt.title), '.mp3'))

or just download mp4 without audio and rename it to mp3

import os

inside if you should have something like

t = yt.streams.filter(only_audio=True)
t[0].download(dir)
mp4_file = (r"{}{}{}".format(dir, safe_filename(yt.title), '.mp4'))
mp3_file = (r"{}{}{}".format(dir, safe_filename(yt.title), '.mp3'))
os.rename(mp4_file, mp3_file)

Upvotes: 1

Related Questions