Я пытаюсь создать большое видео из ~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.