How to add "pytube" downloading info to tqdm Progress Bar? - python

I am trying make a YouTube video downloader.
I want make a progress bar while downloading the YouTube video but I cant get any info (how many MB have been downloaded or how many video MB).
I don't know if this is possible with python or not. Here is my code so far:
import time , os
from pytube import YouTube
from tqdm import tqdm
al = str(input("C4ommand:"))
if al == "4":
af = input("Link:")
you = YouTube(af)
try:
os.mkdir("Download")
except:
pass
time.sleep(2)
time.sleep(1)
res = you.streams.get_highest_resolution()
a = res.download()
with tqdm(total=100) as pbar:
for i in range(10):
time.sleep(0.5)
pbar.update(10)
print(af + "Link downloading....")
b = open("\Download", "w")
b.write(a)
b.close()
print("Downloaded")

To access the progress of the download, you can use the on_progress_callback argument when creating a YouTube instance.
The pytube quickstart says the following:
The on_progress_callback function will run whenever a chunk is downloaded from a video, and is called with three arguments: the stream, the data chunk, and the bytes remaining in the video. This could be used, for example, to display a progress bar.
from pytube import Stream
from pytube import YouTube
from tqdm import tqdm
def progress_callback(stream: Stream, data_chunk: bytes, bytes_remaining: int) -> None:
pbar.update(len(data_chunk))
url = "http://youtube.com/watch?v=2lAe1cqCOXo"
yt = YouTube(url, on_progress_callback=progress_callback)
stream = yt.streams.get_highest_resolution()
print(f"Downloading video to '{stream.default_filename}'")
pbar = tqdm(total=stream.filesize, unit="bytes")
path = stream.download()
pbar.close()
print(f"Saved video to {path}")
Sample output:
Downloading video to 'YouTube Rewind 2019 For the Record YouTubeRewind.mp4'
100%|██████████████████████████████| 87993287/87993287 [00:17<00:00, 4976219.51bytes/s]
Saved video to /tmp/testing/YouTube Rewind 2019 For the Record YouTubeRewind.mp4
Pytube has a built-in progress bar, but it does not use tqdm. Please see https://stackoverflow.com/a/60678355/5666087 for more information.

Related

The solution for Failed to send close message

I am using opencv to load a live video from youtube, but the program terminates in the middle with a "Failed to send close message".
I would like to keep getting images 24 hours a day, all the time, and I would like to know what is the best way to do this.
import pafy
import cv2
url = "https://www.youtube.com/watch?v=_9OBhtLA9Ig"
video = pafy.new(url)
best = video.getbest(preftype="mp4")
capture = cv2.VideoCapture(best.url)
while True:
grabbed, frame = capture.read()
# ...

Detect the end of a song using Spotipy

I'm using Spotipy and LyricsGenius to open lyrics on a web browser from a terminal.
I can open a url for one song, but have to run the script each time to run consecutively. What are some ways to detect the end of a song using Spotipy?
import spotipy
import webbrowser
import lyricsgenius as lg
...
# Create our spotifyObject
spotifyObject = spotipy.Spotify(auth=token)
# Create out geniusObject
geniusObject = lg.Genius(access_token)
...
while True:
currently_playing = spotifyObject.currently_playing()
artist = currently_playing['item']['artists'][0]['name']
title = currently_playing['item']['name']
search_query = artist + " " + title
# if (currently_playing has changed):
song = geniusObject.search_songs(search_query)
song_url = song['hits'][0]['result']['url']
webbrowser.open(song_url)
webbrowser.open(song_url)
I was reading relevant threads such as this, this, and read through documentation but could not find an answer to my question if this could be handled by Spotipy. I would appreciate any suggestions, thank you.
I used time.sleep(length) with the argument 'length' standing for the remaining duration of a current track.

Is there a way to get YT url or video ID from playlist with pafy?

I am trying to make a program that takes YT playlist and play all it's content.
I've installed all components needed for pafy to run with python3. Everything I've tried works as it's expected, except the bellow part of the code.
plurl = "https://www.youtube.com/playlist?list=PL634F2B56B8C346A2"
playlist = pafy.get_playlist(plurl)
url = playlist['items'][21]['pafy'].getbest().url
video = pafy.new(url)
When pafy.new() is called, gives an error because of too long url:
Need 11 character video id or the URL of the video. Got https://r2---sn-bavc5aoxu-nv4l.googlevideo.com/videoplayback?ms=au%2Crdu&sparams=clen%2Cdur%2Cei%2Cgir%2Cid%2Cinitcwndbps%2Cip%2Cipbits%2Citag%2Clmt%2Cmime%2Cmm%2Cmn%2Cms%2Cmv%2Cpl%2Cratebypass%2Crequiressl%2Csource%2Cexpire&mv=m&mt=1554899146&requiressl=yes&ip=37.157.173.53&pl=19&id=o-AGQZkyoEvykUGae7O4v_Ycmuj4jJBYdgafcfLBQ5S4Dd&mn=sn-bavc5aoxu-nv4l%2Csn-nv47lnsr&mm=31%2C29&source=youtube&lmt=1387649403290510&ei=POGtXJzdIo_ugAeEiL_wAQ&c=WEB&key=yt6&mime=video%2Fmp4&gir=yes&itag=18&clen=5461830&fvip=2&expire=1554920860&ratebypass=yes&dur=206.100&initcwndbps=1573750&ipbits=0&signature=AAA8B36CD3B402F587F874956595ACB928806C4F.D36C0A79E7F1727DB872425E696DBFC550AA7DF6
Is there a way I can get normal url or video ID ?
The videoid is also available in the url object. You can use
dir(<object>)
to see what properties are available.
id = playlist['items'][2]['pafy'].videoid
video = pafy.new('https://www.youtube.com/watch?v='+id)
use try and catch before using pafy.new , as some of the videos might not be available in the region.

