-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Project quality? #1976
Comments
@sausix what's your project? Is it available to use? |
@batmanscode It's still in dev state and does not output video yet. Here's my feature list so far: # Features
- Templating and automation
- Parallel processing and caching on rendering if possible
- Immutable Clips
- "KISAP"? - Keep it simple and pythonic.
- No expensive processing within Python. ffmpeg's internal processing is on priority.
- Not reinventing the wheel. External tools are perfect and keep the project's code small and clean.
# ToDo
- resolution & fps vs. cache?
- Stream interface for Clip classes
- Transitions with \_\_add__()
- Encoder interface
- Jupyter integration?
- Docs and tests :-)
- Get community, feedback and love :-)
# Clip ToDo
- FFmpeg base
- Transform
- Filter
- Crossfade
- ClipSequence compare formats
# Roadmap
- Optional UI managing and helping with the python code.
- Animations, vector based (+motion blur) Here's a sneak peek containing the principle and syntax for a video project: # Define cache before first Clip instance or else it will
# be created implicitly as "cwd/cache"
cache = Cache("/tmp/project.cache", discard_missing=True) # Or define a non volatile place
# discard_missing should be True on project caches (default)
# and False on global caches for multiple projects.
# Assign the cache to the base class for all clips
Clip.set_root_cache(cache)
# Project constants
fps = 60
resolution = 1920, 1080
# Static sources
intro = FileClip("/home/user/intro.mpv") # Missing
outro = FileClip("outro.mpv") # Missing
# Images
agenda = ImageFromFile("/home/as/Screenshot_20201207_064554.png")
# print(agenda.size)
# print(agenda.format)
# Video files
video1 = FileClip("/home/as/Rick Astley - Never Gonna Give You Up.mp4", master_format=True)
# master_format: This format will be preferred for other clips.
print(video1) # <FileClip:/home/as/Rick Astley - Never Gonna Give You Up.mp4>
print(video1.video_format) # VideoFormat(codec_name='av1', codec_type='video', codec_tag_string='av01', profile='Main', time_base='1/12800', width=1920, height=1080, coded_width=1920, coded_height=1080, pix_fmt='yuv420p', r_frame_rate='25/1', level=8)
print(video1.audio_format) # AudioFormat(codec_name='aac', codec_type='audio', codec_tag_string='mp4a', profile='LC', time_base='1/44100', channels=2, channel_layout='stereo', sample_fmt='fltp', sample_rate='44100')
video2 = FileClip("testmedia/x264-1080p60.mkv")
print(video2) # <FileClip[V]:testmedia/x264-1080p60.mkv>
print(video2.video_format) # VideoFormat(codec_name='h264', codec_type='video', codec_tag_string='[0][0][0][0]', profile='High 4:4:4 Predictive', time_base='1/1000', width=1920, height=1080, coded_width=1920, coded_height=1080, pix_fmt='yuv444p', r_frame_rate='60/1', level=50)
print(video2.audio_format) # None
# Do some simple magic with clips
mainvideo = video1 * 2 + video2
def make_video_as_always(main: Clip) -> Clip:
"""
Helper function to compose a full video.
Just add the main clip
"""
# ToDo: Crossfades
# return intro + Crossfade(duration=1) + ImageClip(agenda, 2.) + main + Crossfade(duration=1) + outro
return intro + ImageClip(agenda, 2.) + main + outro
final_video = make_video_as_always(mainvideo)
print(final_video) # Gives repr()
# <ClipSequence:⇻(<FileClip[?]:/home/user/intro.mpv>, <ImageClip[V]:2.0s:<ImageFromFile:/home/as/Screenshot_20201207_064554.png>>, <FileClip:/home/as/Rick Astley - Never Gonna Give You Up.mp4>, <FileClip:/home/as/Rick Astley - Never Gonna Give You Up.mp4>, <FileClip[V]:testmedia/x264-1080p60.mkv>, <FileClip[?]:outro.mpv>)>
final_video.render("/tmp/test.mkv", resolution, fps)
# Will use multiple processes
# Make use of cache if available or at least create it for the next run |
Wow that looks great! Looking forward to using it @sausix, good luck with the rest of the development The video magic is very cool! And I appreciate the "Not reinventing the wheel" and "keep the project's code small and clean" 🙂 |
On the other hand, maybe you just wanted to give your opinion and you didn't need to check what was the state of things (for example those two prs I mentioned are very recent). |
@mgaitan I always prefer colaboration instead of forking or creating a new projects. But...
I know moviepy has a lot of work inside and a lot of users. But I've browsed the code and had a lot of "ooof" moments. So why not making a deeper cut? Maybe my project will be moviepy 2.0? Anyway. I've pushed my code as dev preview. Rendering is not yet implemented. https://github.com/sausix/scriptycut |
@sausix excellent, thanks for sharing. I'll be around looking for your progress. Regarding ffmpeg rendering (and reading), and in the spirit of "not reinventing the wheel", I'd recommended you to take a look to imageio v3 , that's something we would like for movipy itself. |
@mgaitan Thanks. I'm using imageio.v3 already in image.py. I'll try not to use imageio for every rendering process. ffmpeg as as ton of filters, effects and transistions. |
I've opened this project in PyCharm and a lot of problems appeared immediately. Mostly docstrings out of date, type mismatches and strange decorator usages.
Most Python devs don't know about type hinting and annotations. Programming in Python should never be guessing function or method names. It's not that hard to implement! Typing is fun and locates issues early in a project. Hinting and annotations were requested at least twice! #1695 and #1912 but received not even a reply!
Docstrings out of date examples:
And here:
Other issues:
int
? Why?Very sad, because a lot of work has been done here obviously.
Anyway. I've started my own project instead of using moviepy. In a more pythonic way.
The text was updated successfully, but these errors were encountered: