Timelapse video through execonmcode!



  • I'm pleased to give back to the community with the following script to add timelapse video when using a Duet3 and Raspberry Pi. I am unsure if this will work with a Duet2, but maybe..? if execonmcode works, then yes it will..

    example video:
    https://vimeo.com/468721949

    This one does take some setup, but the payoff is well worth it. Note that this expects the files to be in the following folders as the default:

    • timelapse.sh should be in a folder named /scripts located off of the root directory
    • a folder named pix must be located in the /scripts folder
    • a seed file named timelapse_counter, containing only a -1 must be located in the /scripts folder
    • a folder located in the root directory named /timelapse for the output video

    Also note that both mjpg_streamer and ffmpeg must be installed on your RPi.

    First, here is the service code. I chose M5575.

    [Unit]
    Description=Duet API listener for Timelapse Video by oozeBot
    After=duetcontrolserver.service
    Requires=duetcontrolserver.service
    
    [Service]
    ExecStart=/usr/local/bin/execonmcode -mCode 5575 -command "./scripts/timelapse.sh %%A %%F"
    Restart=always
    RestartSec=10
    
    [Install]
    WantedBy=multi-user.target
    

    Here is v1.0 of the bash script:

    #!/bin/bash
    # Timelapse Video by oozeBot (www.oozeBot.com) v1.0 - released 10/15/2020
    # Usage: ./timelapse.sh Action FPS
    # Example: ./timelapse.sh "Enable/Disable/Make/Remove" "1-30"
    # gCode: M5575 A"Enable"     ;Enables timelapse and cleans up the image folder
    # gCode: M5575 A"Capture"    ;if enabled, captures a snapshot from the video feed
    # gCode: M5575 A"Disable"    ;Disables timelapse
    # gCode: M5575 A"Make" F"12" ;Creates a video of the snapshots @ 12fps
    # gCode: M5575 A"Remove"     ;Removes all images in the image folder
    
    Action=`echo $1 | tr [a-z] [A-Z] | cut -c1-1`
    
    CounterFile="/scripts/timelapse_counter"
    ImageNum=`cat $CounterFile`
    
    if [ "$Action" = "E" ];then
     #Enables timelapse by setting the counter to 0 and removes all images in the image folder
     ImageNum=0
     rm -rf /scripts/pix/*
     echo $ImageNum > $CounterFile
    elif [ "$Action" = "D" ] && [ $ImageNum -gt 0 ];then
     #If enabled, disables timelapse by setting the counter to -1
     ImageNum=-1
     echo $ImageNum > $CounterFile
    elif [ "$Action" = "M" ] && [ $ImageNum -lt 0 ];then
     #Creates timelapse video at the specified FPS, else defaults to 24
     #This will return an error if no images exist and only works when disabled
     fps=$2
     if ! [[ $2 =~ ^[0-9]+$ ]];then
      fps="24"
     fi
     ffmpeg -framerate $fps -start_number 1 -i "/scripts/pix/%d.jpg" -s:v 1920x1080 -vcodec libx264 -qp 0 -preset veryslow /timelapse/$(date +"%Y_%m_%d_%I_%M_%S_%p").mp4
    elif [ "$Action" = "R" ] && [ $ImageNum -lt 0 ];then
     #If disabled, removes all images within the image folder (optional as all images will be removed after restart)
     rm -rf /scripts/pix/*
    elif [ "$Action" = "C" ] && [ $ImageNum -ge 0 ];then
     #Increments counter and captures snapshot
     ImageNum=$((ImageNum+1))
     wget http://localhost:8080/?action=snapshot -O '/scripts/pix/'$ImageNum'.jpg'
     echo $ImageNum > $CounterFile
    fi
    

    Note all M5575 commands should be preceded by an M400 if you want the extruder to stand still

    I put examples in the script of all usage through gCode. For the example video above, in the starting script of my slicer, I've added M5575 A"Enable" to enable timelapse. In my layer change script, I've added M5575 A"Capture". And finally, in the ending script, I've added M5575 A"Disable" to disable.

    Why did I do it this way? Because I wanted to process the video outside of the control of the job's gCode - however, you could include the following in the bottom of your ending script to both make the video and clean up the photos: M5575 A"Make" F"12" (whatever FPS you want) followed by M5575 A"Remove". Just be prepared to wait before the job actually completes as it holds in process until the video is done.

    I also did it this way so I could adjust the framerate by just running the command with various FPS from DWC..

    This was also designed to be added to your daemon.g file using M5575 A"Capture" followed by a G40 S10 (or whatever second delay you want) to make a different type of timelapse. It will only save photos while the timelapse has been enabled using M5575 A"Enable".. so it's safe to just leave in there if you so choose. However, it currently supports layer change or X seconds - not both at the same time. If there was demand, I could add that..

    And if there are an ffmpeg experts out there, please feel free to correct my usage of it. What I've used might be overkill or not perfect, but it's working well..



  • We have a better camera coming early next week.. can't wait for it to get here. This is going to be invaluable in showing the world the motion system of our new line of printers!



  • This is so cool!!

    However, for some reason the video doesn't work for me. Maybe encoding?



  • @whopping-pochard - here is an external link to it:

    https://vimeo.com/468721949

    Mods- if you see this, will you please update my original post with this video link instead?


  • Moderator

    The mp4 file worked for me in chrome. 🤷



  • Sounds like something that has to be tested with Duet2 when 3.2 is released.

    (.mp4 fine here as well, but it does require the browser to understand what to do with content-type: video/mp4 as there is no embedded player or download prompt)


  • Moderator

    @oozeBot said in Timelapse video through execonmcode!:

    Mods- if you see this, will you please update my original post with this video link instead?

    Done.

    Ian


  • administrators

    very cool, it would be great if someone could write the configuration elements into a DWC plugin and then it could be made into a front and back end plugin.



  • Here is a 300mm z-wobble test I just completed in vase mode. It was printed in ABS with a .6mm nozzle at .5mm layer height x .75mm extrusion width at a sustained 80mm/s in just over 3 hours..

    Note the bad spots in the rear as it prints (and the recovery!). Since this was in vase mode, I didn't use M400 between layers. It was caused by the momentary stutter when the photos were triggered..

    https://vimeo.com/469090014


  • Moderator

    @oozeBot said in Timelapse video through execonmcode!:

    Note all M5575 commands should be followed by an M400!!

    I'll include an option to flush the channel the custom code was received on before executing the command in my next version of execonmcode. That should remove the above requirement.

    EDIT: interesting. I checked the code and it does already flush the channel. In that case I have to ask @oozeBot for the reason of the above recommendation. 🤔



  • @wilriker maybe I'm wrong - still learning the kinks. Though I can now say execonmcode holds "in process" until complete, so maybe an M400 afterwards isn't necessary.. but it is necessary before if you want the extruder to park completely stationary like I did in the first video. I'll request that modified in the original post after I do some more testing.

    Take a look at that latest video I just posted.. you'll see the bad spots in the rear of the print due to calling the timelapse without any M400s in vase mode.. I don't know if it's possible, but it would be great if it was also possible to call execonmode out of process where it doesn't wait on the result. Is that doable? There is likely use cases for both ways..


  • Moderator

    @oozeBot said in Timelapse video through execonmcode!:

    I'll request that modified in the original post after I do some more testing.

    You should be able to edit your own posts. It's in the menu of that post.

    I don't know if it's possible, but it would be great if it was also possible to call execonmode out of process where it doesn't wait on the result. Is that doable? There is likely use cases for both ways..

    Will add that. Not hard to do. 👍



  • @wilriker That's great! I'll be eager to test that when you have time to work on it..



  • @wilriker I was wrong about needing a following M400 (as it's "in process" - duh!). I changed it in my original post. Thanks for letting me know I can edit earlier posts - not sure how I missed that!


  • Moderator

    @oozeBot said in Timelapse video through execonmcode!:

    @wilriker That's great! I'll be eager to test that when you have time to work on it..

    I've put a build into my Dropbox. You can add a command-line parameter --no-flush and it will not flush the code queue prior executing the command. Note that since this is subscribing to the PRE subscription mode it will execute your command as soon as it is read from disk which might be a while (this heavily depends on the execution time of the commands ahead - long slow moves obviously take up more time than short quick moves) before it is actually executed.


Log in to reply