Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting AttributeError: 'NoneType' object has no attribute 'get_frame' when trying to save a CompositeVideoClip #2196

Open
Gammer0909 opened this issue Jun 8, 2024 · 0 comments
Labels
question Questions regarding functionality, usage

Comments

@Gammer0909
Copy link

Gammer0909 commented Jun 8, 2024

I'm building a quick script to make some small 9:16 videos automatically from some pre-gathered clips.
However, when I try to add multiple TextClips like this stackoverflow post. This should just create the video, however I'm getting this traceback at the write_videofile():

Traceback (most recent call last):
  File "/workspaces/AutoTube/src/main.py", line 19, in <module>
    main()
  File "/workspaces/AutoTube/src/main.py", line 12, in main
    create_video(True)
  File "/workspaces/AutoTube/src/autovideo/__init__.py", line 14, in create_video
    vid = _create_fact_video()
  File "/workspaces/AutoTube/src/autovideo/__init__.py", line 69, in _create_fact_video
    final.write_videofile('./Output/fact_video.mp4')
  File "<decorator-gen-55>", line 2, in write_videofile
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "<decorator-gen-54>", line 2, in write_videofile
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 135, in use_clip_fps_by_default
    return f(clip, *new_a, **new_kw)
  File "<decorator-gen-53>", line 2, in write_videofile
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 22, in convert_masks_to_RGB
    return f(clip, *a, **k)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/video/VideoClip.py", line 300, in write_videofile
    ffmpeg_write_video(self, filename, fps, codec,
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/video/io/ffmpeg_writer.py", line 220, in ffmpeg_write_video
    for t,frame in clip.iter_frames(logger=logger, with_times=True,
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 472, in iter_frames
    frame = self.get_frame(t)
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/video/compositing/CompositeVideoClip.py", line 111, in make_frame
    f = c.blit_on(f, t)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/video/VideoClip.py", line 527, in blit_on
    img = self.get_frame(ct)
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 136, in <lambda>
    newclip = self.set_make_frame(lambda t: fun(self.get_frame, t))
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/video/VideoClip.py", line 490, in <lambda>
    return self.fl(lambda gf, t: image_func(gf(t)), apply_to)
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 136, in <lambda>
    newclip = self.set_make_frame(lambda t: fun(self.get_frame, t))
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 187, in <lambda>
    return self.fl(lambda gf, t: gf(t_func(t)), apply_to,
  File "<decorator-gen-11>", line 2, in get_frame
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/Clip.py", line 93, in get_frame
    return self.make_frame(t)
  File "/home/codespace/.python/current/lib/python3.10/site-packages/moviepy/video/io/VideoFileClip.py", line 113, in <lambda>
    self.make_frame = lambda t: self.reader.get_frame(t)
AttributeError: 'NoneType' object has no attribute 'get_frame'

As you can see from the traceback, somewhere I'm getting a None clip?

Here's the function (including my print debugs)

def _create_fact_video() -> str:
    # First, create the clip
	with _get_clip(f'./Assets/gameplay.mp4') as clip:
		print('Randomized Clip, editing...')
		fact = _get_random_fact()
		print(f'Got random fact!\nFact for the video is \"{fact}\"')
		# Create the tts file
		print('Creating audio...')
		tts_file = _get_tts(fact)
		print(f'Audio created successfully at {tts_file}')
		# Create a TextClip of the fact, for the duration of the tts file
		print('Creating text...')
		text = mp.TextClip(fact, fontsize=24, color='white', bg_color='black')
		# First, the intro
		intro_text = mp.TextClip('Interesting Fact of the Day', fontsize=24, color='white', bg_color='black')
		# Next, the ad
		ad_text = mp.TextClip('Ad', fontsize=24, color='white', bg_color='black')
		print('Text created successfully')
		print('Editing audio...')
		# Get the duration of the mp3 file, at ./Output/output.mp3
		audio = mp.AudioFileClip(tts_file)
		# Get the ending ad at ./Assets/ad.mp3
		ad = mp.AudioFileClip('./Assets/ad.mp3')
		# Get the Intro at Assets/factOpening.mp3
		intro = mp.AudioFileClip('./Assets/factOpening.mp3')

		# Set each textclip duration to the corresponding audio
		intro_text = intro_text.set_duration(intro.duration)
		text = text.set_duration(audio.duration)
		ad_text = ad_text.set_duration(ad.duration)
		print('Audio accessed, editing...')
		# Create the final audio
		final_audio = mp.concatenate_audioclips([intro, audio, ad])
		print('Audio edited successfully')
		print('Cutting final video together...')
		clip.set_audio(final_audio)
		final = mp.CompositeVideoClip([clip, intro_text, text, ad_text])
		final = final.set_audio(final_audio)
		final = final.set_duration(audio.duration + intro.duration + ad.duration)
		print('Video cut together successfully')
		print('Writing video...')
		# Save the video
		final.write_videofile('./Output/fact_video.mp4')
	print('Video written successfully at ./Output/fact_video.mp4')
	return './Output/fact_video.mp4'

(Side note: It shouldn't be in the _get_clip() function, however I'll provide that If I need to)

Is there anything I'm doing wrong?

thanks :)

@Gammer0909 Gammer0909 added the question Questions regarding functionality, usage label Jun 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Questions regarding functionality, usage
Projects
None yet
Development

No branches or pull requests

1 participant