Мое решение немного неортодоксально, потому что оно зависит от библиотеки.Mydia позволяет передавать кадры для извлечения вместо того, чтобы заставить Videos
клиента производить сэмплирование напрямую.Это дает мне возможность предварительно рассчитать кадры для выборки в родительском процессе.Делая это, я могу «высмеивать» случайность в подпроцессах, создавая новый Videos
с этими кадрами.Например:
class MySampler:
def __init__(self, input_directory: Path, total_frames: int, num_frames: int, fps: int):
self.input_directory = Path(input_directory)
self.frames_per_video = [
self.__get_frame_numbers_for_each_video(total_frames, num_frames, fps)
for _ in self.input_directory.glob("*.mp4")
]
@staticmethod
def get_reader(num_frames: int, frames: List[int]):
# ignores the inputs and returns samples the frames that its constructed with
return Videos(target_size=(512, 512), num_frames=num_frames, mode=lambda *_: frames)
, и тогда я могу просто распараллелить это:
def sample_frames(self, number_of_workers: int):
pool = Pool(processes=number_of_workers)
videos = list(self.input_directory.glob("*.mp4"))
pool.starmap_async(self.read_video, zip(self.frames_per_video, videos))
pool.close()
pool.join()
, где read_video
- это метод, который вызывает get_reader
и выполняет чтение.