How to show the current audio volume of my microphone? - audio

I'm completely new to QMultimedia. At the moment, I try to get the audio stream from the microphone in my webcam for further processing. Right now I just try to continuously show the volume level of the sound "heard" by the mic with a slider. So I googled some code together (found nearly 10 tons of examples how I can play an audio, but only a few blocks of C++ code about audio input) and got stuck.
This is my actual code:
import sys, time
from PyQt4 import Qt, QtGui, QtCore, QtMultimedia
class VolumeSlider(QtGui.QSlider):
def __init__(self, parent=None):
super(VolumeSlider, self).__init__(parent)
self.audio = None
self.volumeSlider = QtGui.QSlider(QtCore.Qt.Horizontal)
self.volumeSlider.setTickInterval(1)
self.volumeSlider.setMaximum(100)
self.volumeSlider.setValue(49)
self.volumeSlider.show()
self.openMicStream()
# THIS IS WHAT I WANT - DOESN'T WORK
while True:
self.volumeSlider.setValue(self.audio.volume())
time.sleep(0.02)
def openMicStream( self ):
#audioInputDevices = QtMultimedia.QAudioDeviceInfo.availableDevices(QtMultimedia.QAudio.AudioInput)
#for d in audioInputDevices: d.deviceName()
info = QtMultimedia.QAudioDeviceInfo(QtMultimedia.QAudioDeviceInfo.defaultInputDevice())
print "Default audio input device:", info.deviceName()
audioFormat = QtMultimedia.QAudioFormat()
audioFormat.setFrequency(8000);
audioFormat.setChannels(1);
audioFormat.setSampleSize(8);
audioFormat.setCodec("audio/pcm");
audioFormat.setByteOrder(QtMultimedia.QAudioFormat.LittleEndian);
audioFormat.setSampleType(QtMultimedia.QAudioFormat.UnSignedInt);
audioDeviceInfo = QtMultimedia.QAudioDeviceInfo.defaultInputDevice();
if not audioDeviceInfo.isFormatSupported(audioFormat):
sys.stderr("default audioFormat not supported try to use nearest")
audioFormat = audioDeviceInfo.nearestFormat(audioFormat);
self.audioInput = QtMultimedia.QAudioInput(audioFormat);
fmtSupported = info.isFormatSupported(audioFormat)
print "Is the selected format supported?", fmtSupported
if not fmtSupported:
audioFormat = info.nearestFormat(audioFormat)
print "Is the nearest format supported?", info.isFormatSupported(audioFormat)
self.audio = QtMultimedia.QAudioInput(audioFormat, None)
self.audio.start()
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
x = VolumeSlider()
sys.exit(app.exec_())
Could anybody poke me in the head what I have to do at the "#THIS IS WHAT I WANT" place to calculate and show the current level of volume?

There is no inbuilt function for computing the current volume level of the input sound signal when recorded with QAudioInput neither in Qt 4 (QAudioInput documentation) nor in Qt 5.
But you could calculate it for yourself. The root-mean-square in a moving window of the signal is often used as a measure for current loudness. See How can I determine how loud a WAV file will sound? for more suggestions.

Solved it after a while of working on another parts. Now I can at least hear the sound out of the boxes, after I changed the openMicStream(self) to this:
def openMicStream( self ):
info = QAudioDeviceInfo(QAudioDeviceInfo.defaultInputDevice())
print "Default audioInput input device: ", info.deviceName()
audioFormat = QAudioFormat()
audioFormat.setFrequency(44100);
audioFormat.setChannels(1);
audioFormat.setSampleSize(16);
audioFormat.setCodec("audioInput/pcm");
audioFormat.setByteOrder(QAudioFormat.LittleEndian);
audioFormat.setSampleType(QAudioFormat.UnSignedInt);
audioDeviceInfo = QAudioDeviceInfo.defaultInputDevice();
if not audioDeviceInfo.isFormatSupported(audioFormat):
messages.error(__name__, "default audioFormat not supported try to use nearest")
audioFormat = audioDeviceInfo.nearestFormat(audioFormat);
print audioFormat.frequency()
print audioFormat.channels()
print audioFormat.sampleSize()
print audioFormat.codec()
print audioFormat.byteOrder()
print audioFormat.sampleType()
self.audioInput = QAudioInput(audioFormat);
audioFmtSupported = info.isFormatSupported(audioFormat)
messages.info(__name__, "Is the selected format supported?"+str(audioFmtSupported))
if not audioFmtSupported:
audioFormat = info.nearestFormat(audioFormat)
messages.info(__name__, "Is the nearest format supported?"+str(info.isFormatSupported(audioFormat)))
self.audioInput = QAudioInput(audioFormat, None)
self.audioOutput = QAudioOutput(audioFormat, None)
device = self.audioOutput.start()
self.audioInput.start(device)

Related

How to use Progress bar in pytube?

I want to implement a progress bar in my code, but neither the old nor the new way of implementation is working.
How to add progress bar?
this fix dosen't work in the latest version.
Here is the latest documentation
https://pypi.org/project/pytube/
from pytube import YouTube
url="https://youtu.be/J5EXnh53A1k"
path=r'D://'
yt = YouTube(url)
yt.register_on_progress_callback(show_progress_bar)#by commenting this line code works fine but no progress bar is displyed
yt.streams.filter(file_extension='mp4').first().download(path)
def show_progress_bar(stream, _chunk, _file_handle, bytes_remaining):
current = ((stream.filesize - bytes_remaining)/stream.filesize)
percent = ('{0:.1f}').format(current*100)
progress = int(50*current)
status = '█' * progress + '-' * (50 - progress)
sys.stdout.write(' ↳ |{bar}| {percent}%\r'.format(bar=status, percent=percent))
sys.stdout.flush()
You first need to define the progress bar function, say progress_function:
def progress_function(chunk, file_handle, bytes_remaining):
global filesize
current = ((filesize - bytes_remaining)/filesize)
percent = ('{0:.1f}').format(current*100)
progress = int(50*current)
status = '█' * progress + '-' * (50 - progress)
sys.stdout.write(' ↳ |{bar}| {percent}%\r'.format(bar=status, percent=percent))
sys.stdout.flush()
Then register the above defined function progress_function with the on_progress_callback as follows:
yt_obj = YouTube(<<youtube_video_url>>, on_progress_callback = progress_function)
Rest of the code follows:
yt_obj.streams.filter(progressive=True, file_extension='mp4').get_highest_resolution().download(output_path='/home/myusername/Videos', filename='MyVideo')
Output looks like this:
↳ |██████████████████████████████████----------------| 68.4%
Have fun!!
I'm using progressbar2
def progress_Check(stream = None, chunk = None, file_handle = None, remaining = None):
percent = file_size - remaining + 1000000
try:
# updates the progress bar
bar.update(round(percent/1000000,2))
except:
# progress bar dont reach 100% so a little trick to make it 100
bar.update(round(file_size/1000000,2))
yt = YouTube(url, on_progress_callback=progress_Check)
yt = yt.streams.filter(progressive=True, file_extension='mp4').order_by('resolution').desc().first().download()
Here is function used to download youtube video and display progress bar from shell:
from pytube import YouTube
from pytube.cli import on_progress
fuchsia = '\033[38;2;255;00;255m' # color as hex #FF00FF
reset_color = '\033[39m'
# url is url of youtube video to download.
def download_youtube(url):
""" Instantiates YouTube class and downloads selected video. Uses Built-in
pytube.cli function on_progress to show a DOS style progress bar. """
yt = YouTube(url, on_progress_callback=on_progress)
# following line displays title and number of times video has been viewed.
print(f'\n' + fuchsia + 'Downloading: ', yt.title, '~ viewed', yt.views,
'times.')
# creates download and downloads to subdirectory called 'downloads'
yt.streams.first().download('.\\downloads\\')
# displays message verifying download is complete, and resets color scheme
# back to original color scheme.
print(f'\nFinished downloading: {yt.title}' + reset_color)
Display colors were switched because the default progress bar is fairly bright. In event video was previously downloaded the 'Finished downloading:' message will display but the progress bar won't displayed.
Please see this Showing progress in pytube regarding the use of pytube's built-in on_progress function.
# importing YouTube from pytube
import progressbar as progress
from pytube import YouTube
def progress(streams, chunk: bytes, bytes_remaining: int):
contentsize = video.filesize
size = contentsize - bytes_remaining
print('\r' + '[Download progress]:[%s%s]%.2f%%;' % (
'█' * int(size*20/contentsize), ' '*(20-int(size*20/contentsize)), float(size/contentsize*100)), end='')
url = 'https://www.youtube.com/watch?v=qOVAbKKSH10'
yt = YouTube(url, on_progress_callback=progress)
video = yt.streams.get_highest_resolution()
video.download()

Python error "expected LP_SDL_Window" when trying "SDL_GetWindowID"

I'm trying to get the Window ID of the SDL window, to give to VLC so it can play the video in the window.
Being new to Python, I'm vaguely aware this has to do with variable type conversions to play nice with SDL, and using the correct python binding...
The line with the error is "win_id = SDL_GetWindowID(window)"
Here is my code;
import sys
import sdl2.ext
import vlc
import ctypes
from sdl2 import *
RESOURCES = sdl2.ext.Resources(__file__, "resources")
sdl2.ext.init()
window = sdl2.ext.Window("Hello World!", size=(640, 480))
window.show()
factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.bmp"))
spriterenderer = factory.create_sprite_render_system(window)
spriterenderer.render(sprite)
vlcInstance = vlc.Instance("--no-xlib")
player = vlcInstance.media_player_new()
win_id = SDL_GetWindowID(window)
player.set_xwindow(win_id)
player.set_mrl("agro.mp4")
player.play()
processor = sdl2.ext.TestEventProcessor()
processor.run(window)
sdl2.ext.quit()
What you get with SDL_GetWindowID is SDL's internal window ID that it itself refers to in e.g. events. What you need is X11 window ID, which you can get through SDL_GetWindowWMInfo. That however requires some trickery with SDL versioning, e.g. (I'm not sure it is safe to call that in python if SDL version changes but pysdl2 is not updated):
wminfo = SDL_SysWMinfo();
SDL_GetVersion(wminfo.version);
if(SDL_GetWindowWMInfo(window.window, wminfo) == 0):
print("can't get SDL WM info");
sys.exit(1);
win_id = wminfo.info.x11.window;
Then use that win_id to feed to vlc.

How to Play Sound in Odoo with Single Device Running

I have designed a method when product not found in using barcode scanning I put this code in that product not found.
#api.multi
def _product_sound(self)
PyAudio = pyaudio.PyAudio
bitrate = 8000
frq = 500
LENGTH = 2
if frq > bitrate:
bitrate = frq+100
numberofframe = int(bitrate * LENGTH)
restframe = numberofframe % bitrate
wave = ''
for x in range(numberofframe):
wave = wave+chr(int(math.sin(x/((bitrate/frq)/math.pi))*124+128))
for x in range(restframe):
wave = wave+chr(128)
p = PyAudio()
stream = p.open(format = p.get_format_from_width(1), channels = 1,rate = bitrate,output = True)
stream.write(wave)
stream.stop_stream()
stream.close()
p.terminate()
When I try this code in single system its work perfectly. but when I try to using in the different device that time sound not be generated.
So how to play sound in odoo with different system or current system ?

How to wait until a sound file ends in vlc in Python 3.6

I have a question in vlc in python
import vlc
sound = vlc.MediaPlayer('sound.mp3')
sound.play()
# i wanna wait until the sound ends then do some code without
time.sleep()
import time, vlc
def Sound(sound):
vlc_instance = vlc.Instance()
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(sound)
player.set_media(media)
player.play()
time.sleep(1.5)
duration = player.get_length() / 1000
time.sleep(duration)
After edit
That exactly what I wanted, thanks everyone for helping me ..
You can use the get_state method (see here: https://www.olivieraubert.net/vlc/python-ctypes/doc/) to check the state of the vlc player.
Something like
vlc_instance = vlc.Instance()
media = vlc_instance.media_new('sound.mp3')
player = vlc_instance.media_player_new()
player.set_media(media)
player.play()
print player.get_state()# Print player's state
for wait util end of vlc play sound, except your:
player.play()
time.sleep(1.5)
duration = player.get_length() / 1000
time.sleep(duration)
other possible (maybe more precise, but CPU costing) method is:
# your code ...
Ended = 6
current_state = player.get_state()
while current_state != Ended:
current_state = player.get_state()
# do sth you want
print("vlc play ended")
refer :
vlc.State definition
vlc.Instance
vlc.MediaPlayer - get_state
I.m.o. Flipbarak had it almost right. My version:
import vlc, time
vlc_instance = vlc.Instance()
song = 'D:\\mozart.mp3'
player = vlc_instance.media_player_new()
media = vlc_instance.media_new(song)
media.get_mrl()
player.set_media(media)
player.play()
playing = set([1])
time.sleep(1.5) # startup time.
duration = player.get_length() / 1000
mm, ss = divmod(duration, 60)
print "Current song is : ", song, "Length:", "%02d:%02d" % (mm,ss)
time_left = True
# the while loop checks every x seconds if the song is finished.
while time_left == True:
song_time = player.get_state()
print 'song time to go: %s' % song_time
if song_time not in playing:
time_left = False
time.sleep(1) # if 1, then delay is 1 second.
print 'Finished playing your song'
A slight alternative / method that i just tested and had good results (without needing to worry about the State.xxxx types.
This also allowed me to lower the overall wait/delay as i'm using TTS and found i would average 0.2 seconds before is_playing returns true
p = vlc.MediaPlayer(audio_url)
p.play()
while not p.is_playing():
time.sleep(0.0025)
while p.is_playing():
time.sleep(0.0025)
The above simply waits for the media to start playing and then for it to stop playing.
Note: I'm testing this via a URL / not a local file but was having the same issue and believe this will work the same.
Also fully aware its a slightly older and answered, but hopefully its of use to some.

VLC-QT get the framerate of current video file

I use the vlc-qt lib and try to access the frames per second information of an openend video file.
The player:
_instance = new VlcInstance(VlcCommon::args(), this);
_player = new VlcMediaPlayer(_instance);
_media = new VlcMedia(file, true, _instance);
_player->openOnly(_media);
the player has a public function playbackRate() but it gives only the current playback ration, so it is 1 if no slowmotion is applied.
float playbackRate = _player->playbackRate();
I also tried to get it over the codec, but the codec itself is not a class but only an enum with possible codecnames.
How can I access the fps, so get back something like 30 frames per second?
Using python vlc.py:
Where self.player is:
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
It has a function get_fps()
def mspf(self):# Milliseconds per frame.
return int(1000 // (self.player.get_fps() or 25))
EDIT:
Having dug deeper, there appears to be no reference to fps in the vlc-qt sources, except where it offers fps as an experimental input to the Media::duplicate and Media::record functions within VlcMedia.cpp although fps is available within vlc

Resources