marcomusy / vedo

A python module for scientific analysis of 3D data based on VTK and Numpy
https://vedo.embl.es
MIT License
2.04k stars 265 forks source link

Saving simulation video #210

Open maxvov opened 4 years ago

maxvov commented 4 years ago

Hi @marcomusy,

First of all, thanks for the great user-friendly software! However, I have an issue regarding video exporting.

I'm doing a little simulation and want to save a video (mp4/gif/whatever) to my computer. While the program is running, vp.show works as expected, but the final file (.mp4) is broken. Now I have the following code:

video = Video("my_video.mp4", duration=6, backend='ffmpeg')
vp = Plotter(axes=0, interactive=0, bg="w", size=(800, 600))
<...>
for t in pb.range():
    <the simulation itself>
    vp.show(offscreen=True)
    video.addFrame()
video.close()

In the examples given, I did not find a complete way to save the video from the simulation. Do I need to create a .ply/.x3d/.npz/.stl file first and then create a movie (using vp.load(...) -> video = Video(...) as in makeVideo.py) using it? Or is there a way to do this without an intermediate file? Should I set offscreen=True to the vp.show function, or it is not necessary? Do I also need to use exportWindow for video saving?

It would be great if you could provide a general way to save a video of the simulation running (for example, aspring.py). I think this will help many who are facing a similar problem. Or show me please where I can find information about this if I missed it :)

Thanks a lot!

marcomusy commented 4 years ago

Thanks for your feedback, btw what is your operative system? are you able to take individual screenshots? (eg. with vp.screenshot()) is makeVideo.py generating a video?

Do I need to create a .ply/.x3d/.npz/.stl file first and then create a movie

No!

Should I set offscreen=True to the vp.show function, or it is not necessary?

not necessary,

Do I also need to use exportWindow for video saving?

no, that actually saves a static 3D scene in various formats (npz, x3d)

It would be great if you could provide a general way to save a video of the simulation running (for example, aspring.py).

in principle makeVideo.py is already doing this kind of job.

Another possibility is for you to save single frames and then merge them with online tools like https://ezgif.com/

maxvov commented 4 years ago

Thanks for your answers!

what is your operative system? I am using Windows 10 and Python 3.7

are you able to take individual screenshots? (eg. with vp.screenshot()) Just checked, vp.screenshot() works fine.

is makeVideo.py generating a video? As far as I can understand, I need the "spider.ply" file to run 'makeVideo.py'. But I couldn't find it in your repository, so I can't run the program :) And I also don’t know what it should be and what it should contain in order to generate it by myself. That's why I asked for a complete video saving program example (no need to load third-party files).

And I just discovered a strange thing: if I convert my .mp4 video to .gif (using an online converter), everything works and I am able to open it. But I still cannot open the .mp4 file with any of my video viewers. Perhaps the problem is with saving the file. But video.close() is done.

marcomusy commented 4 years ago

As far as I can understand, I need the "spider.ply" file to run 'makeVideo.py'. But I couldn't find it in your repository, so I can't run the program :)

No datadir is a url link! file is downloaded on the fly (or it should be..) data is here anyway: https://vedo.embl.es/examples/data/

If you can't open the file on windows it's probably because of a missing video codec.

maxvov commented 4 years ago

My fault, sorry. Thanks for the advice!

Regarding the 'makeVideo.py' file: in its original form, it doesn't work:

 Video spider.mp4 is open...
Traceback (most recent call last):
  File ".\makeVideo_original.py", line 26, in <module>
    video.action(zoom=1.1)
  File "C:\ProgramData\Anaconda3\lib\site-packages\vedo\io.py", line 1642, in action
    vp.show(resetcam=False, interactive=False)
  File "C:\ProgramData\Anaconda3\lib\site-packages\vedo\plotter.py", line 1774, in show
    self.interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
AttributeError: 'NoneType' object has no attribute 'SetInteractorStyle'

If instead of video.action() I run vp.show() and video.addFrame() in the loop, I get the same thing:

 Video spider.mp4 is open...
Traceback (most recent call last):
  File ".\makeVideo_original.py", line 21, in <module>
    vp.show(elevation=1, azimuth=2)  # render the scene
  File "C:\ProgramData\Anaconda3\lib\site-packages\vedo\plotter.py", line 1774, in show
    self.interactor.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
AttributeError: 'NoneType' object has no attribute 'SetInteractorStyle'
(base) PS C:\Users\maxvov\!_GSP2020\Visualisation_GSP\makeVideo_py>

But if I set offscreen=False and video.action(), it starts to show me the video!

With offscreen=False and vp.show() &video.addFrame() in the loop it just shows me the image without any animation. I could rotate it with my mouse, but the video is not being saved: Video spider.mp4 is open... and that's all. After I close the window with the image I have vtkOutputWindow with 85 lines of code and ERROR: In C:\Dev\Soft\vtk\source\Rendering\OpenGL2\vtkShaderProgram.cxx, line 438 vtkShaderProgram (0000019E0430C0E0J: Could not create shader object. This window closes in a second. But if I manually set interactive=0 in vp = Plotter(), it works (animation and saving).

For the video.action() it works both with interactive=0 and interactive=1 with no difference.

By the way, .mp4 file is still broken for me (didn't find the way to fix the codecs issue, backend='ffmpeg', ffmpeg version 4.3.1, Windows 10). But with backend='opencv' it works fine.

Hope this small bug report will be helpful for you in some way.

I have many other issues with vedo (drag&drop on vedo.bat always gives ..could not load file(s),; often could not run vedo in Jupiter Notebook; ...) but I guess some of them are due to the fact that I might have installed something wrong :)

marcomusy commented 4 years ago

hi @maxvov thanks for reporting these issues! i'll have a look to fix them for the next release (~1 week).

antmatyjajo commented 3 years ago

Hi @maxvov

By the way, .mp4 file is still broken for me (didn't find the way to fix the codecs issue, backend='ffmpeg', ffmpeg version 4.3.1, Windows 10). But with backend='opencv' it works fine.

I don't know whether you managed to resolve this in the end (at least just the ffmpeg part). If not, I offer a possible solution; I had a lot of problems similar to this with ffmpeg and the solution was to change the colour format of the output.

You can do this by passing the option -pix_fmt yuv420p to ffmpeg before defining the output file. For example, to encode a sequence of png images to a compatible mp4 the command would look (roughly) something like this:

ffmpeg -y -r 25 -i %04d.png -c:v libx264 -pix_fmt yuv420p out.mp4

In (practical) vedo terms, you need to have a recent version of vedo installed. Then, you can (re)define the video.options field in order to pass this colour format parameter to ffmpeg. In the case of the makeVideo.py example that is included with vedo, the relevant lines would look like this:

video = Video("spider.mp4", duration=3, backend='ffmpeg') # backend='opencv'
video.options = "-b:v 8000k -c:v libx264 -pix_fmt yuv420p"

(Be aware that this is overwriting a property set by vedo, so maybe it will change in future...)

I hope that's of some help!

marcomusy commented 3 years ago

Thanks Antoni, this is quite a useful piece of information!