Skip to content

Commit 712ffcb

Browse files
authored
Removing duration for mpg movies calculation. moviepy 2.* appears to have fixed this. Added duration keyword for movie generatoin to allow setting in case moviepy gets it wrong. (#926)
1 parent 956b7a6 commit 712ffcb

File tree

1 file changed

+14
-31
lines changed

1 file changed

+14
-31
lines changed

act/utils/io_utils.py

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ def unpack_gzip(filename, write_directory=None, remove=False):
280280
return str(write_filename)
281281

282282

283-
def generate_movie(images, write_filename=None, fps=10, **kwargs):
283+
def generate_movie(images, write_filename=None, fps=10, duration=None, **kwargs):
284284
"""
285285
Creates a movie from a list of images or convert movie to different type
286286
@@ -296,6 +296,9 @@ def generate_movie(images, write_filename=None, fps=10, **kwargs):
296296
that does not exist, will create the directory path.
297297
fps: int
298298
Frames per second. Passed into moviepy->ImageSequenceClip() method
299+
duration : float, int or None
300+
Converting mpg format can have issues with reading the duration of the movie. Set
301+
to number of seconds to override the derived value if the result is not what you expect.
299302
**kwargs: dict
300303
Optional keywords passed into moviepy->write_videofile() method
301304
@@ -309,6 +312,9 @@ def generate_movie(images, write_filename=None, fps=10, **kwargs):
309312
if not MOVIEPY_AVAILABLE:
310313
raise ImportError('MoviePy v2.X needs to be installed on your system to make movies.')
311314

315+
if int(moviepy.__version__.split('.')[0]) <= 1:
316+
raise ImportError('MoviePy v2.X needs to be installed on your system to make movies.')
317+
312318
# Set default movie name
313319
if write_filename is None:
314320
write_filename = Path(Path().cwd(), 'movie.mp4')
@@ -332,36 +338,13 @@ def generate_movie(images, write_filename=None, fps=10, **kwargs):
332338
with VideoFileClip(images) as clip:
333339
# There can be an issue converting mpeg to other movie format because the
334340
# duration parameter in the movie file is not set. So moviepy guesses and
335-
# can get the duration wrong. This will find the correct duration (correct to 0.2 seconds)
336-
# and set before writing.
337-
if Path(images).suffix == '.mpg':
338-
import numpy as np
339-
import warnings
340-
from collections import deque
341-
342-
with warnings.catch_warnings():
343-
warnings.filterwarnings('ignore', category=UserWarning)
344-
desired_len = 3
345-
frame_sums = deque()
346-
duration = 0.0 # Duration of movie in seconds
347-
while True:
348-
result = clip.get_frame(duration)
349-
frame_sums.append(np.sum(result))
350-
if len(frame_sums) > desired_len:
351-
frame_sums.popleft()
352-
353-
if len(set(frame_sums)) == 1:
354-
break
355-
356-
duration += 0.1
357-
358-
clip = clip.with_start(0)
359-
clip = clip.with_duration(duration)
360-
clip = clip.with_end(duration)
361-
clip.write_videofile(str(write_filename), **kwargs)
362-
363-
else:
364-
clip.write_videofile(str(write_filename), **kwargs)
341+
# can get the duration wrong.
342+
if duration is not None:
343+
clip = clip.with_start(0)
344+
clip = clip.with_duration(duration)
345+
clip = clip.with_end(duration)
346+
347+
clip.write_videofile(str(write_filename), **kwargs)
365348

366349
else:
367350
clip = moviepy.video.io.ImageSequenceClip.ImageSequenceClip(images, fps=fps)

0 commit comments

Comments
 (0)