Skip to content
Advertisement

pytube (python) video stops playing video after few seconds

I have been using pytube to create my youtube video downloader and after the video is done downloading and compiling and i play it, it plays for only a few seconds then just displays a still image while the audio continues in background

These are the functions in file “module.py”

import pytube
from moviepy.editor import *
import os.path

def video(link):
    yt = pytube.YouTube(link)
    streamlist = []
    for stream in yt.streams.filter():
        streamlist.append(stream)
    finalstreamlist = []
    for i in streamlist:
        if i.resolution == "1080p" and i.mime_type == "video/mp4":
            finalstreamlist.append(i)
    stream = yt.streams.get_by_itag(finalstreamlist[0].itag)
    stream.download(r"C:UserspcPycharmProjectsyoutube")
    return [stream.title, yt.length]

def audio(link):
    yt = pytube.YouTube(link)
    streamlist = []
    for stream in yt.streams.filter():
        streamlist.append(stream)
    finalstreamlist = []
    for i in streamlist:
        if i.mime_type == "audio/mp4":
            finalstreamlist.append(i)
    stream = yt.streams.get_by_itag(finalstreamlist[0].itag)
    stream.download(r"C:UserspcPycharmProjectsyoutube", "Audio.mp4")
    return ["Audio.mp4",yt.length]


def mixer(video,audio,title):
    videoclip = VideoFileClip(video)
    audioclip = AudioFileClip(audio)
    videoclip2 = videoclip.set_audio(audioclip)
    videoclip2.write_videofile(title)

And this is the “main.py” file:

from modules import *
import time
link = "https://www.youtube.com/watch?v=CLk7A7HXhYQ"

vtitle = video(link)[0] + ".mp4"
atitle = audio(link)[0]
print("Files Downloaded")
time.sleep(1)
print("Compiling")

mixer(vtitle,atitle,vtitle)
print("FileDone")

Advertisement

Answer

I tried your code and it downloads video file correctly but problem is when it mixs video and audio.

I think problem it that it writes new video with the same name as original video – probably it doesn’t load old video to memory but it reads it all time from file – and this makes conflict.

I think you should write new video with new (temporary) filename and later rename it to expected name. Or you should download video with temporary name (i.e. video.mp4)


My code which I used for tests

import pytube
from moviepy.editor import *
import os

BASE = os.path.dirname(os.path.abspath(__file__))

def video(link):
    yt = pytube.YouTube(link)
    
    finalstreamlist = yt.streams.filter(resolution='1080p', mime_type='video/mp4')
    
    itag = finalstreamlist[0].itag
    print('video itag:', itag)
    
    stream = yt.streams.get_by_itag(itag)
    stream.download(os.path.join(BASE, 'youtube'), 'video.mp4')

    return [os.path.join(BASE, 'youtube/video.mp4'), stream.title, yt.length]

def audio(link):
    yt = pytube.YouTube(link)
    
    finalstreamlist = yt.streams.filter(mime_type='video/mp4')
    
    itag = finalstreamlist[0].itag
    print('audio itag:', itag)
    
    stream = yt.streams.get_by_itag(itag)
    stream.download(os.path.join(BASE, 'youtube'), 'audio.mp4')
    
    return [os.path.join(BASE, 'youtube/audio.mp4'), stream.title, yt.length]

def mixer(video, audio, title):
    videoclip = VideoFileClip(video)
    audioclip = AudioFileClip(audio)
    new_videoclip = videoclip.set_audio(audioclip)
    new_videoclip.write_videofile(title)

# --- main ---

link = 'https://www.youtube.com/watch?v=CLk7A7HXhYQ'

print('Downloading')
v = video(link)
a = audio(link)
print('Downloaded')

print('Compiling')
output = os.path.join(BASE, v[1] + '.mp4')
mixer(v[0], a[0], output)
print('Compilied')
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement