Szukałem kilku dni w związku z tym problemem, ale nie znalazłem rozwiązania. Mam duży skrypt (próbuję połączyć dużą liczbę filmów, ~ 100-500), dlatego pojawił się błąd "Zbyt wiele otwartych plików". Czytając odpowiedzi Zulko do innych zagadnień, widziałem, że to było konieczne, aby usunąć każdą instancję VideoFileClip ręcznie tak:Instancja MoviePy VideoFileClip nie ma atrybutu "czytnik"
del clip.reader
del clip
Problem mam w obliczu jest, że mam prosty hello_world starając się to zrobić, ale dostać błąd VideoFileClip instance has no attribute 'reader'
Oto kod:
from moviepy.editor import *
rel_path = "main.py"
file_path="hello_world.mp4"
newVideo = VideoFileClip(file_path)
del newVideo.reader
del newVideo
Używam El Capitan (OS X), zostały zaktualizowane MoviePy, Numpy, ImageMagick, a wszystkie pakiety widziałem jak jest to wymagane, ale nadal jestem coraz to błąd. Problemem jest to, że mój komputer czasami zamarza, ponieważ zużywa tyle pamięci. Aktualnie łączę 25 kawałków i próbuję usunąć wszystkie 25 "otwartych plików", połączyć kolejne 25 i tak dalej. Potem połączyłem dłuższe filmy.
Należy pamiętać, że bez linii del newVideo.reader nadal pojawia się błąd Zbyt wiele plików otworzyć
gdy próbuję działa prawdziwy scenariusz, pojawia się następujący błąd, jeśli ja nie dodawać 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
Zgodnie z życzeniem Tynn, publikuję "prawdziwy kod". To, co tu robię, to, jak wyjaśniłem powyżej, kompilacja filmów w porcjach 25 filmów, a następnie skompilowanie wszystkich tych wstępnie skompilowanych filmów w jeden duży film. Dostaję błąd Too Many Files Open
teraz (jeśli nie dodawać del clip.reader) sam
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
W pętli for usuniesz odwołanie, które właśnie utworzyłeś wcześniej. Nic tam nie zamykasz. 'videos_and_subtitles = []' usuwa odniesienia na liście. Może nawet ~ 50 referencji na twojej liście i zawartość 'preprocessedVideos' są za dużo. – tynn
Co masz na myśli, że niczego nie zamykam? Każdego elementu usuwam w videos_and_subtitles co 50 filmów (lub kiedy docieram do ostatniego filmu). W preprocessedVideos nie zawiera więcej niż 1-3 elementów (jest to wideo, które zostało wygenerowane po skompilowaniu 50 filmów, więc jeśli mam 150 filmów, będę miał 3 teledyski złożone) – Waclock
Po użyciu polecenia CompositeVideoClip, usunę go i utworzę nowe odniesienie do nowego wideo (wykonane z 50 filmów). – Waclock