简体   繁体   中英

Python module for playing sound data with progress bar?

I have an array of raw sound data samples, and I'm trying to make a graphical player that displays the waveform along with the progress of the audio as it plays.

I can plot it easily enough with matplotlib, and I can play it with audiolab, but audiolab appears to have no way to get the "current location" of the playhead.

Are there any modules capable of doing this?

If you just want a progress bar and not a "seek" function- just want to show how much is done and left, you can easily build that using tkintr and integrate with whatever you have now.

Otherwise,

There are basically two modules that give you a progress bar.

http://code.google.com/p/py-audio-gui/wiki/PageName

PyAudio plays only MP3. Main drawback. But is easier to use.

There is another module called Snack which supports a lot of different formats and has the progress bar feature as well.

This is a bit harder to use but I heard they did make available some good tutorials/samples recently.

So, I would suggest shift to Snack if you want that.

Cheers.

If you know the number of audio frames, and the samplerate, you don't need to audiolab to tell you the current location, you can compute it.

Sndfile.frames / Sndfile.samplerate will give you the duration of the file in seconds, you can then use this in conjunction with elapsed time since since sound file start to compute relative current location. To illustrate the principle:

import time

start_time = time.time()
duration_s = sndfile.frames / sndfile.samplerate

while 1:
    elapsed_time = time.time() - start_time
    current_location = elapsed_time / float(duration_s)
    if current_location >= 1:
         break
    time.sleep(.01)

To implement this in practice, you could use Python threading , to play the sound file asynchronously, and then compute the current location (as above) in the parent thread. To handle the case where playback fails, wrap your call to scikits.audiolab.play() in an exception handler, and then use threading.Event to pass an event to the parent thread if/when the play() call fails.

In the parent thread you would then need to check event.isSet() accordingly:

if current_location >= 1 or fail_event.isSet():
    break

I have found a good code which is able to run what you are looking for. Here is the Link: https://gist.github.com/deeplycloudy/2152643 I wasn't able to run the code from the author but I have made some corrections in a comment below that repository.

Saludos!!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM