24
$\begingroup$

I'm putting together a video from the VSE. In the sequencer window it is rendering and scrubbing at near realtime yet during output it is taking around 3x longer.

The frames are taking 0.13 seconds each whilst the CPU is only utilised around 20%. I am rendering onto an SSD and using H.264 format 1280x720. Tile size options etc appear to have no or very little effect.

In short - is there any method to speed up the rendering of frames from the VSE?

$\endgroup$
  • $\begingroup$ the blender VSE is not multi-threaded like rending in cycles might be $\endgroup$ – Vader Mar 13 '14 at 15:17
  • 5
    $\begingroup$ @Vadar, this isnt right, the sequencer has the ability to do threaded per-fetching. $\endgroup$ – ideasman42 Mar 13 '14 at 23:08
  • $\begingroup$ @ideasman42 I just tired you answer. I am not getting a huge speed up. I am still wrong though and you are still right. But it is not %100 $\endgroup$ – Vader Mar 13 '14 at 23:57
  • 1
    $\begingroup$ You may be seeing an FFmpeg limitation, which is what blender uses to compress the video stream. v0.7.x normally only uses one thread. While v2.x uses more than one thread, I'm not sure that blender enables multi threading with ffmpeg, or that it fully supports ffmpeg 2.x yet. $\endgroup$ – sambler Mar 14 '14 at 7:42
  • $\begingroup$ There are some suggestions in this answer: how-to-speed-up-blender-video-sequence-editor-rendering $\endgroup$ – FvD May 14 '15 at 18:49
15
$\begingroup$

tl;dr: Open source program for automated solution is at the bottom of the post. Latest release as well as usage instruction can be found at the GitHub project page:


Problem

I was looking for a free (and maybe even open-source) video editor, and after using it for a while I found out that Blender is very capable of this task, but I was facing the same problem with the unused resources during exporting the finished file. I was searching everywhere, but I couldn't find anything about speeding up the Video Sequence Editor (VSE) rendering that would work for me.

Solution

After thinking for a while and trying out things I realized that I can run multiple renders at once from the command line, and it seems like the performance scales pretty much linearly with the number of instances running. Of course until you reach the limit of your processor or the amount of RAM you have. (I was running at 87% CPU and 89% of the memory filled, and I wouldn't recommend going higher, because if one of the rendering processes fail to allocate more memory it will crash and you have to do that part over again.)

Running a render in this configuration.

After you have the parts/chunks of rendered video, you can put it together using the concatenation functionality of ffmpeg. I tried it with mp4 [H.264] and avi [Xvid], so I can confirm that those are working, but there might be other formats that can be used, but I haven't experimented with those yet.

Code parts

I don't have time to do a full tutorial now, but if anybody will show interest I might get around to putting together something.

For this to work you need to have the blender and ffmpeg executables in your PATH environmental variable, and the project file needs to be in the current working directory of the command window. The code parts I finally ended up writing and using were these:

blender -b "name_of_project.blend" -E BLENDER_RENDER -s 0 -e 1000 -a

to render one chunk of video. (You can try changing BLENDER_RENDER to CYCLES if that works better for you, and you have to replace the 0 and 1000 with the actual frame range you want to render. I had quite good results with doing it in chunks of 1000 frames and having around 4-6 processes running at once.)

You have to have multiple CMD windows open at once (unless you write a program to automate it), and you need to call them with different frame ranges.
(I would suggest 0 - 1000; 1001 - 2000; 2001 - 3000; ...)
[The frame range is inclusive, so pay attention not to write the ending number as the beginning number for the next process.]

You have to set the output properties in the Blender rendering setting while the project is open, but you can close the window afterwards. I think you can also set memory limit for the individual processes in Blender at File -> User Preferences -> System -> Memory Cache Limit, but I am not entirely sure about what that does.

For generating the list with the filenames I used PowerShell:

dir -n *.mp4 | %{"file '" + $_ + "'"} | Set-Content parts.txt

And for joining them I called ffmpeg (also from PowerShell, but this should work from CMD too.)

ffmpeg -f concat -i parts.txt -c copy ../output.mp4

This seems to be almost instantaneous, so you don't even really need to count this into your rendering time. It puts the resulting video in the parent directory so it doesn't get mixed into the video parts.
(If you used avi, you only need to change the extension of the output file and this should work.)

I hope that I could help somebody!

Sources

My main sources for the Blender command line options were these sites:
https://www.blender.org/manual/render/workflows/command_line.html
https://www.blender.org/manual/advanced/command_line.html
http://wiki.blender.org/index.php/Doc:2.4/Reference/Command_Line

And for the joining of the files using ffmpeg:
https://trac.ffmpeg.org/wiki/Concatenate
https://superuser.com/questions/607383/concat-two-mp4-files-with-ffmpeg-without-losing-quality/607384
https://stackoverflow.com/questions/15186500/howto-merge-two-avi-files-using-ffmpeg


Edit 2:
Version v0.4 has been released with the contributions of RedRaptor93.

Edit:

Program

I wrote a very basic application for the purpose of automating this process, that GitHub user MeTwentyFive very generously took upon and updated, so now it's more convenient and less buggy.

I have the code of that publicly accessible here:
https://github.com/Isti115/BlenderRenderController

I also included an executable in the release of the package, but for that to work you need to have the main blender.exe file accessible from the PATH environmental variable for rendering, and the same thing holds true with ffmpeg.exe for concatenating the parts.

If you need any help modifying, compiling or using it then feel free to message me!

ps.: You can get ffmpeg from here: https://ffmpeg.org/download.html
And I assume that you already have blender, since you are here asking questions about it. ;)


Edit 3:
Mikeycal Meyers wrote his own python script as a cross-platform solution for the problem.
You can find his explanation about it here:
https://youtu.be/rgwP5L1bICk
and the actual project here:
https://github.com/mikeycal/the-video-editors-render-script-for-blender
Make sure to check his work out as well, and help him improve it if you know some python! ;)

$\endgroup$
  • $\begingroup$ I have started writing a small C# application to automate this process, so if somebody is interested, I can make a simple user guide for it and post it here. :) $\endgroup$ – Isti115 Jan 18 '16 at 22:28
  • $\begingroup$ amazing, thank you for your application now convert my videos in half the time $\endgroup$ – Moliveira May 18 '16 at 18:15
  • $\begingroup$ I am really glad that I have helped you! Thank you very much for letting me know! :) It makes me feel that it was worth posting it here! $\endgroup$ – Isti115 May 18 '16 at 20:19
  • $\begingroup$ This is the best answer I've seen to date when researching how to encode long videos faster. I did this with avi / h.264 / aac and checked the split points after the ffmpeg copy: seamless. 1) I wonder if it is better to split at gop boundaries? 2) Since I mix animations, overlays, blending throughout my files, I also wonder if it is better to keep to the 1000 frame 'chunks' or something like that so one CPU isn't left running for too long over a complex scene while the other tasks finish. $\endgroup$ – jtmcdole Jul 16 '16 at 20:06
  • 1
    $\begingroup$ @JanKadeřábek I'm glad you figured it out! :) About the mixdown: for it to work you need the "Scripts" folder that you can get from the repository. Put it next to the exe file, and it should work, but I found that it wasn't very intuitive (also, I looked at the code and realized that it doesn't work under every circumstance), so I'm currently working on a newer release that will include that and other modifications from a new pull request by RedRaptor93. ps.: Don't forget to upvote if it works for you! ;) $\endgroup$ – Isti115 Feb 18 '17 at 2:12
4
$\begingroup$

One common reason for the sequencer to slow down is editing video at a different resolution, for fast editing make sure the input and output sizes are the same. (even one pixel difference will make a significant slowdown)

Update, Prefetch option has been removed:

Another way to speed up things is by enabling pre-fetch frames: *

User Prefs -> System -> Sequencer/Clip Editor

This will use multiple threads to evaluate frames in advance.

If you have enough memory you could also increase the cache limit, which is accessed from the same place.


Warning: There is a bug with pre-fetch which is why its disabled by default, any animated sequence strip values (animated opacity for example), won't be correctly taken into account when pre-fetching, however this may not be important in many cases, and crossfades avoid this issue. Just worth noting.

The pre-fetch option was added before Blender's animation system re-write, and the 2 don't work correctly together.

$\endgroup$
  • $\begingroup$ More interested to speed up the file output (ie saving the video frames). Sequencer editor window is already running at near full speed. $\endgroup$ – Rhys Mar 14 '14 at 2:11
  • $\begingroup$ @Rhys these speedups apply to rendering too. $\endgroup$ – ideasman42 Mar 17 '14 at 6:13
  • 1
    $\begingroup$ May the prefetch not be at this position any more in current Blender releases? You have a Pre-Fetch option per strip now!?! $\endgroup$ – Samoth Jan 3 '16 at 17:27
  • 2
    $\begingroup$ Prefetch option is now removed, edited answer. $\endgroup$ – ideasman42 Jan 4 '16 at 10:01
4
$\begingroup$

I have been having the same problem and I found that changing

User Prefs -> System -> Images Draw Method

to "GLSL" or "DrawPixels" from "2D Texture" about doubled my VSE render speed.

$\endgroup$
4
$\begingroup$

You can use Pulverize to do multi-process rendering from Blender's Video Sequence Editor:

https://github.com/sciactive/pulverize

This will divide the rendering time of your project by the number of CPU cores you have.

(This is like Isti115's program, but it runs on Linux.)

$\endgroup$
  • $\begingroup$ Nice to see that this approach is made available on other platforms too! :) $\endgroup$ – Isti115 Feb 26 '17 at 10:52
0
$\begingroup$

For what it is worth I wrote a small addon paraller_render.py (can be found at https://github.com/elmopl/ktba/) that lets you easily select how many instances of Blender in parallel it should launch and into how many parts to split your video.

To install simply download file from addons/parallel_rende.py and put it in your Blender's scripts/addons directory. You should be able to enable it in File -> User Perfernces... -> Addons and search for VSE Parallel Render.

Once enabled you should be able to just press space in sequencer (or anywhere else really) and search for "Parallel Render" action.

enter image description here

Note: As it launches other instances of Blender and tells them to load the same file it will use last saved version of your file. So if you want your most recent changes to be reflected in those renders just save your file before launching it.

enter image description here

$\endgroup$
0
$\begingroup$

Here is a single very scary command line which does incremental, parallel, resumable renders on Linux --- and it ought to work on Windows to if you have Cygwin.

seq 3041 75966 | parallel --joblog joblog -X -n 20 --eta --bar 'blender -b video.blend -E BLENDER_RENDER --render-frame `echo {} | tr " " ","`'

Replace the two numbers after seq with your start and end frames. Replace video.blend with your Blender file. Then run, and... hope...

It'll show you a pretty clunky progress bar on the command line which looks like this:

5% 184:3463=739s 6861 6862 6863 6864 6865 6866 6867 6868 6869 6870 6871 6872

The 5% tells you where it's got to, the 184:3463 tells you which batch it's reached and how many are left to go (note that frames are processed in batches controlled by the -n argument, and are not the same as frame numbers, increasing -n will make for slightly more efficient renders), the =739s is an estimate of how long there is to go, and be warned that it lies foully, and the rest of the numbers indicate frames it's currently rendering.

If you ^C it in the middle, or it dies with lack of disk space or something, you should be able to resume by adding --resume after the parallel, and it should automatically pick up from where it left off.

Remember to configure for rendering to frames, etc, in the normal way.

$\endgroup$

protected by David Oct 28 '16 at 12:45

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.