VideoIO.jl only seems to have the capabilities of reading in video with ffmpeg.
I couldn’t find any options to create a Video so I was wondering if I am missing something.
I know @sdanisch is exporting to png files first and then uses ffmpeg to create a video. That is not really an option for me since my image data is quite large.
ffmpeg certainly has the capability to produce videos, and I had intended on adding it to VideoIO.jl a long time ago, but it’s been challenging for me to make the time for that package recently. Pull requests are very welcome.
In the mean time, you might check to see if one of the OpenCV.jlimplementations implements video. I know that OpenCV supports it, but I don’t know if that functionality has been exposed in either package.
(I’m also not sure how easy it is to install either package, as neither is registered.)
Hi, I now use Images.jl or actually ImageMagick.jl for this task which works pretty well. You just have to convert the data first to an RGB Image and then simply call save. But I think this just works for animated gifs, which are in my case pretty suitable.
GR.jl can produce videos on the fly. You can find some examples in this talk (e.g. slides 10, 11). There’s also a backend for animated GIFs - but creating videos (with only 256 colors) is probably not what you want …
I looked around about a year ago, and the best I could do was to use matplotlib.animation.FuncAnimation via PyCall. I wouldn’t recommend it, but I can post my code if the other options don’t work for you.
Thank you all for the suggestions I solved my particular problem the following way
open(`ffmpeg -f rawvideo -pix_fmt gray -s:v 5120x5120 -r 70 -i pipe:0 test.mkv`, "w") do out
for frame in video
img = convert(Image{Gray{U8}}, frame)
write(out, reinterpret(UInt8, data(img)))
end
end
It is not terrible performant but it get’s the job done for now.
This is great! I updated and generalized it a bit:
using Images
function writevideo(imgstack, filename; overwrite=true, framerate=30)
# Input validation
length(size(imgstack)) == 3 || error("input image must have three dimensions")
if !(eltype(imgstack) <: Color)
error("element type of input array is $(eltype(imgstack));
needs to be RGB or Gray")
end
# Translate inputs to command line args
ow = overwrite ? "-y" : ""
w, h, nframes = size(imgstack)
if eltype(imgstack) <: RGB
open(`ffmpeg $ow -f rawvideo -pix_fmt rgb24 -s:v $(w)x$(h)
-r $framerate -i pipe:0 -vf "transpose=0" $filename`, "w") do out
for i = 1:nframes
write(out, convert.(RGB24, imgstack[:,:,i]))
end
end
else
open(`ffmpeg $ow -f rawvideo -pix_fmt gray -s:v $(w)x$(h)
-r $framerate -i pipe:0 -vf "transpose=0" $filename`, "w") do out
for i = 1:nframes
write(out, convert.(Gray{N0f8}, imgstack[:,:,i]))
end
end
end
end
Have you tried VideoIO.jl? If that works for your use case, it’ll be more robust & user-friendly to add that as a lazy-loaded dependency than requiring people to install FFMPEG themselves.