Moviepy: AudioClip.max_volume's bug and repair suggestion

Created on 31 Jul 2020  路  3Comments  路  Source: Zulko/moviepy

from  moviepy.editor import *
import numpy as np

if __name__ == '__main__':

    make_frame = lambda t: 2 * [t*(-1) ]
    clip = AudioClip(make_frame, duration=5,fps=24000)
    v = clip.max_volume(True)

    clip.write_audiofile(r"f:\video\audio.mp3")

Expected Behavior

Generate the sound and get the max value

Actual Behavior

"C:\Program Files\Python37\python.exe" F:/study/python/project/moviepyTest/moviepyTest.py 
Traceback (most recent call last):
  File "F:/study/python/project/moviepyTest/moviepyTest.py", line 31, in <module>
    v = clip.max_volume(True)
  File "C:\Program Files\Python37\lib\site-packages\moviepy\audio\AudioClip.py", line 144, in max_volume
    maxi = np.maximum(maxi, abs(chunk).max(axis=0)) if stereo else max(maxi, abs(chunk).max())
ValueError: operands could not be broadcast together with shapes (2,) (40000,) 

Process finished with exit code 1

Steps to Reproduce the Problem


Excute these scripts.

Repair suggestion: add a line 'chunk = np.array(chunk) ' and modified 'max(axis=1)' to 'max(axis=0)' in max_volume :

def max_volume(self, stereo=False, chunksize=50000, logger=None):

        stereo = stereo and (self.nchannels == 2)

        maxi = np.array([0, 0]) if stereo else 0
        for chunk in self.iter_chunks(chunksize=chunksize,logger=logger):
            chunk = np.array(chunk) 
            maxi = np.maximum(maxi, abs(chunk).max(axis=0)) if stereo else max(maxi, abs(chunk).max())
        return maxi

Specifications

audio bug bug-fix good first issue

Most helpful comment

Hey,
I would like to give it a shot if no one is working on it

All 3 comments

Thank you very much for providing the suggested fix! Unfortunately I'll not be able to get around to it for a while, but it will probably be in the final v2.0 release.

I've edited your post already to fix the formatting issues, but in future remember not to put code inside the html comments (<!-- and -->) because it won't show in the final post. Also I'd recommend formatting the error traces as code as well (with the 3 backticks).

Hey,
I would like to give it a shot if no one is working on it

I think that the error is that you are not creating a proper stereo data frame, you need to transpose the array. It would be make_frame = lambda t: np.array(2 * [t*(-1)]).T. I've tested using next code and works as expected, but no sound is generated because you are not generating any wave:

from moviepy.editor import *

make_frame = lambda t: np.array(2 * [t*(-1)]).T
clip = AudioClip(make_frame, duration=5, fps=24000)
v = clip.max_volume(True)
clip.write_audiofile("foo.mp3")
print(v)

This is the same behaviour of next example, if I remove the .T transposition, it would raises the same error:

make_frame = lambda t: np.array([
    np.sin(440 * 2 * np.pi * t),
    np.sin(880 * 2 * np.pi * t),
]).T
clip = AudioClip(make_frame, duration=3, fps=44100)
v = clip.max_volume(True)
clip.write_audiofile("foo.mp3")

Mono waves generation does not need this transposition, is easier to generate them:

make_frame = lambda t: np.sin(440 * 2 * np.pi * t)
clip = AudioClip(make_frame, duration=3, fps=44100)
v = clip.max_volume(True)
clip.write_audiofile("foo.mp3")
print(v)

Of course, I think that the current implementation in moviepy as failures and inconsistencies, and your make_frame function could be valid if these would be fixed, like a possible error in maxi = np.maximum(maxi, abs(chunk).max(axis=0)) if stereo else max(maxi, abs(chunk).max()), but related to this issue, what sound are you trying to generate? It seems to me that your example does not generate sound because it's creating negative vectors.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

buddhashrestha picture buddhashrestha  路  3Comments

djevo1 picture djevo1  路  3Comments

tburrows13 picture tburrows13  路  3Comments

bilel picture bilel  路  4Comments

wayn picture wayn  路  4Comments