Skip to content

Instantly share code, notes, and snippets.

@THeK3nger
Last active September 1, 2023 21:35
Show Gist options
  • Star 19 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save THeK3nger/3624478 to your computer and use it in GitHub Desktop.
Save THeK3nger/3624478 to your computer and use it in GitHub Desktop.
Python Wave Audio Loop
import os
import wave
import threading
import sys
# PyAudio Library
import pyaudio
class WavePlayerLoop(threading.Thread) :
"""
A simple class based on PyAudio to play wave loop.
It's a threading class. You can play audio while your application
continues to do its stuff. :)
"""
CHUNK = 1024
def __init__(self,filepath,loop=True) :
"""
Initialize `WavePlayerLoop` class.
PARAM:
-- filepath (String) : File Path to wave file.
-- loop (boolean) : True if you want loop playback.
False otherwise.
"""
super(WavePlayerLoop, self).__init__()
self.filepath = os.path.abspath(filepath)
self.loop = loop
def run(self):
# Open Wave File and start play!
wf = wave.open(self.filepath, 'rb')
player = pyaudio.PyAudio()
# Open Output Stream (basen on PyAudio tutorial)
stream = player.open(format = player.get_format_from_width(wf.getsampwidth()),
channels = wf.getnchannels(),
rate = wf.getframerate(),
output = True)
# PLAYBACK LOOP
data = wf.readframes(self.CHUNK)
while self.loop :
stream.write(data)
data = wf.readframes(self.CHUNK)
if data == b'' : # If file is over then rewind.
wf.rewind()
data = wf.readframes(self.CHUNK)
stream.close()
player.terminate()
def play(self) :
"""
Just another name for self.start()
"""
self.start()
def stop(self) :
"""
Stop playback.
"""
self.loop = False
@411736
Copy link

411736 commented Jul 21, 2015

Sorry I am a beginner programmer and I am wondering where to insert the .wav file and if this will play the file or just loop it

@11208
Copy link

11208 commented Aug 3, 2018

player = WavePlayerLoop("sounds/1.wav")
player.play()

@411736

@nik312123
Copy link

Note that it will be

if data == b''
instead of
if data == ''

in the newest version of Python

@benoitvalery
Copy link

What if you would insert some delay between two repetitions ?
Thanks for this work !

@THeK3nger
Copy link
Author

THeK3nger commented Nov 13, 2019

@benoitvalery

Just add a time.sleep(x) (where x is the number of seconds you want to delay) at the end of the while loop in line 45. time.sleep blocks the thread, not the process. :)

@benoitvalery
Copy link

Thank you for your response. I modified your code, removing the loop side, and adding a play_once() function, that I call on demand. It suits my needs very well. Thanks again.

@xuantee
Copy link

xuantee commented Nov 19, 2019

@THeK3nger

Somehow I can't seem to get the audio to loop. I copy-pasted your code word-for-word and yet it stops right after it finishes. Please help :(

edit: I managed to make it work somehow. the data != '' doesn't seem to on my laptop so instead i wrote it so that when len(data)==0, break from the loop. Would appreciate if you knew a more elegant method.

@benoitvalery
Copy link

Did you see the previous comment by nik312123 ?

Note that it will be

if data == b''
instead of
if data == ''

in the newest version of Python

@THeK3nger
Copy link
Author

I updated the main file to fix this. Thank you all. :)

@xuantee
Copy link

xuantee commented Nov 19, 2019

@benoitvalery
Ah, thanks for that. somehow i read that comment the other way round.
@THeK3nger
Thanks a lot :D

@leamu
Copy link

leamu commented Nov 6, 2020

Hello, i have the same problem:

Sorry I am a beginner programmer and I am wondering where to insert the .wav file and if this will play the file or just loop it

Do I have to insert the file AND my local file path here?

def run(self):
# Open Wave File and start play!
wf = wave.open(self.filepath, 'rb')
player = pyaudio.PyAudio()

I tried different options but nothing is working..

Copy link

ghost commented Apr 11, 2021

@leamu no you have to use it outside the class like this:

import os
import wave
import threading
import sys

# PyAudio Library
import pyaudio

class WavePlayerLoop(threading.Thread):
    CHUNK = 1024

    def __init__(self, filepath, loop=True):
        """
        Initialize `WavePlayerLoop` class.
        PARAM:
            -- filepath (String) : File Path to wave file.
            -- loop (boolean)    : True if you want loop playback.
                                   False otherwise.
        """
        super(WavePlayerLoop, self).__init__()
        self.filepath = os.path.abspath(filepath)
        self.loop = loop

    def run(self):
        # Open Wave File and start play!
        wf = wave.open(self.filepath, 'rb')
        player = pyaudio.PyAudio()

        # Open Output Stream (based on PyAudio tutorial)
        stream = player.open(format=player.get_format_from_width(wf.getsampwidth()),
                             channels=wf.getnchannels(),
                             rate=wf.getframerate(),
                             output=True)

        # PLAYBACK LOOP
        data = wf.readframes(self.CHUNK)
        while self.loop:
            stream.write(data)
            data = wf.readframes(self.CHUNK)
            if data == b'':  # If file is over then rewind.
                wf.rewind()
                data = wf.readframes(self.CHUNK)

        stream.close()
        player.terminate()

    def play(self):
        """
        Just another name for self.start()
        """
        self.start()

    def stop(self):
        """
        Stop playback.
        """
        self.loop = False

player = WavePlayerLoop("sounds/1.wav")
player.play()

@abcshubhamabc
Copy link

I also wanted to ask that, how can we play all the songs from a particular folder, in python because as a beginner I'm facing a problem with that,

currently, I'm using the code -

elif 'play some music' in query:
music_dir = 'D:\Music'
songs = os.listdir(music_dir)
print(songs)
os.startfile(os.path.join(music_dir, songs[0]))

But this only plays the 1st song, [0]

if anyone knows - how to play all the songs then, please help,

thanks

insta - im__ace_

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment