I'm interested in creating a python 3.9 program that streams audio from a YouTube livestream but unfortunately I can't get the video.getbestaudio() function to work and the function only returns the value null. Thus causing the null error on the next line.
Just in case you need to know I'm using the Pafy library to get the audio stream and the python-vlc library to play the audio. The script is also fully functional if I use a YouTube video that is not a livestream or use the video.getbest() function but this also creates a window displaying the video stream which is not what I want.
I was wondering how I could work around the error and create a functioning python script. I am open to use other methods if they properly work. Thanks for any help in advance!
Here is the error:
Traceback (most recent call last):
File "C:\Users\mjten\Desktop\Programing\Python\lofi.py", line 8, in <module>
playurl = best.url
AttributeError: 'NoneType' object has no attribute 'url'
Here is my code:
import pafy
import vlc
url = 'https://www.youtube.com/watch?v=5qap5aO4i9A'
video = pafy.new(url)
best = video.getbestaudio()
playurl = best.url
player = vlc.MediaPlayer(playurl)
player.play()
while True: pass
P.S Sorry for the bad code I'm just trying to figure out a working example in the meantime.
pip install pafy
pip install youtube_dl
import pafy
def stream(url):
video = pafy.new(url, ydl_opts={'nocheckcertificate': True})
print(video)
best = video.getbestaudio()
stream_urls = best.url
print(stream_urls)
stream('https://www.youtube.com/watch?v=5qap5aO4i9A')
Related
import vlc
p = vlc.MediaPlayer("https://www.youtube.com/watch?v=7ailmFB38Rk")
p.play()
gives me this error
[00007f97a80030c0] http stream error: local stream 1 error: Cancellation (0x8)
I was told this is causes if the link is invalid or broken, both of these are not the cases because using regular vlc to play the video works perfectly
Also, if it is somehow not possible to play the video, I only need to play the audio so that will also be of help.
use pafy
# importing vlc module
import vlc
# importing pafy module
import pafy
# url of the video
url = "https://www.youtube.com/watch?v = vG2PNdI8axo"
# creating pafy object of the video
video = pafy.new(url)
# getting best stream
best = video.getbest()
# creating vlc media player object
media = vlc.MediaPlayer(best.url)
# start playing video
media.play()
I'm starting learning basic feature extraction with librosa and was trying reading and storing ten kick drums with pathlib, but it doesn't work since I always getting an encoding error, where as there is no error without pathlib.
I tried changing the path, updating every imported library very often, using wav instead of mp3 but had no further idea.
My code:
%matplotlib inline
from pathlib import Path
import numpy, scipy, matplotlib.pyplot as plt, sklearn, urllib, IPython.display as ipd
import librosa, librosa.display
kick_signals = [
librosa.load(p)[0] for p in Path().glob('audio/drum_samples/train/kick_*.mp3')
]
Error messages:
RuntimeError: Error opening 'audio/techno-nine_o_three.mp3': File contains data in an unknown format.
and
AttributeError: 'PosixPath' object has no attribute 'encode'
I would be very thankful, if you would and could help me.
You can convert the PossixPath object to a string, using p.as_posix()
Example:
p = Path(file_path)
p.as_posix()
Try:
kick_signals = [
librosa.load(p.absolute())[0] for p in Path().glob('audio/drum_samples/train/kick_*.mp3')
]
That way you pass a string instead of a PosixPath to librosa.
If that does not fix it, check your mp3 file. Does it play in a regular player? If not, please post the whole error message (stacktrace). Perhaps librosa's dependencies aren't installed properly.
I'm using the library moviepy on Linux Mint 18.1.
Specifically, it's moviepy 0.2.3.2 on python 3.5.2
Since I'm getting started, I tried this simple script, which should concatenate two videos one after the other:
import moviepy.editor as mp
video1 = mp.VideoFileClip("short.mp4")
video2 = mp.VideoFileClip("motivation.mp4")
final_video = mp.concatenate_videoclips([video1,video2])
final_video.write_videofile("composition.mp4")
The two videos are short random videos that I downloaded from YouTube. They both play perfectly, both with VLC and the standard video player provided with Linux Mint.
The script runs fine with no errors, with the final message:
[MoviePy] >>>> Building video composition.mp4
[MoviePy] Writing audio in compositionTEMP_MPY_wvf_snd.mp3
100%|██████████████████████████████| 1449/1449 [00:23<00:00, 59.19it/s]
[MoviePy] Done.
[MoviePy] Writing video composition.mp4
100%|██████████████████████████████| 1971/1971 [11:34<00:00, 2.84it/s]
[MoviePy] Done.
[MoviePy] >>>> Video ready: composition.mp4
The file is indeed created, and it also have a size (about 20 MB). However, when I try to play it, nothing happens: it seems to be corrupted. The standard video player even tells me that "there is no video stream to be played".
If I try to do the same with the interactive console, and use final_video.preview(), I get an AttributeError, along with this traceback:
In [5]: final_video.preview()
Exception in thread Thread-417:
Traceback (most recent call last):
File "/usr/lib/python3.5/threading.py", line 914, in _bootstrap_inner
self.run()
File "/usr/lib/python3.5/threading.py", line 862, in run
self._target(*self._args, **self._kwargs)
File "<decorator-gen-211>", line 2, in preview
File "/usr/local/lib/python3.5/dist-packages/moviepy/decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python3.5/dist-packages/moviepy/audio/io/preview.py", line 49, in preview
sndarray = clip.to_soundarray(tt,nbytes=nbytes, quantize=True)
File "<decorator-gen-184>", line 2, in to_soundarray
File "/usr/local/lib/python3.5/dist-packages/moviepy/decorators.py", line 54, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python3.5/dist-packages/moviepy/audio/AudioClip.py", line 107, in to_soundarray
fps = self.fps
AttributeError: 'CompositeAudioClip' object has no attribute 'fps'
and the video seems frozen at the first frame.
I don't have any clue, since everything seems to work fine (except with the preview, which doesn't work because of the error). I tried to reinstall ffmpeg, but no succes: everything is exactly the same. Without any useful error, I can't figure out how to fix this problem. Can anyone help me?
EDIT: What are the 4 magic letters? R-T-F-M! I solved the problem by setting the kwarg method of mp.concatenate_videoclips to compose, since the original videos have a different frame size.
To hopefully figure out what's going on, I decided to take a more systematic approach, following these steps:
Create a virtual environment with no packages other than moviepy and its dependencies
Use videos from a different source
Try different codecs and/or other different parameters
Dig into the source code of moviepy
Sacrifice a goat to the Angel of Light, the Deceiver, the Father of Lies, the Roaring Lion, Son of Perdition Satan Lucifer
In each case I will this script (test.py):
import moviepy.editor as mp
video1 = mp.VideoFileClip("short.mp4")
video2 = mp.VideoFileClip("motiv_30.mp4")
final_video = mp.concatenate_videoclips([video1,video2])
final_video.write_videofile("composition.mp4")
with some minor changes, when needed. I'll update this post as I follow the steps.
1. Create a virtual environment
I created a virtual environment using virtualenv, activated it and installed moviepy with pip. This is the output of pip freeze:
decorator==4.0.11
imageio==2.1.2
moviepy==0.2.3.2
numpy==1.13.3
olefile==0.44
Pillow==4.3.0
tqdm==4.11.2
All with python 3.5.2.
After running test.py, the video is created, with no apparent problems. However, the video can't be played, neither by VLC nor by the default video player of Linux Mint 18.1.
Then, I noticed that mp.concatenate_videoclips has the kwarg method, which is by default set to chain. In the documentation, I read that:
- method="compose", if the clips do not have the same
resolution, the final resolution will be such that no clip has
to be resized.
So, I tried to use the kwarg method="compose", since the two videos have different frame sizes and... it worked. I am an idiot. Oh well, no goats for Satan, I suppose. Lesson learned: RTFM
I was having the same trouble.
I fond the solution at https://zulko.github.io/moviepy/FAQ.html
It turns out that the video cannot have a odd ratio like 1080 x 351, so you just have to check if it's not even them add ou subtract one from that.
I'm trying play mp3 without default player use, so I want try pyglet, but nothing works
import pyglet
music = pyglet.resource.media('D:/folder/folder/audio.mp3')
music.play()
pyglet.app.run()
I've tried it this way
music = pyglet.resource.media('D:\folder\folder\audio.mp3')
and like this:
music = pyglet.resource.media('D:\\folder\\folder\\audio.mp3')
but have this error
Traceback (most recent call last):
File "C:\Users\User\AppData\Roaming\Python\Python35\site-packages\pyglet\resource.py", line 624, in media
location = self._index[name]
KeyError: 'D:\folder\folder\audio.mp3'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "D:/PC/PyCharm_project/0_TEMP.py", line 3, in <module>
music = pyglet.resource.media('D:\folder\folder\audio.mp3')
File "C:\Users\User\AppData\Roaming\Python\Python35\site-packages\pyglet\resource.py", line 634, in media
raise ResourceNotFoundException(name)
pyglet.resource.ResourceNotFoundException: Resource "D:\folder\folder\audio.mp3" was not found on the path. Ensure that the filename has the correct captialisation.
It's because of the way you load the resource.
Try this code for instance:
import pyglet
music = pyglet.media.load(r'D:\folder\folder\audio.mp3')
music.play()
pyglet.app.run()
The way this works is that it loads a file and places it in a pyglet.resource.media container. Due to namespaces and other things, the code you wrote is only allowed to load resources from the working directory. So instead, you use pyglet.media.load which is able to load the resource you need into the current namespace (Note: I might be missusing the word "namespace" here, for lack of a better term without looking at the source code of pyglet, this is the best description I could come up with).
You could experiment by placing the .mp3 in the script folder and run your code again but with a relative path:
import pyglet
music = pyglet.resource.media('audio.mp3')
music.play()
pyglet.app.run()
But I'd strongly suggest you use pyglet.media.load() and have a look at the documentation
I want to play a .wav file in Python 3.4. Additonally, I want python to play the file rather than python open the file to play in VLC, media player etc..
As a follow up question, is there any way for me to combine the .wav file and the .py file into a standalone exe.
Ignore the second part of the question if it is stupid, I don't really know anything about compiling python.
Also, I know there have been other questions about .wav files, but I have not found one that works in python 3.4 in the way I described.
Using pyaudio you may get incorrect playback due to speed, consider instead:
sudo apt-get install python-pygame
Windows:
choco install python-pygame?
def playSound(filename):
pygame.mixer.music.load(filename)
pygame.mixer.music.play()
import pygame
pygame.init()
playSound('hellyeah.wav')
I fixed the problem by using the module pyaudio, and the module wave to read the file.
I will type example code to play a simple wave file.
import wave, sys, pyaudio
wf = wave.open('Sound1.wav')
p = pyaudio.PyAudio()
chunk = 1024
stream = p.open(format =
p.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
data = wf.readframes(chunk)
while data != '':
stream.write(data)
data = wf.readframes(chunk)
If you happen to be using linux a simple solution is to call aplay.
import os
wav_file = "./Hello.wav"
os.system(f'aplay {wav_file}')