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..
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..