I'm trying to download my video playlist and convert it to mp3 extension using pytube,moviepy,re. Everything works but when it hits a number it stops working.
How can I fix this?
from pytube import YouTube
from pytube import Playlist
import os
import moviepy.editor as mp #to convert the mp4 to wav then mp3
import re
playlist = Playlist("https://www.youtube.com/playlist?list=PLb2p41g_hNVOeBy3OjGTdXKgscedya9f_")
for url in playlist:
print(url)
for vid in playlist.videos:
print(vid)
for url in playlist:
YouTube(url).streams.filter(only_audio=True).first().download("./Downloads/Music_2")
folder = "./Downloads/Music_2"
for file in os.listdir(folder):
if re.search('mp4', file):
print("Converting: " + file)
mp4_path = os.path.join(folder,file)
mp3_path = os.path.join(folder,os.path.splitext(file)[0]+'.mp3')
new_file = mp.AudioFileClip(mp4_path)
new_file.write_audiofile(mp3_path)
os.removed(mp4_path)
Error Code;
Traceback (most recent call last):
File "C:\Users\user\Downloads\Projects\Python\main.py", line 14, in <module>
YouTube(url).streams.filter(only_audio=True).first().download("./Downloads/Music_3")
^^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\Downloads\Projects\Python\venv\Lib\site-packages\pytube\__main__.py", line 296, in streams
return StreamQuery(self.fmt_streams)
^^^^^^^^^^^^^^^^
File "C:\Users\user\Downloads\Projects\Python\venv\Lib\site-packages\pytube\__main__.py", line 176, in fmt_streams
stream_manifest = extract.apply_descrambler(self.streaming_data)
^^^^^^^^^^^^^^^^^^^
File "C:\Users\user\Downloads\Projects\Python\venv\Lib\site-packages\pytube\__main__.py", line 161, in streaming_data
return self.vid_info['streamingData']
~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
KeyError: 'streamingData'
Process finished with exit code 1
I was able to reproduce your issue with the latest pytube version.
More precisely these video ids failed to be downloaded on first trial. However after another trial only the following video ids are still not available for download: bFfSn7RKgwE, pYEwoUgKhV8 and UtF6Jej8yb4. pYEwoUgKhV8 is a members-only video so you are obliged to pay to access it and bFfSn7RKgwE and UtF6Jej8yb4 are just age-restricted, you can access these videos with yt-dlp for instance.
So there is no pytube issue here.
Related
I have a .m3u8 link which I'm trying to download as an .mp3 file.
import m3u8
import subprocess
import requests
link = 'https://cs9-9v4.vkuseraudio.net/s/v1/ac/NeMmHNX2Iyt08MZ4z5fELAMybgSNR6T1xYEcBEv5Kdsenci3KHOAC-1fKapAV9vxwVOBIik40I4DwfrN-a_jtjILYVcx3mLTNCzKo1UF-UhbKOztLrboF9NEn1jzZs1Jl0ijfmccog6aAcB4PcdnrxPzXY7WCMVWtUjWKOgHad5a-g0/index.m3u8'
m3u8_parsed = m3u8.load(link)
with open('track.ts', 'wb') as f:
for segment in m3u8_parsed.segments:
r = requests.get(segment.absolute_uri)
f.write(r.content)
subprocess.run(['ffmpeg', '-i', 'track.ts', 'track.mp3'])
The result is that the track.ts file takes up 6MB storage but doesn't have sound when I try to play it with the VLC Player, while track.mp3 is basically an empty file taking up a couple kilobytes.
You only need FFmpeg to retrieve the audio:
import subprocess
link = 'https://cs9-9v4.vkuseraudio.net/s/v1/ac/NeMmHNX2Iyt08MZ4z5fELAMybgSNR6T1xYEcBEv5Kdsenci3KHOAC-1fKapAV9vxwVOBIik40I4DwfrN-a_jtjILYVcx3mLTNCzKo1UF-UhbKOztLrboF9NEn1jzZs1Jl0ijfmccog6aAcB4PcdnrxPzXY7WCMVWtUjWKOgHad5a-g0/index.m3u8'
subprocess.run(['ffmpeg', '-i', link, 'track.mp3'])
This resulted in a playable mp3 file when I tried it.
I've downloaded some files using requests
url = 'https://www.youtube.com/watch?v=gp5tziO5lXg&feature=youtu.be'
video_name = url.split('/')[-1]
print("Downloading file:%s" % video_name)
# download the url contents in binary format
r = requests.get(url)
# open method to open a file on your system and write the contents
with open('saved.mp4', 'wb') as f:
f.write(r.content)
and using urllib.requests
url = 'https://www.youtube.com/watch?v=gp5tziO5lXg&feature=youtu.be'
video_name = url.split('/')[-1]
print("Downloading file:%s" % video_name)
# Copy a network object to a local file
urllib.request.urlretrieve(url, "saved2.mp4")
When I then try to open the .mp4 file I get the following error
Cannot play
This file cannot be played. This can happen because the file type is
not supported, the file extension is incorrect or the file is
corrupted.
0xc00d36c4
If I test it with pytube it works fine.
What's wrong with the other methods?
To answer your question, with the other methods it is not downloading the video but the page. What you may be obtaining is an html file with an mp4 file extension.
Therefore, it gives that error when trying to open the file.
If pytube works for what you need, I would suggest using that one.
If you want to download videos from other platforms, you might consider youtube-dl.
Hello you can import IPython.display for audio diplay
import IPython.display as ipd
ipd.Audio(video_name)
regards
I hope I can have solved your problem
I'm trying to use google speech_recognition but only works when i use audio files on portuguese, if i use some audio on english gives me that error:
Traceback (most recent call last):
File "C:\Users\deabr_000\Downloads\stt.py", line 16, in <module>
print(r.recognize_google(audio, language="en-US"))
File "C:\Users\deabr_000\AppData\Local\Programs\Python\Python37\lib\site-packages\speech_recognition\__init__.py", line 858, in recognize_google
if not isinstance(actual_result, dict) or len(actual_result.get("alternative", [])) == 0: raise UnknownValueError()
speech_recognition.UnknownValueError
the full code is here:
import speech_recognition as sr
r = sr.Recognizer()
with sr.WavFile('C:/Users/deabr_000/Downloads/something_inside.wav') as source:
audio = r.record(source)
print(r.recognize_google(audio, language="en-US"))
I'm using songs because I need to get the lyrics to do something, I have success with pt-br songs but with any song with another language just dont work
I dont know what the problem is cause with songs that I download from youtube and convert into wav dont work (if the song is pt-br work), but with that audio files works (https://github.com/realpython/python-speech-recognition/tree/master/audio_files)
what the heck can I do?
I am getting an error when writing to an audio file.
Basically, I am overwriting the data in the mp3 whenever my function gets called and then playing it.
It works the first time through, but then gives me [Errno 13] Permission denied: 'file.mp3' then on.
Here is the code:
def speech(self, response):
audio_file = "response.mp3"
tts = gTTS(text=str(response), lang="en")
tts.save(audio_file)
pygame.mixer.init()
pygame.mixer.music.load(audio_file)
pygame.mixer.music.play()
Error is on the tts.save line.
More info:
Traceback (most recent call last):
File "myprojectpath", line 63, in speech
tts.save(audio_file)
File "C:\Python35\lib\site-packages\gtts\tts.py", line 93, in save
with open(savefile, 'wb') as f:
Thanks!
from gtts import gTTS
import playsound
import os
x = ['sunny', 'sagar', 'akhil']
tts = 'tts'
for i in range(0,3):
tts = gTTS(text= x[i], lang = 'en')
file1 = str("hello" + str(i) + ".mp3")
tts.save(file1)
playsound.playsound(file1,True)
print 'after'
os.remove(file1)
change the file name every time you save it, this worked for me.
You should name your file for a unique name each time , so the solution that I realized is to name your file with date like this ==>
date_string = datetime.now().strftime("%d%m%Y%H%M%S")
filename = "voice"+date_string+".mp3"
tts.save(filename)
playsound.playsound(filename)
You can create another file in the same folder, just copy and rename it.
File you want to use: ("C:/.../file.mp3")
copied file: ("C:/.../file_copy.mp3")
You can change the file loaded in mixer.music.load("C:/.../file.mp3") to mixer.music.load("C:/.../file_copy.mp3") and delete delete the ("C:/.../file.mp3") without problem using this:
from pygame import mixer
import os
mixer.music.load("C:/.../file.mp3")
mixer.music.play()
mixer.music.load("C:/.../file_copy.mp3")
os.remove("C:/.../file.mp3")
but the code above will remove the file before even playing it, so you can use a method to await it play:
from pygame import mixer
import os
mixer.music.load("C:/.../file.mp3")
mixer.music.play()
while mixer.music.get_busy(): # check if the file is playing
pass
mixer.music.load("C:/.../file_copy.mp3")
os.remove("C:/.../file.mp3")
try to save the fi open an other file whitout playing, then you will have the permission to delete it here is the talk function:
def Talk (mytext, language= "fr" ):
myobj = gTTS(text=mytext, lang=language, slow=False)
myobj.save("1.mp3")
mixer.init()
mixer.music.load("1.mp3")
mixer.music.set_volume(1)
mixer.music.play()
mixer.music.get_endevent()
while mixer.music.get_busy():
continue
mixer.music.load("Talker\empty.mp3")
os.remove("1.mp3")
You are getting this error because the mixer is not releasing that audio file. If you want to mixer release that file you can load a useless or empty file into a mixer. Then you can overwrite that audio file.
E. g.. Mixer.load("C:/...../empty.mp3")
After this previously loaded file is released.
if you don't want the file before saved anymore, you can delete the audio file before saving the next file. so, you can save the new file with the same name.
bellow is the code I ran successfully
import speech_recognition as ram
from playsound import playsound
from gtts import gTTS
import os
r=ram.Recognizer()
with ram.Microphone() as source:
while True:
r.adjust_for_ambient_noise(source,duration=1)
print("I'm Listening....")
playsound('audio/listen.mp3')
audio=r.listen(source, timeout=5)
text=r.recognize_google(audio)
tts = gTTS("Boss. you said "+str(text)+". i'm opening it")
tts.save('audio/text.mp3')
print("you said "+text+".")
playsound('audio/text.mp3')
os.remove('audio/text.mp3')
a much better solution is this, if i had the time i would also calculate the probability of ever landing a same file
from gtts import gTTS
from playsound import playsound
import random
import os
#creating a super random named file
r1 = random.randint(1,10000000)
r2 = random.randint(1,10000000)
randfile = str(r2)+"randomtext"+str(r1) +".mp3"
tts = gTTS(text='hey, STOP It!!', lang='en', slow=True)
tts.save(randfile)
playsound(randfile)
print(randfile)
os.remove(randfile)
I have faced the same problem, then figure it out that the file is pointing to the previous position so I have to release it. It works fine and important thing is that it does not create an mp3 file also. If you don't release it, it will work fine for the first time and save the audio file then the error occurs for the second time.
from gtts import gTTS
import os
import playsound
def tts(text, lang):
file = gTTS(text = text, lang = lang)
file.save("audio/speak_func.mp3")
playsound.playsound('audio/speak_func.mp3', True)
os.remove("audio/speak_func.mp3")
Basically what i want is TTS in python 3...
I already tried pyttsx but aparently it only works with python 2
I already tried other things too...
Now i'm trying with the api from voicerss.org but i can't figure out how can HTTP GET it and then play it with python with pyglet...
here is my code so far:
import pyglet
import urllib3
http = urllib3.PoolManager()
speechrequest = http.request('GET', 'http://api.voicerss.org/?key=04f49802d32d442ca997d4d2ea76d3d5&hl=pt-pt&c=wav&src=texto')
speech = pyglet.media.load(speechrequest)
speech.play()
pyglet.app.run()
The errors are:
Traceback (most recent call last):
File "C:/Users/Diogo/Documents/test.py", line 6, in <module>
speech = pyglet.media.load(speechrequest)
File "C:\Users\Diogo\AppData\Local\Programs\Python\Python35\lib\site-packages\pyglet\media\__init__.py", line 1429, in load
source = get_source_loader().load(filename, file)
File "C:\Users\Diogo\AppData\Local\Programs\Python\Python35\lib\site-packages\pyglet\media\__init__.py", line 1410, in load
return riff.WaveSource(filename, file)
File "C:\Users\Diogo\AppData\Local\Programs\Python\Python35\lib\site-packages\pyglet\media\riff.py", line 185, in __init__
file = open(filename, 'rb')
TypeError: invalid file: <urllib3.response.HTTPResponse object at 0x0000002EB0730D30>
i guess its not returning an wav file to python don't know why because. If i enter 'http://api.voicerss.org/?key=04f49802d32d442ca997d4d2ea76d3d5&hl=pt-pt&c=wav&src=texto' in internet explorer it returns a wav file...
So, my questions are:
what i am doing wrong with the code or if is impossible this way how can python speak?
Please be patient with me, i'm only 18 years old and i can't speak english properly, because i'm portuguese...
You could save the remote wav file locally and play it using a default application:
#!/usr/bin/env python3
from urllib.request import urlretrieve
import webbrowser
filename = 'speech.wav'
urlretrieve("http://api.voicerss.org/?key=04f49802d32d442ca997d4d2ea76d3d5"
"&hl=pt-pt&c=wav&src=texto", filename)
webbrowser.open(filename) # play the file using default application
On Windows, you could use os.startfile() instead of webbrowser.open() or to play the wav file directly in Python without an external application:
import winsound
winsound.PlaySound('speech.wav', winsound.SND_FILENAME)
Your code have at least two issues:
You should pass a filename (a string) to pyglet.media.load() function, not an HTTPResponse object.
pyglet may fail to play it anyway: I get pyglet.media.riff.RIFFFormatException: Size of format chunk is incorrect. error on my system.
You could also play a remote wav file without saving it to disk i.e., you can play streaming content:
#!/usr/bin/env python3
from urllib.parse import quote
from urllib.request import urlopen
api_key = open('api.key', encoding='ascii').read().strip()
language = 'pt-pt'
text = quote("1 2 3")
playwav(urlopen('https://api.voicerss.org/?c=wav&f=8khz_8bit_mono&ssml=false&'
'key={api_key}&src={text}&hl={language}'.format(**vars())))
where playwav():
import wave
from contextlib import closing
import pyaudio # Windows: py -m pip install pyaudio
# $ sudo apt-get install python{,3}-pyaudio
player = None
def playwav(path_or_file):
global player
if player is None:
player = pyaudio.PyAudio()
with closing(wave.open(path_or_file, 'rb')) as wavfile, \
closing(player.open(
format=player.get_format_from_width(wavfile.getsampwidth()),
channels=wavfile.getnchannels(),
rate=wavfile.getframerate(),
output=True)) as stream:
while True:
data = wavfile.readframes(1024) # read 1024 frames at once
if not data: # EOF
break
stream.write(data)