Я пытаюсь создать большое видео из ~400 видео, однако у меня возникают проблемы с "Открыто слишком много файлов"

Я пытаюсь создать большое видео из ~400 видео, однако у меня возникают проблемы с "Открыто слишком много файлов". Я прочитал документацию (и увидел этот пост).

Однако я все еще получаю ту же ошибку: OSError: [Errno 24] Too many open files

Я исследовал и не знаю, что еще делать, если я уже удаляю каждый открытый фильм методом close_files,

Код:

from moviepy.editor import *
import json
import os
import urllib
import shutil
import re
import api.constants
import traceback
from api.constants import *
import datetime
import string


def close_files(files):
    for file in files:
        try:
            if not (isinstance(file,ImageClip) or isinstance(file,TextClip)):
                del file.reader
            del file
        except Exception,e:
            print "Exception: "+str(e)

def max_text(title,author):
    return title
    #if len(title) > 120:
    #    return title[0:(120- len(author))]+"..."
    #else:
    #    return title

def clean(text):
    return ''.join(filter(lambda x: x in string.printable, text))

def compile_videos(fileName,serverjson,post_to):
    try:
        now = datetime.datetime.now()
        print "Starting at: "+str(now)

        #Video's dimensions
        w = 1440
        h = 1440
        videoDimension = w,h

        #Video offset
        videoOffset = 580
        titleOffset = 0

        #Movie dimensions
        w2 = 2560
        h2 = 1440
        movieDimensions = w2,h2

        #Title dimensions
        w3 = 540
        h3 = 1440
        titleDimensions = w3,h3

        #Left Holder Dimension
        holderDimensions = 500,500
        holderPosition = 50,450


        #Holder
        left_holder = ImageClip("assets/everyday_icon.png").set_position(holderPosition)
        if post_to=="7min":
            left_holder = ImageClip("assets/7min_icon.png").set_position(holderPosition)
        elif post_to=="7x7":
            left_holder = ImageClip("assets/7x7_icon.png").set_position(holderPosition)

        #Temporal directory
        directory = 'tmp'
        if os.path.exists(directory):
          shutil.rmtree(directory)
        if not os.path.exists(directory):
          os.makedirs(directory)

        #Read Videos/Files

        data = serverjson

        videos_and_subtitles = []
        #We add the holder so that there's always a background
        videos_and_subtitles.append(left_holder)

        currentDuration = 0
        videoId = ""
        preprocessedVideos = []
        counter = 0
        videoNumber = 0
        print "Total videos: "+str(len(data["videos"]))
        for videoObject in data["videos"]:
            counter+=1
            #Download video and thumbnail
            downloader=urllib.URLopener()
            videoId = videoObject[API_VIDEO_ID]
            videoPath = directory+"/"+str(videoObject[API_VIDEO_ID])+'_video.mp4'
            thumbPath = directory+"/"+str(videoObject[API_VIDEO_ID])+'_thumb.jpg'
            try:
                downloader.retrieve(str(videoObject[API_VIDEO_URL]),videoPath)
                downloader.retrieve(str(videoObject[API_THUMB_URL]),thumbPath)
            except Exception,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=w,width=h).set_position((videoOffset,titleOffset)).set_start(currentDuration)
            #Append new video to videos

            videos_and_subtitles.append(newVideo)
            #Append subtitle to Subtitles
            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):
                currentFilename=directory+"/"+str(videoNumber)+fileName
                result = CompositeVideoClip(videos_and_subtitles,size=movieDimensions,bg_color=(0,164,119)).set_duration(currentDuration).write_videofile(filename=currentFilename,preset='ultrafast',fps=24)
                preprocessedVideos.append(VideoFileClip(currentFilename))
                close_files(videos_and_subtitles)
                videos_and_subtitles = []
                currentDuration = 0
                videoNumber+=1
                if (videoObject==data["videos"][-1]):
                    break
            print "Next video"

        print "Compiling video"
        result = concatenate_videoclips(preprocessedVideos).write_videofile(filename=directory+"/"+fileName,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 fileName
    except Exception,e:
        print "Exception: "+str(e)
        print "Video ID: "+str(videoId)
        traceback.print_exc()
        return None

Я обрабатываю файлы партиями по 50, потому что это занимает больше времени, если я делаю это небольшими партиями. Проблема не в том, чтобы открыть сразу 50 файлов. Проблема возникает после первого или второго пакета (обработано ~100-150 файлов), это указывает на то, что файлы не закрываются (в противном случае первый пакет не был бы обработан правильно). Это означает, что то же самое происходит, если я делаю это партиями по 10, просто файлы закрываются неправильно

Другие посты, как этот, как вы можете видеть ответ:

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

Не совсем применимо, так как я перезаписываю экземпляр каждые 50 итераций, однако у меня все еще есть проблема.

Кроме того, я не могу вызвать "закрыть" на VideoFileClip.

0 ответов

Другие вопросы по тегам