VLC Media Player API

I am trying to stream an online video using VLC media player. But the URL I'm receiving is random, so that URL needs to be linked to the VLC media player online stream. Is there any APIs that enables the random online video to be played ?
A small understanding of the project that I'm building...
I have a device that will receive the URL from the server and will play it on a screen.
Earlier I was playing it via a web browser. But this time I want it to implement it using a media player.Thus my question, is there any API for VLC media player that can be used to stream online videos?
*** BTW I'm using python to write my scripts.
As wizzwizz4 stated the vlc.py program is available # https://wiki.videolan.org/Python_bindings along with example code for wxpython, pyQt and pyGtk
The documentation is here: https://www.olivieraubert.net/vlc/python-ctypes/doc/
Here is a rough bit of code, which runs from the command line, to give you a start
import requests
import vlc
import time
import os
#Test data a local file, a couple of radio stations and a video to cover all the bases
urls = [
'file:///home/rolf/Music/H5O.mp3',
'http://www.lounge-radio.com/listen128.m3u',
'http://network.absoluteradio.co.uk/core/audio/aacplus/live.pls?service=acbb',
'http://statslive.infomaniak.ch/playlist/energy90s/energy90s-high.mp3/playlist.pls',
'http://streaming.radio.rtl2.fr/rtl2-1-44-128',
'http://clips.vorwaerts-gmbh.de/VfE_html5.mp4'
]
#Define playlist extensions
playlists = set(['pls','m3u'])
#Define vlc playing Status values
playing = set([1,2,3,4])
Instance = vlc.Instance()
# Loop over urls provided
for url in urls:
print ("\n\nLooking for:", url)
# Grab file extension
ext = (url.rpartition(".")[2])[:3]
found = False
# Test if url is a local file or remote
if url[:4] == 'file':
if os.path.isfile(url[7:]):
found = True
else:
print ('Error: File ', url[7:], ' Not found')
continue
else:
try:
r = requests.get(url, stream=True)
found = r.ok
except ConnectionError as e:
print('failed to get stream: {e}'.format(e=e))
continue
if found:
player = Instance.media_player_new()
Media = Instance.media_new(url)
Media_list = Instance.media_list_new([url])
Media.get_mrl()
player.set_media(Media)
# if url is a playlist load list_player else use player
if ext in playlists:
list_player = Instance.media_list_player_new()
list_player.set_media_list(Media_list)
if list_player.play() == -1:
print ("\nError playing playlist")
else:
if player.play() == -1:
print ("\nError playing Stream")
#=========================================================#
# #Use this code for 15 second samples
print ('Sampling ', url, ' for 15 seconds')
time.sleep(15)
#
#=========================================================#
# #Use this code to play audio until it stops
# print ('Playing ', url, ' until it stops')
# time.sleep(5) #Give it time to get going
# while True:
# if ext in playlists:
# state = list_player.get_state()
# if state not in playing:
# break
# else:
# state = player.get_state()
# if state not in playing:
# break
#=========================================================#
if ext in playlists:
list_player.stop()
else:
player.stop()
else:
print ('\nError getting the audio')
If the URL is to the stream / video file, you can just open it directly in VLC like you would anything else. If it's to an HTML document, you'll need to extract the URL of the actual stream.

Can't get a full playlist with pafy

I'm trying to get all the urls of the videos in a playlist.
The playlist contains 700+ videos.
When I create a playlist with pafy.get_playlist it only creates an array with 194 videos, not all of them.
So is there a size limit for the playlist with pafy?
According to this issue on their github page you can just use get_playlist2()
Hello Everyone this is my first answer:)
you can use get_playlist2() as #JalxP said
just checkout the below code and run it.
I think It should solve the problem
Thanks!
import pafy
import sys
import time
url = sys.argv[1] # takes the playlist link as argument
details = pafy.get_playlist(url)
playlist = pafy.get_playlist2(url)
# below three statements print the tilte,author and number of videos
print(details['title'])
print(details['author'])
print(len(playlist))
# path to store the videos
userpath = input("enter path to save the playlist:")
# you can modify this for loop for a particular range of videos
# this a bare-bone
# this loop downloads all the videos in the playlist
for item in range(len(playlist)):
url = playlist[item].getbest()
url.download(userpath)
time.sleep(3)# just to not make immediate download calls
import os
from pafy import get_playlist
import pafy
from pafy import *
from socket import *
name_pc=gethostname()
var2=name_pc.split("-")[0] # ex: ("document-PC") -> ["document","PC"]to get #name pc
os.chdir(r"C:\Users\\"+var2+"\\Downloads")
vobj=get_playlist(str(input("Enter a URL :")))
down_path=str(input("Enter a Dir ?: "))
for video in range(len(vobj['items'])):
down=vobj['items'][video]['pafy'].getbest() # to get all items for item in playlist
if 1:
t=r"C:\Users\\"+var2+"\\Downloads"
down.download(t)
else:
down.download(down_path)

Categories

Resources