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/468721949This 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:
Mods- if you see this, will you please update my original post with this video link instead?
-
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)
-
@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
-
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..
-
@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..
-
@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!
-
@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 thePRE
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. -
@oozeBot said in 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/468721949This 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..
Good morning, this is the feature I'm looking! I'm not a Raspberry/Linux expert so, if possible, I would like to make some questions:
1)Actually on my Raspy I've installed MotionEye wich gives me the capability of having an URL for still images, could I keep on using it?
2) what is a service code and where has it to be stored? In the Duet SD?
3) Is the bash script you pasted the script called timelapse.sh?Thanks!
-
@the_dragonlord
more info on "Exec on mCode" can be found here:
https://forum.duet3d.com/topic/13194/dsf-extension-exec-on-mcode-was-shutdown-sbc
Once installed, it will allow custom mCodes to be run which execute scripts on the RPi.
My script was written entirely around M-JPEG streamer. I use it for both streaming video to DWC and capturing snapshots for the timelapse in the script.. so MotionEye won't work without rewriting the script.
And yes, sorry - the bash script is named timelapse.sh and is what is referenced in the service code.
-
@oozeBot said in Timelapse video through execonmcode!:
@the_dragonlord
more info on "Exec on mCode" can be found here:
https://forum.duet3d.com/topic/13194/dsf-extension-exec-on-mcode-was-shutdown-sbc
Once installed, it will allow custom mCodes to be run which execute scripts on the RPi.
My script was written entirely around M-JPEG streamer. I use it for both streaming video to DWC and capturing snapshots for the timelapse in the script.. so MotionEye won't work without rewriting the script.
And yes, sorry - the bash script is named timelapse.sh and is what is referenced in the service code.
excellent, thanks!
-
@oozeBot said in Timelapse video through execonmcode!:
@the_dragonlord
more info on "Exec on mCode" can be found here:
https://forum.duet3d.com/topic/13194/dsf-extension-exec-on-mcode-was-shutdown-sbc
Once installed, it will allow custom mCodes to be run which execute scripts on the RPi.
My script was written entirely around M-JPEG streamer. I use it for both streaming video to DWC and capturing snapshots for the timelapse in the script.. so MotionEye won't work without rewriting the script.
And yes, sorry - the bash script is named timelapse.sh and is what is referenced in the service code.
so what I have to do now is install a clean image of Raspberry OS, configure it, install mjpeg on it and then configure rff? I have read the content of the link you sent me but I still don't understand what is the service code and where it is stored...
-
@the_dragonlord I don't know that you need to start from a clean install, but it might be useful to try this on a second SD card and keep your working version intact. Once you get execonmcode installed and understand how to add services, etc, this will all make better sense. Post a reply to wilriker in the other thread for installation questions, etc..