Closed Netherdrake closed 10 years ago
I am on 0.2.1.7.21.
Any update on this?
Really busy, give me some time. But thanks for the bug report. That is a strange bug, I don't know exactly what causes it. What is the length of the words for which your fix doesn't work ? Could you upload the files somewhere ?
Error: wrong indices in video buffer. Maybe buffer too small.
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "<string>", line 2, in preview
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/preview.py", line 59, in preview
sndarray = clip.to_soundarray(tt,nbytes)
File "<string>", line 2, in to_soundarray
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 83, in to_soundarray
snd_array = self.get_frame(tt)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 189, in get_frame
if (part is not False) ]
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 189, in get_frame
if (part is not False) ]
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/AudioFileClip.py", line 69, in <lambda>
self.get_frame = lambda t: self.reader.get_frame(t)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/readers.py", line 173, in get_frame
raise error
IndexError: index 48361 is out of bounds for axis 0 with size 48360
Code:
# WORD clip
wordSlide = ColorClip((1280,720), (178, 240, 120))
wordText = TextClip(wordStr, font="Arial-Regular", color="#5782D4", fontsize=90)
wordAudio = AudioFileClip(path + "word.aif")
wordClip = CompositeVideoClip([wordSlide.set_audio(wordAudio),
wordText.set_pos('center')]).set_duration(wordAudio.duration)
word.aif: https://www.dropbox.com/s/3o57t1u74jogyoq/word.aif
Seems like a similar error message is thrown here. https://github.com/Zulko/moviepy/issues/10
I have to ship my code into production this week, a fix would be greatly appreciated.
Ok, I'll look into it tonight (in 10h) if I have time. should be fixed by tomorrow.
Thank you. You are awesome!
Ok, so it seems that the error is what I thought it was: the buffer for reading audio from video/audio files expects these to be longer, which causes the bug.
To be precise, the default buffer is 200000 bytes of 2-channel 44100Hz 16-bit sound, which can only be found in clips that are more than 200000/(2_44100_2) = 1.13 seconds long.
So you need to change the buffer size; your example works if I replace the line
wordAudio = AudioFileClip(path + "word.aif")
by
wordAudio = AudioFileClip(path + "word.aif", buffersize=40000)
Don't make that buffer too small (<20000) though, or the video-writer on the other end will scream that it cannot write enough bytes at once.
As an alternative, you can also try the version I fixed on Github, in which the default buffersize is adapted to the file if the file is short.
Can you push fixed version to pip or easy_install?
Nevermind, I figured out pip can install from github.
pip install git+https://github.com/Zulko/moviepy.git@b64cf4cd66b28724e01cb5d8327a5cdb805475b4
The problem doesn't seem to be fixed tho:
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|###-------| 287/869 33% [elapsed: 00:00 left: 00:01, 573.88 iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
The buffersize=40000
hack appears to work on some clips, but crashes on others.
It's not the same bug, this time it is the writer which screams at you. Can you give me a script/audio file for which it crashes ?
Yes, the error is:
Error: wrong indices in video buffer. Maybe buffer too small.
Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 810, in __bootstrap_inner
self.run()
File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py", line 763, in run
self.__target(*self.__args, **self.__kwargs)
File "<string>", line 2, in preview
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/preview.py", line 59, in preview
sndarray = clip.to_soundarray(tt,nbytes)
File "<string>", line 2, in to_soundarray
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 83, in to_soundarray
snd_array = self.get_frame(tt)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 189, in get_frame
if (part is not False) ]
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 189, in get_frame
if (part is not False) ]
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/AudioFileClip.py", line 69, in <lambda>
self.get_frame = lambda t: self.reader.get_frame(t)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/readers.py", line 174, in get_frame
raise error
IndexError: index 19788 is out of bounds for axis 0 with size 19788
Code:
from moviepy.editor import *
# WORD clip
wordSlide = ColorClip((1280,720), (178, 240, 120))
wordText = TextClip(wordStr, font="Arial-Regular", color="#5782D4", fontsize=90)
wordAudio = AudioFileClip(path + "word.aif", buffersize=40000)
wordClip = CompositeVideoClip([wordSlide.set_audio(wordAudio),
wordText.set_pos('center')]).set_duration(wordAudio.duration)
wordClip.preview()
quit()
If I set buffersize something bigger (eg 50,000), or smaller (30,000) it goes away.
I just double checked that the only version of moviepy installed on my machine is the commit b64cf4cd66b28724e01cb5d8327a5cdb805475b4.
So with:
AudioFileClip(path + "word.aif")
Crashes still occur (on different files). With manual buffersize settings crashes occur too.
Another observation:
Running on purely last commit https://github.com/Zulko/moviepy/commit/b64cf4cd66b28724e01cb5d8327a5cdb805475b4, without buffersize params in AufioFileClip initializers, the preview()
no longer crashes, but whole video is badly out of sync (slow motion style).
The rendering crashes every time, but at different sections:
~/D/g/s/b/f/urbanvideos % ./urbanvideos t -id 7446454
2014/05/21 00:22:15 exit status 1
MoviePy: building video file MEDIA/7446454/out.mp4
----------------------------------------
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|###-------| 292/869 33% [elapsed: 00:00 left: 00:00, 583.05 iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
~/D/g/s/b/f/urbanvideos % ./urbanvideos t -id 7446454
2014/05/21 00:22:35 exit status 1
MoviePy: building video file MEDIA/7446454/out.mp4
----------------------------------------
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|###-------| 262/869 30% [elapsed: 00:00 left: 00:01, 523.34 iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
~/D/g/s/b/f/urbanvideos % ./urbanvideos t -id 7446454
2014/05/21 00:22:44 exit status 1
MoviePy: building video file MEDIA/7446454/out.mp4
----------------------------------------
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|###-------| 287/869 33% [elapsed: 00:00 left: 00:01, 573.42 iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
This only happens on some videos.
Rendering code:
video.to_videofile(path + "out.mp4", fps=30)
I got the crash rate down a bit by this line:
self.buffersize= min( self.nframes+1, buffersize )
in audio/io/readers.py line 60.
I don't know why, but it reduces crashes a bit. It is not a fix by any means.
Are you interested in fixing this bug, or not really?
Yes I am interested in fixing this bug (it must be one of the most visible bugs left in moviepy). However I have other emergencies, so your feedbacks are greatly appreciated. I'll give it a look tomorrow.
A few days ago I have changed something in the computation of "which clip is playing when". This little change fixes a bug that happened because at the end of a video file moviepy asked for a last video frame which was outside the range of the videofile. I can't guaranty anything, but I can see reasons why this could also be the reason why the audio bugs. So could you try installing the version on Github (with python setup.py install) and tell me if it still bugs ? Thanks in advance.
Hi,
I'm sorry for late reply (was travelling to Europe). I've upgraded my local branch to the latest commit, but the issue still exists:
|###-------| 350/966 36% [elapsed: 00:01 left: 00:01, 349.27 iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
Could it be the case that the audio files have incorrect metadata or something of that nature? It only happens on 5% of files, and the same files consistently fail.
Interesting... Could you upload one of these files somewhere (or does it fail with the last file that you already uploaded ?)
Yup, just run this: https://www.dropbox.com/s/f3i6w6ynve3zfw7/Archive.zip
The audio files are generated by say
program on Mac (siri thingy).
Also, I've a quick question. Is it possible to have 2 audio tracks playing at same time? So the image/text clips get 1 and than the entire video gets 1 audio track as well?
First, an update on your bugs.
At least on my computer, it seems that the main problem is that you ask the same clip to play three times, which forces the ffmpeg-reader to "rewind" or re-initialize, and that's where the bug happens. You so that it is clearer:
# Won't work
video = concatenate([ wordClip.fadein(0.3),
spellingClip,
wordClip, ###
meaningClip,
wordClip, ###
exampleClip,
ending ])
# Will work
video = concatenate([ wordClip.fadein(0.3),
spellingClip,
meaningClip,
exampleClip,
ending ])
I will try to see what causes this bug. In the meantime, the most reliable solution is to create different entry points into the file:
clip1 = VideoFileClip("myvideo.mp4")
clip2 = VideoFileClip("myvideo.mp4")
clip3 = VideoFileClip("myvideo.mp4")
Since you need to process these clips afterwards, the best thing to do is to make a loop or a function, like this:
def make_wordClip(wordStr, wordFile):
wordSlide = ColorClip((1280,720), (178, 240, 120))
wordText = TextClip(wordStr, font="Helvetica", color="#5782D4",
fontsize=90)
wordAudio = AudioFileClip(wordFile, buffersize=4000)
wordClip = CompositeVideoClip([wordSlide.set_audio(wordAudio),
wordText.set_pos('center')])\
.set_duration(wordAudio.duration)
return wordClip
wordClips = [make_wordClip(wordStr, "word.aif") for i in [1,2,3]]
#later
video = concatenate([ wordClips[0].fadein(0.3),
spellingClip,
wordClips[1], ###
meaningClip,
wordClips[2], ###
exampleClip,
ending ])
While I am at it: your code is not optimized. The way you wrote it, for each frame of the video MoviePy will regenerate the slide (by blitting the text on the background). It is better to tell MoviePy that your slides are clips made of a single frame. To do so, you just change this code:
wordClip = CompositeVideoClip([wordSlide.set_audio(wordAudio),
wordText.set_pos('center')])\
.set_duration(wordAudio.duration)
by adding this line:
wordClip = CompositeVideoClip([wordSlide.set_audio(wordAudio),
wordText.set_pos('center')])\
.to_ImageClip() ###
.set_duration(wordAudio.duration)
Applying this to all your slides made the video generation 10x faster (it will also greatly improve your previews).
Note that if your backgrounds are simply colors, you don't need to use CompositeVideoClip, you can use wordText.on_color(size=(1280,720), color=(178, 240, 120))
Also I would suggest you use a variable SIZE=(1280,720)
at the beginning of your script, just in case you need to change it. One of the big advantages of 'scripting' videos, compared to a graphic interface, is that you can change a lot, with minimum effort.
Now to answer your question on adding an audio background. I will certainly add a function to do this. Right now the way to do it is as follows:
from moviepy.editor import *
# ... some code ...
audio_background = AudioFileClip("albinoni.mp4")
video = concatenate([ clip1, clip2, etc.]) # your 'final' clip
video.audio = CompositeAudioClip([video.audio, audio_background]).\
set_duration(video.duration)
Thank you! You are absolutely awesome.
I've applied the to_image optimization, and that has reduced render time from 45 to 14 seconds. Awesome!
As for crashes, I just upgraded to the latest commit, and almost every rendering crashes.
MoviePy: building video file out.mp4
----------------------------------------
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|#---------| 206/1302 15% [elapsed: 00:00 left: 00:02, 411.50 iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
My +1 hack in audio/io/readers.py line 60 seems to reduce these crashes significantly.
I don't get it. Is it due to the concatenation or is it a problem with the files themselves ? Could you try this:
clip = AudioFileClip("myaudiofile.aif")
clip.to_audiofile("test.mp3")
and tell me if you get a bug, and if you get one for a given file, send me the file ?
I believe there might be a problem with metadatas, I will try to implement a robust solution. Have you tried the trick in which I create 3 different clips from the same file.
Yes, I no longer reuse clips in concatenation. That was probably not the issue anyway.
I think its metadata problem with files. It seems to be just slightly off at times.
Hi,
I tried converting .aif
files to .mp3
, to no avail. (I used lame
program to do it).
MoviePy: building video file out.mp4
----------------------------------------
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|----------| 0/896 0% [elapsed: 00:00 left: ?, ? iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
Traceback (most recent call last):
File "viddler.py", line 148, in <module>
video.to_videofile("out.mp4", fps=30)
File "/usr/lib/python2.7/site-packages/moviepy/video/VideoClip.py", line 275, in to_videofile
verbose)
File "<string>", line 2, in to_audiofile
File "/usr/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 104, in to_audiofile
codec, bitrate, verbose)
File "<string>", line 2, in ffmpeg_audiowrite
File "/usr/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/lib/python2.7/site-packages/moviepy/audio/io/ffmpeg_audiowriter.py", line 124, in ffmpeg_audiowrite
sndarray = clip.to_soundarray(tt, nbytes= nbytes)
File "<string>", line 2, in to_soundarray
File "/usr/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 83, in to_soundarray
snd_array = self.get_frame(tt)
File "/usr/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 189, in get_frame
if (part is not False) ]
File "/usr/lib/python2.7/site-packages/moviepy/audio/io/AudioFileClip.py", line 69, in <lambda>
self.get_frame = lambda t: self.reader.get_frame(t)
File "/usr/lib/python2.7/site-packages/moviepy/audio/io/readers.py", line 177, in get_frame
raise error
IndexError: index 55345 is out of bounds for axis 0 with size 55345
shell returned 1
It all goes back to audio/io/readers.py. I don't know what the problem is.
Furthermore, on same files, here is the output of:
clip = AudioFileClip("example.aif")
clip.to_audiofile("test.mp3")
Writing audio in test.mp3
|----------| 0/237 0% [elapsed: 00:00 left: ?, ? iters/sec]Traceback (most recent call last):
File "viddler.py", line 112, in <module>
clip.to_audiofile("test.mp3")
File "<string>", line 2, in to_audiofile
File "/usr/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 104, in to_audiofile
codec, bitrate, verbose)
File "<string>", line 2, in ffmpeg_audiowrite
File "/usr/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/lib/python2.7/site-packages/moviepy/audio/io/ffmpeg_audiowriter.py", line 125, in ffmpeg_audiowrite
writer.write_frames(sndarray)
File "/usr/lib/python2.7/site-packages/moviepy/audio/io/ffmpeg_audiowriter.py", line 78, in write_frames
self.proc.stdin.write(frames_array.tostring())
IOError: [Errno 32] Broken pipe
I believe there are different issues here, but the error you get is not really a bug, it's just that to_audiofile also requires you to provide the codec, given that it cannot guess the codec from the extension. Here are some examples of codecs:
codecs = { 'libmp3lame': 'mp3',
'libvorbis':'ogg',
'libfdk_aac':'m4a',
'pcm_s16le':'wav',
'pcm_s32le': 'wav'}
So this will work:
clip.to_audiofile('test.mp3', codec='libmp3lame')
I will look into the rest.
With codec parameter, it works fine. Conversion work, but rendering crashes.
Ok, but then I will need you to provide the script that crashes. The script you gave me last time works fine, even on the new files you sent me.
Thats weird. It crashed for me on all of my machines.
I've just stumbled upon something. If I do convert every .aif to .mp3 with clip.to_audiofile('test.mp3', codec='libmp3lame')
And than use mp3's for rendering, the crash is gone. Testing a sample of 100 vids, will know in a bit if its for sure.
Nevermind, it still crashes.
Here is the the latest example: https://www.dropbox.com/s/f3i6w6ynve3zfw7/Archive.zip
Run it with:
python2 viddler.py MEDIA/7271838
On latest version of moviepy:
~/D/g/s/b/f/urbanvideos % python2 viddler.py MEDIA/7271838
Writing audio in word.mp3
Done writing Audio in word.mp3 !
Writing audio in spelling.mp3
Done writing Audio in spelling.mp3 !
Writing audio in meaning.mp3
Done writing Audio in meaning.mp3 !
Writing audio in example.mp3
Done writing Audio in example.mp3 !
MoviePy: building video file out.mp4
----------------------------------------
Writing audio in outTEMP_MPY_to_videofile_SOUND.ogg
|----------| 0/787 0% [elapsed: 00:00 left: ?, ? iters/sec]Error: wrong indices in video buffer. Maybe buffer too small.
Traceback (most recent call last):
File "viddler.py", line 156, in <module>
video.to_videofile("out.mp4", fps=30)
File "/usr/local/lib/python2.7/site-packages/moviepy/video/VideoClip.py", line 275, in to_videofile
verbose)
File "<string>", line 2, in to_audiofile
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 104, in to_audiofile
codec, bitrate, verbose)
File "<string>", line 2, in ffmpeg_audiowrite
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/ffmpeg_audiowriter.py", line 124, in ffmpeg_audiowrite
sndarray = clip.to_soundarray(tt, nbytes= nbytes)
File "<string>", line 2, in to_soundarray
File "/usr/local/lib/python2.7/site-packages/moviepy/decorators.py", line 60, in requires_duration
return f(clip, *a, **k)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 83, in to_soundarray
snd_array = self.get_frame(tt)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/AudioClip.py", line 189, in get_frame
if (part is not False) ]
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/AudioFileClip.py", line 69, in <lambda>
self.get_frame = lambda t: self.reader.get_frame(t)
File "/usr/local/lib/python2.7/site-packages/moviepy/audio/io/readers.py", line 177, in get_frame
raise error
IndexError: index 30428 is out of bounds for axis 0 with size 30428
Ok, I can reproduce the bug, I will see what is going wrong.
Ok, I removed a "+1" (not where you had changed it) and now it seems to work. I hope I didn't break anything (my other projects still compile, that's a good sign). If that was it, thagt was a silly error, and it means that it wasn't the metadata's fault.
Could you try reinstalling (either from PyPI or github) and send me files for which it still wouldn't work ?
Thanks for your help in debugging this, that might be one of the most annoying bugs in the library !
I have ran a couple hundred renderings, and I can confirm the bug is definitely fixed. Thank you very much! You're awesome.
The following code:
Produces:
A little hack that kinda makes it go away is to do:
Although this doesn't fix anything. It just happens to work in this case, but not for other clips. Why is it crashing?
The wordAudio.duration is 1.04s in this case. On some audio files it crashes, on some it doesn't. Is this the accuracy problem with generating number of frames based on audio length?