2016-01-28 2 views
7

Я искал несколько дней относительно этой проблемы, но не нашел решения. У меня большой скрипт (я пытаюсь объединить большое количество видеороликов, ~ 100-500), поэтому я получаю сообщение об ошибке «Слишком много файлов открыта». Чтение ответов Zulko на другие вопросы, я увидел, что это было необходимо удалить каждый экземпляр VideoFileClip вручную, как это:У экземпляра MoviePy VideoFileClip нет атрибута 'reader'

del clip.reader 
del clip 

Проблема я столкнулся в том, что у меня есть простой hello_world пытается это сделать, но получить ошибка VideoFileClip instance has no attribute 'reader' Вот код:

from moviepy.editor import * 
rel_path = "main.py" 
file_path="hello_world.mp4" 
newVideo = VideoFileClip(file_path) 
del newVideo.reader 
del newVideo 

Я использую El Capitan (OS X), обновили MoviePy, Numpy, ImageMagick, и все пакеты, которые я видел, как это требуется, но я все еще получаю это ошибка. Проблема в том, что мой компьютер иногда замирает, потому что он использует так много памяти. В настоящее время я объединяю фрагменты из 25 видеороликов и пытаюсь удалить все 25 «открытых файлов», объединить следующие 25 и т. Д. После этого я объединил бы более длинные видео.

Пожалуйста, обратите внимание, что без линии дель newVideo.reader я все еще получаю ошибку слишком много открытых файлов

Когда я пытаюсь запустить реальный сценарий, я получаю следующее сообщение об ошибке, если не добавить 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 

По просьбе Тинн, я отправляю «реальный код». Что я здесь делаю, как я объяснил выше, компилируйте видео в кусках из 25 видеороликов, а затем скомпилируйте все эти предварительно скомпилированные видео в одно большое видео. Я получаю ошибку Too Many Files Open прямо сейчас (если я не добавляю дель 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 
+0

В цикле for вы удаляете ссылку, которую вы только что создали. Ты ничего не закрываешь. 'videos_and_subtitles = []' удаляет ссылки в списке. Возможно, даже 50 ссылок в вашем списке и содержание 'preprocessedVideos' - это много. – tynn

+0

Что значит, я ничего не закрываю? Я удаляю каждый элемент в video_and_subtitles каждые 50 видео (или когда я добираюсь до последнего видео). PreprocessedVideos не содержит более 1-3 элементов (это видео, которое было сгенерировано после компиляции 50 видео, поэтому, если у меня есть 150 видео, у меня будет 3 композитных видеоролика) – Waclock

+0

После использования CompositeVideoClip я удаляю его и создаю новая ссылка на новое видео (сделанное из 50 видео). – Waclock

ответ

2

Zulko сам writes:

В следующих версиях MoviePy просто del clip будет достаточно.

Это было до выпуска версии 0.2.2. Так что, похоже, вам не нужно делать del clip.reader.

Чтобы быть более точным, вы не должны этого делать! VideoFileClip определяет деструктор делает это для вас:

def __del__(self): 
    """ Close/delete the internal reader. """ 
    del self.reader 

Но так как вы удалили его уже вы получаете AttributeError:

экземпляр VideoFileClip не имеет атрибут 'читателя'

в <bound method VideoFileClip.__del__ of <...VideoFileClip instance at 0x13..>>

+0

Здравствуйте, Tynn, спасибо за ваш ответ. Вы правы, я забыл упомянуть, что если я только поставлю «del clip», я получаю сообщение об ошибке «Too Many Files Open», так что это тоже не полезно:/ – Waclock

+0

@Waclock вам нужно удалить все ссылки на 'clip' сам. Вы пытались сделать «clip.reader = None»? Это должно иметь тот же эффект, что и удаление без побочного эффекта. – tynn

+0

Я попробую. Я считаю, что у меня есть, я создаю массив и нажимаю каждый объект клипа, затем, итерацию через объект и удаление каждого экземпляра клипа, который у меня есть. – Waclock

0

Я решил свой вопрос, который подробно описан в https://github.com/Zulko/moviepy.

Как только вы установили ImageMagick, он будет автоматически обнаружен MoviePy, кроме Windows! Перед установкой MoviePy вручную пользователям Windows необходимо отредактировать moviepy/config_defaults.py, чтобы указать путь к двоичному файлу ImageMagick, который называется convert. Он должен выглядеть следующим образом: IMAGEMAGICK_BINARY = "C:\\Program Files\\ImageMagick_VERSION\\convert.exe".

Смежные вопросы