I've searched for a few days regarding this issue but have come to no solution. I have a big script (I'm trying to concatenate large number of videos, ~100-500), which is why I was getting the error "Too many files open". Reading Zulko's responses to other issues, I saw that it was necessary to delete each VideoFileClip instance manually like this:
del clip.reader
del clip
The issue I'm facing is that I have a simple hello_world trying to do this, but get the error VideoFileClip instance has no attribute 'reader'
Here's the code:
from moviepy.editor import *
rel_path = "main.py"
file_path="hello_world.mp4"
newVideo = VideoFileClip(file_path)
del newVideo.reader
del newVideo
I'm using El Capitan (OS X), have updated MoviePy, Numpy, ImageMagick, and all packages I've seen as required, but I'm still getting this error. The problem is my computer ends up freezing sometimes because it's using so much memory. I'm currently concatenating chunks of 25 videos, and trying to delete all 25 "opened files", concatenate the next 25, and so forth. After that I'd concatenate the longer videos.
Please note that without the line del newVideo.reader I still get the error Too many files open
When I try running the real script, I get the following error if I don't add newVideo.reader
Traceback (most recent call last):
File "/Users/johnpeebles/mispistachos/vines/video/reader.py", line 135, in compile_videos
newVideo = VideoFileClip(videoPath).resize(height=finalHeight,width=finalWidth).set_position('center').set_start(currentDuration)
File "/Library/Python/2.7/site-packages/moviepy/video/io/VideoFileClip.py", line 55, in __init__
reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)
File "/Library/Python/2.7/site-packages/moviepy/video/io/ffmpeg_reader.py", line 32, in __init__
infos = ffmpeg_parse_infos(filename, print_infos, check_duration)
File "/Library/Python/2.7/site-packages/moviepy/video/io/ffmpeg_reader.py", line 237, in ffmpeg_parse_infos
proc = sp.Popen(cmd, **popen_params)
File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 710, in __init__
errread, errwrite)
File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1223, in _execute_child
errpipe_read, errpipe_write = self.pipe_cloexec()
File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/subprocess.py", line 1175, in pipe_cloexec
r, w = os.pipe()
OSError: [Errno 24] Too many open files
Error compiling videos
Exception AttributeError: "VideoFileClip instance has no attribute 'reader'" in <bound method VideoFileClip.__del__ of <moviepy.video.io.VideoFileClip.VideoFileClip instance at 0x136e46908>> ignore
As requested by Tynn, I'm posting the "real code". What I'm doing here is, as I explained above, compile videos in chunks of 25 videos, then compile all these pre-compiled videos into one big video. I'm getting the error Too Many Files Open
right now (if I don't add del clip.reader)
for videoObject in data["videos"]:
counter+=1
#Download video and thumbnail
downloader=urllib.URLopener()
videoId = videoObject[API_VIDEO_ID]
videoUrl = str(videoObject[API_VIDEO_URL])
videoPath =os.path.join(file_dir, "tmp",str(videoObject[API_VIDEO_ID].replace("/",""))+'_video.mp4')
thumbPath =os.path.join(file_dir, "tmp",str(videoObject[API_VIDEO_ID].replace("/",""))+'_thumb.jpg')
currentVideoDimension = videoObject[API_VIDEO_DIMENSIONS]
currentVideoWidth = currentVideoDimension[0]
currentVideoHeight = currentVideoDimension[1]
thumbUrl = str(videoObject[API_THUMB_URL])
finalWidth = w*1.0
finalHeight = h*1.0
videoProportion = (float(currentVideoWidth)/float(currentVideoHeight))
if currentVideoWidth >= currentVideoHeight:
finalHeight = finalWidth/videoProportion
else:
finalWidth = finalHeight*videoProportion
try:
download(videoUrl, videoPath)
download(thumbUrl, thumbPath)
except Exception as e:
print("Exception: "+str(e))
print("Video ID: "+str(videoId))
traceback.print_exc()
continue
#Create new video and update video duration's offset
newVideo = VideoFileClip(videoPath).resize(height=finalHeight,width=finalWidth).set_position('center').set_start(currentDuration)
#If it's not squared we append a video first
if videoProportion != float(1):
backgroundClip = ColorClip(size=((w,h)), col=colors.hex_to_rgb("#000")).set_position("center").set_start(currentDuration).set_duration(newVideo.duration)
videos_and_subtitles.append(backgroundClip)
#Append new video to videos
videos_and_subtitles.append(newVideo)
#Append subtitle to Subtitles
# newSubtitleText = max_text(videoObject[API_NAME],videoObject[API_AUTHOR])+" \n\n"+videoObject[API_AUTHOR]
videoName = clean(videoObject[API_NAME])
videoAuthor = clean(videoObject[API_AUTHOR])
newSubtitleText = clean(max_text(videoName,videoAuthor)+" \n\n"+videoObject[API_AUTHOR])
newSubtitle = ( TextClip(newSubtitleText,fontsize=70,color='white',font='Helvetica-Narrow',align='center',method='caption',size=titleDimensions).set_start(currentDuration).set_position((videoOffset+w,0)).set_duration(newVideo.duration) )
videos_and_subtitles.append(newSubtitle)
currentDuration+=newVideo.duration
#Preprocess videos
if counter%50==0 or len(data["videos"])==(counter):
if closure_video_path != None and closure_video_path != "" and len(data["videos"])==(counter):
newVideo = VideoFileClip(closure_video_path).resize(height=finalHeight,width=finalWidth).set_position((videoOffset,titleOffset)).set_start(currentDuration)
videos_and_subtitles.append(newVideo)
currentDuration+=closure_video_duration
currentFilename=os.path.join(file_dir, "tmp",str(videoNumber)+fileName)
result = CompositeVideoClip(videos_and_subtitles,size=movieDimensions,bg_color=colors.hex_to_rgb(background_color)).set_duration(currentDuration).write_videofile(filename=currentFilename,preset='ultrafast',fps=24)
del result
preprocessedVideos.append(VideoFileClip(currentFilename))
#Close files
#close_files(videos_and_subtitles)
for clip in videos_and_subtitles:
try:
if not (isinstance(clip,ImageClip) or isinstance(clip,TextClip)):
del clip
else:
del clip
except Exception,e:
print "Exception: "+str(e)
#End Close files
videos_and_subtitles = []
videos_and_subtitles.append(left_holder)
currentDuration = 0
videoNumber+=1
if (videoObject==data["videos"][-1]):
break
print("Next video")
print("Compiling video")
filepath = os.path.join(file_dir, "tmp",fileName)
result = concatenate_videoclips(preprocessedVideos).write_videofile(filename=filepath, preset='ultrafast')
#result = CompositeVideoClip(videos_and_subtitles,size=movieDimensions,bg_color=(0,164,119)).set_duration(currentDuration).write_videofile(filename=directory+"/"+fileName,preset='ultrafast')
print("Video Compiled")
now = datetime.datetime.now()
print("Finished at: "+str(now))
return filepath
except Exception as e:
print("Exception: "+str(e))
print("Video ID: "+str(videoId))
traceback.print_exc()
rollbar.report_exc_info()
return None
Zulko himself writes:
In the next versions of MoviePy just
del clip
will suffice.
This was before version 0.2.2 was released. So it seems like you don't need to do del clip.reader
.
To be more precise you mustn't do it! VideoFileClip
defines a destructor doing this for you:
def __del__(self):
""" Close/delete the internal reader. """
del self.reader
But since you've deleted it already you get the AttributeError
:
VideoFileClip instance has no attribute 'reader'
in <bound method VideoFileClip.__del__ of <...VideoFileClip instance at 0x13..>>
I have solved my question, which is described in detail at https://github.com/Zulko/moviepy.
Once you have installed ImageMagick, it will be automatically detected by MoviePy, except on Windows! Before installing MoviePy by hand, Windows users need to edit moviepy/config_defaults.py
to provide the path to the ImageMagick binary, which is called convert. It should look like this:
IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\convert.exe"
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With