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

Moviepy ffmpeg issue #2349

Open
XRYong opened this issue Jan 26, 2025 · 18 comments
Open

Moviepy ffmpeg issue #2349

XRYong opened this issue Jan 26, 2025 · 18 comments
Labels
question Questions regarding functionality, usage

Comments

@XRYong
Copy link

XRYong commented Jan 26, 2025

Clip 1 FPS: 29.97002997002997
Clip 2 FPS: 23.976023976023978
Moviepy - Building video output/short.mp4.
MoviePy - Writing audio in shortTEMP_MPY_wvf_snd.mp3
MoviePy - Done.
Moviepy - Writing video output/short.mp4

Traceback (most recent call last):
  File "/home/andrew/Codes/AutomatedYouTubeShorts/main.py", line 85, in <module>
    create_short(clip1=moutain, clip2=rain, clip1dura=cl1dura, clip2dura=cl2dura, narr=narr, music="src/RiseAbove.mp3", output_folder="output")
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/andrew/Codes/AutomatedYouTubeShorts/main.py", line 71, in create_short
    combined.write_videofile(output_short, temp_audiofile="temp-audio.m4a", remove_temp=True, fps=default_fps)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.13/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/usr/lib/python3.13/site-packages/moviepy/decorators.py", line 54, in requires_duration
    return f(clip, *a, **k)
  File "/usr/lib/python3.13/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/usr/lib/python3.13/site-packages/moviepy/decorators.py", line 135, in use_clip_fps_by_default
    return f(clip, *new_a, **new_kw)
  File "/usr/lib/python3.13/site-packages/decorator.py", line 232, in fun
    return caller(func, *(extras + args), **kw)
  File "/usr/lib/python3.13/site-packages/moviepy/decorators.py", line 22, in convert_masks_to_RGB
    return f(clip, *a, **k)
  File "/usr/lib/python3.13/site-packages/moviepy/video/VideoClip.py", line 300, in write_videofile
    ffmpeg_write_video(self, filename, fps, codec,
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       bitrate=bitrate,
                       ^^^^^^^^^^^^^^^^
    ...<4 lines>...
                       ffmpeg_params=ffmpeg_params,
                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                       logger=logger)
                       ^^^^^^^^^^^^^^
  File "/usr/lib/python3.13/site-packages/moviepy/video/io/ffmpeg_writer.py", line 213, in ffmpeg_write_video
    with FFMPEG_VideoWriter(filename, clip.size, fps, codec = codec,
         ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                preset=preset, bitrate=bitrate, logfile=logfile,
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                audiofile=audiofile, threads=threads,
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                                ffmpeg_params=ffmpeg_params) as writer:
                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.13/site-packages/moviepy/video/io/ffmpeg_writer.py", line 88, in __init__
    '-r', '%.02f' % fps,
          ~~~~~~~~^~~~~
TypeError: must be real number, not NoneType
import os
from moviepy.editor import VideoFileClip, concatenate_videoclips, AudioFileClip, CompositeAudioClip
from gtts import gTTS
from mutagen.mp3 import MP3
import moviepy.editor as mp

# Video file paths
moutain = "src/mountain_climbing.mp4"
rain = "src/running_in_rain.mp4"

# Get the input from the user
print("Enter a motivation speech")
motivation_speech = input()
print("Enter the name of the speaker")
speaker = input()

# Clip Durations
if speaker == "":
    clip_durations = {
        "motivation": 30,
        "speak": 0
    }
    fullClipDuration = sum(clip_durations.values())
else:
    clip_durations = {
        "motivation": 30,
        "speak": 5
    }
    fullClipDuration = sum(clip_durations.values())

# Video Variables
language = "en"
title = "\"" + motivation_speech + "\" -" + speaker

def create(motivation_speech, speaker, output_folder):
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)

    if speaker == "":
        speaker = ""
    else:
        speaker = " was said by " + speaker

    narr = motivation_speech + speaker
    print(narr, output_folder)
    output_file = os.path.join(output_folder, "output.mp3")
    outputs = gTTS(text=narr, lang=language, slow=False)
    outputs.save(output_file)

narr = motivation_speech + speaker

def create_short(clip1, clip2, clip1dura, clip2dura, narr, music, output_folder):
    clip1 = VideoFileClip(clip1).subclip(0, float(clip1dura)).fx(mp.vfx.fadeout, 1)
    clip2 = VideoFileClip(clip2).subclip(0, float(clip2dura)).fx(mp.vfx.fadeout, 1)
    print(f"Clip 1 FPS: {clip1.fps}")
    print(f"Clip 2 FPS: {clip2.fps}")

    default_fps = 24
    if clip1.fps is None:
        clip1 = clip1.set_fps(default_fps)
    if clip2.fps is None:
        clip2 = clip2.set_fps(default_fps)

    # Combine the video clips
    combined = concatenate_videoclips([clip1, clip2])

    # Add narration and background music
    audio1 = os.path.join(output_folder, "output.mp3")
    audio = MP3(audio1)
    audio_duration = audio.info.length
    narration = AudioFileClip(audio1)
    background_music = AudioFileClip(music).subclip(0, audio_duration)
    final_audio = CompositeAudioClip([narration, background_music])
    combined = combined.set_audio(final_audio)

    # Define the output file path
    output_short = os.path.join(output_folder, "short.mp4")

    # Write the combined video to a file
    combined.write_videofile(output_short, codec="libx264", audio_codec="aac", temp_audiofile="temp-audio.m4a", remove_temp=True, fps=default_fps)

# Create the narration audio file
create(motivation_speech=motivation_speech, speaker=speaker, output_folder="output")

# Get the audio duration
audio = os.path.join("output", "output.mp3")
audio = MP3(audio)
audio_duration = audio.info.length

print(audio_duration)

# Get the clip durations from the user
cl1dura = input("Enter the duration of the first clip: ")
cl2dura = input("Enter the duration of the second clip: ")

# Create the short video
create_short(clip1=moutain, clip2=rain, clip1dura=cl1dura, clip2dura=cl2dura, narr=narr, music="src/RiseAbove.mp3", output_folder="output")

OS VERSION:

endeavour os (arch distribution)
packages: up-to-date
package manager: pacman and chaotic

PC:
cpu: intel core i7 14700kf
gpu: rtx 4060
memory: kingston memory 32gb 5600mt/s

ISSUE

When using moviepy to render video ffmpeg error will pop up with '-r', '%.02f' % fps,
~~~~~~~~^~~~~
TypeError: must be real number, not NoneType

@XRYong XRYong added the question Questions regarding functionality, usage label Jan 26, 2025
@XRYong
Copy link
Author

XRYong commented Jan 26, 2025

I've try reinstalling everything and checking for solutions online even try reinstalling pip modules with pacman (sudo pacman -U python-modules and sudo pacman -S python-modules) modules are: moviepy etc
Reinstalling ffmpeg doesn't work
I've updated all system packages

@Implosiv3
Copy link
Contributor

Implosiv3 commented Jan 26, 2025

Can you try just using the combined.write_videofile(output_short) line with no more attributes and tell us if it works? It should get the fps automatically from the combined clip.

And, can you print the combined.fps before writing it?

By the way, thanks for the detailed post. I think it is something within the library code (maybe the @use_clip_fps_by_default decorator), because the parameter is being passed correctly but your code says the error is in moviepy. We will 👀

@XRYong
Copy link
Author

XRYong commented Jan 27, 2025

Still same error....
Combined FPS 24

@XRYong
Copy link
Author

XRYong commented Jan 27, 2025

Can you try just using the combined.write_videofile(output_short) line with no more attributes and tell us if it works? It should get the fps automatically from the combined clip.

And, can you print the combined.fps before writing it?

By the way, thanks for the detailed post. I think it is something within the library code (maybe the @use_clip_fps_by_default decorator), because the parameter is being passed correctly but your code says the error is in moviepy. We will 👀

No it doesn't work... I've recently switched to endeavour os. Is there a way that I can fix this error?

@XRYong
Copy link
Author

XRYong commented Jan 27, 2025

Also, do you mind helping me with another issue?
I've a line that write resized_video = output_short.resize((height, width))
But in my code editor resize is underline with red squiggly lines. Thanks!

@Implosiv3
Copy link
Contributor

Mmm... I don't have an answer for the first thing yet.

The new version of moviepy includes the resized method (with a d at the end) instead of resize. This is to be more natural because what you get is a clip that is resized.

@XRYong
Copy link
Author

XRYong commented Jan 27, 2025

Mmm... I don't have an answer for the first thing yet.

The new version of moviepy includes the resized method (with a d at the end) instead of resize. This is to be more natural because what you get is a clip that is resized.

Thanks btw should I try this script again on my windows system? See if the script runs?

@XRYong
Copy link
Author

XRYong commented Jan 27, 2025

Mmm... I don't have an answer for the first thing yet.

The new version of moviepy includes the resized method (with a d at the end) instead of resize. This is to be more natural because what you get is a clip that is resized.

I saw some issue on this online but the fixes won't work

@OsaAjani
Copy link
Collaborator

motivation_speech 🤮

@XRYong
Copy link
Author

XRYong commented Jan 27, 2025

motivation_speech 🤮

💀 its like a yt shorts generator

@XRYong
Copy link
Author

XRYong commented Jan 28, 2025

Do you have any idea what's the issue

@OsaAjani
Copy link
Collaborator

Can you please provide a short code snippet reproducing the error, and describe exactly what is the expected vs actual behaviour ? We are willing to try and find if their is a bug in moviepy, but we need some code we can easily run to do so.

@OsaAjani
Copy link
Collaborator

OsaAjani commented Feb 4, 2025

Hi, any news or should i close this one ?

@XRYong
Copy link
Author

XRYong commented Feb 5, 2025

Hi sorry I've not checked GitHub for a while

@XRYong
Copy link
Author

XRYong commented Feb 5, 2025

Hi, the rendering section of the code (not audio)

@XRYong
Copy link
Author

XRYong commented Feb 5, 2025

create_short(clip1=moutain, clip2=rain, clip1dura=cl1dura, clip2dura=cl2dura, narr=narr, music="src/RiseAbove.mp3", output_folder="output") here :D

@OsaAjani
Copy link
Collaborator

OsaAjani commented Feb 5, 2025

Hi, I would need a simpler code that I can easily run to reproduce, not something needing some input, files, google text to speech, etc. Please provide such a short demo as a zip for example, so I can just uncompress it and run it to stack trace the code and debug.

@XRYong
Copy link
Author

XRYong commented Feb 6, 2025

Ok :D I'll do it later

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

3 participants