Here is a function for doing this on Linux (and maybe Mac). For my case this method uses a reasonable amount of memory, even for high-resolution, high-framecount animations. It's also significantly faster than using Export (6x in one test case). ### How it works - You make sure the `ffmpeg` executable is available on the path. - You supply `frameGraphicFun`, a frame generator function which accepts a single `time` argument and returns a `Graphics[]` object. - You supply `times`, which is a list of time values . - The function `EncodeMyVideo` launches `ffmpeg` as a subprocess. It then generates frames one at a time, by calling `frameGraphicFun` using the values in `times`. It rasterizes the frame `Graphics[]` and feeds it to `ffmpeg` using a fifo/named pipe (here's where this is *nix-dependent). - When all frames have been sent to `ffmpeg`, it closes the fifo and waits for `ffmpeg` to return. ... and the result is a video file. The code comes with some caveats: 1. Tested on linux only. It may work as-is on Mac. It almost certainly does not work on windows (though it probably could be made to). 2. The encoding parameters are a matter of personal preference. In particular, I choose to force periodic keyframes even though that results in a substantially larger file. The advantage is that the extra keyframes make seeking much smoother. Which I find useful when I manually "scrub" through portions of a mathematical animation (and I often do). My thanks to [1] for guidance. [1] https://stackoverflow.com/questions/51903888/is-it-possible-to-send-ffmpeg-images-by-using-pipe ### Implementation ```mathematica EncodeMyVideo[frameGraphicFun_, times_, outputFile_, rasterWidth_, fps_ : 24, keyframeInterval_ : 24, videoBitrate_ : "2500k", batchSize_ : Max[$ProcessorCount, Min[16, $ProcessorCount*4]]] := Block[{ fifoName = FileNameJoin[{$TemporaryDirectory, "fifo." <> CreateUUID[]}], rasterHeight = ImageAspectRatio[frameGraphicFun[times[[1]]]]*rasterWidth // N // Ceiling, templateCtx, templateBody, stdout, cmd, process, bst, i = 1, progressMessage, messageCell, result }, templateCtx = <| "width" -> ToString[rasterWidth], "height" -> ToString[rasterHeight], "fps" -> ToString[fps], "fifoName" -> fifoName, "keyframeInterval" -> keyframeInterval, "videoBitrate" -> videoBitrate |>; templateBody = "ffmpeg -hide_banner -nostats -loglevel 24 -y -f rawvideo -pix_fmt \ rgb24 -s `width`x`height` -r `fps` -i `fifoName` -c:v libx264 -b:v \ `videoBitrate` -x264-params keyint=`keyframeInterval` -an"; RunProcess[{"mkfifo", fifoName}]; WithCleanup[ cmd = (TemplateApply[templateBody, templateCtx] // StringSplit)~ Join~{outputFile}; process = StartProcess[cmd]; bst = OpenWrite[fifoName, BinaryFormat -> True]; progressMessage = "Encoding Frame " <> ToString[i] <> "/" <> ToString[Length[times]]; messageCell = PrintTemporary[Dynamic[progressMessage]]; Scan[( frames = ParallelMap[ Rasterize[frameGraphicFun[#], RasterSize -> {rasterWidth, rasterHeight}] &, #]; (*frames =Rasterize[frameGraphicFun[#], RasterSize\[Rule]{rasterWidth,rasterHeight}]&/@#;*) Scan[( progressMessage = "Encoding Frame " <> ToString[i++] <> "/" <> ToString[Length[times]]; BinaryWrite[bst, ImageData[#, "Byte"]]; ) &, frames]; ) &, Partition[times, UpTo[batchSize]]]; NotebookDelete[messageCell]; ProcessStatus[process]; , Close[bst], RunProcess[{"rm", fifoName}]]; progressMessage = "Waiting for ffmpeg to return... " <> ProcessStatus[process]; messageCell = PrintTemporary[Dynamic[progressMessage]]; While[ProcessStatus[process] == "Running", progressMessage = "Waiting for ffmpeg to return... " <> ProcessStatus[process]; Pause[0.25]]; NotebookDelete[messageCell]; result = ReadString[ProcessConnection[process, "StandardError"]]; If [result == EndOfFile, "Encoding Completed Successfully!", "Error:\n" <> result] ] ``` ### Usage ```mathematica generateFrameGraphic[t_] := Plot[Sin[x t], {x, 0, 2 \[Pi]}, PlotRange -> {-2, 2}]; Block[{fps = 24, duration = 5, tStart = 0, tEnd = 1, videoWidth = 640, times}, times = Range[tStart, tEnd, (tEnd - tStart)/(duration*fps)]; EncodeMyVideo[generateFrameGraphic, times, "sinAnimation.mp4", videoWidth, fps] ] ```