Hello,
I would like to use the capture extension through a service call. My code works just fine from the script editor, but when calling it through a service I get an error “divide by zero exception”. I think the problem is that the capturing has to be started from the main thread… but how to post that call to the main thread?
Here is the code for capturing and sending the result to my application…
data = dict()
import os
import urllib.request
import ssl
import shutil
import time
import threadingcaptureInstance = omni.kit.capture.viewport.CaptureExtension.get_instance()
help(captureInstance.options)
requestId = data.get(“requestId”, “00000000-0000-0000-0000-000000000000”)
#acceptCapturingResultUri = data.get(“acceptRenderedImageUri”, “https://localhost:11000/api/session/00000000-0000-0000-0000-000000000000/AcceptCapturingResult”)
acceptCapturingResultUri = data.get(“acceptRenderedImageUri”, “https://localhost:60001/api/session/00000000-0000-0000-0000-000000000000/AcceptCapturingResult”)
cameraPath = data.get(“cameraPath”, “/Stage/Cameras/Rendering”)captureInstance.options.output_folder = ‘D:\Temp\Renderings’
captureInstance.options.file_name = requestId
#captureInstance.options.file_type = ‘.mp4’
captureInstance.options.file_type = data.get(“fileType”, “.png”)
captureInstance.options.camera = cameraPath
captureInstance.options.start_frame = data.get(“timeLinePositionStart”, 1)
captureInstance.options.end_frame = data.get(“timeLinePositionEnd”, 100)
captureInstance.options.start_time = data.get(“timeLinePositionStart”, 1)
captureInstance.options.end_time = data.get(“timeLinePositionEnd”, 100)
captureInstance.options.res_width = data.get(“rendererResolutionWidth”, 1920)
captureInstance.options.res_height = data.get(“rendererResolutionHeight”, 1080)
captureInstance.options.fps = data.get(“framesPerSecond”, 24)
captureInstance.options.spp_per_interation = data.get(“sppPerIteration”, 1)
captureInstance.options.path_trace_spp = data.get(“pathTraceSpp”, 1)
captureInstance.options.ptmb_subframes_per_frame = data.get(“ptmbSubSurfacesPerFrame”, 1)
captureInstance.options.ptmb_fso = data.get(“ptmFso”, 0.0)
captureInstance.options.ptmb_fsc = data.get(“ptmFsc”, 1.0)
captureInstance.options.save_alpha = data.get(“saveAlpha”, False)
captureInstance.options.preroll_frames = data.get(“preRollFrames”, 0)
captureInstance.options.range_type = getattr(omni.kit.capture.viewport.CaptureRangeType, data.get(“rangeType”, “FRAMES”))
captureInstance.options.renderer_preset = getattr(omni.kit.capture.viewport.CaptureRenderPreset, data.get(“rendererPreset”, “PATH_TRACE”))
captureInstance.options.movie_type = getattr(omni.kit.capture.viewport.CaptureMovieType, data.get(“movieCaptureType”, “SEQUENCE”))localFile = “”
if captureInstance.options.file_type == “.mp4”:
localFile = os.path.join(captureInstance.options.output_folder, f"{captureInstance.options.file_name}{captureInstance.options.file_type}“)
else:
localFile = os.path.join(captureInstance.options.output_folder, f”{captureInstance.options.file_name}1{captureInstance.options.file_type}")localFolder = os.path.join(captureInstance.options.output_folder, f"{captureInstance.options.file_name}_frames")
def onDone():
try:
if os.path.exists(localFile) == False:
time.sleep(1)req = urllib.request.Request(acceptCapturingResultUri, method="POST") req.add_header('RequestId', requestId) req.add_header('Content-Length', os.stat(localFile).st_size) req.add_header('CameraPath', cameraPath) gcontext = ssl.SSLContext() with open(localFile, 'rb') as f: urllib.request.urlopen(req, f, context=gcontext)
except:
print(f"[Diomex Framework Kitagent]: {str(sys.exc_info()[0])}")
finally:
if os.path.exists(localFolder):
shutil.rmtree(localFolder)if os.path.exists(localFile): os.remove(localFile)
captureInstance.capture_finished_fn = onDone
captureInstance.start()
As mentioned this works fine in the script editor… can anyone tell me how to get this running in a service?
This is the code from my service method:
@router.post(“/capture”, description=“Captures videos and images from a session”, summary=“Renders the current session from a specified camera”)
async def post_capture(data: dict = fastapi.Body(None)):
try:
captureInstance = omni.kit.capture.viewport.CaptureExtension.get_instance()requestId = data.get("requestId", "00000000-0000-0000-0000-000000000000") acceptCapturingResultUri = data.get("acceptRenderedImageUri", "https://localhost:11000/api/session/00000000-0000-0000-0000-000000000000/AcceptCapturingResult") cameraPath = data.get("cameraPath", "/Stage/Cameras/Rendering") captureInstance.options.output_folder = 'D:\\Temp\\Renderings' captureInstance.options.file_name = requestId captureInstance.options.file_type = data.get("fileType", ".png") captureInstance.options.camera = cameraPath captureInstance.options.start_frame = data.get("timeLinePositionStart", 1) captureInstance.options.end_frame = data.get("timeLinePositionEnd", 100) captureInstance.options.start_time = data.get("timeLinePositionStart", 1) captureInstance.options.end_time = data.get("timeLinePositionEnd", 100) captureInstance.options.res_width = data.get("rendererResolutionWidth", 1920) captureInstance.options.res_height = data.get("rendererResolutionHeight", 1080) captureInstance.options.fps = data.get("framesPerSecond", 24) captureInstance.options.spp_per_interation = data.get("sppPerIteration", 1) captureInstance.options.path_trace_spp = data.get("pathTraceSpp", 1) captureInstance.options.ptmb_subframes_per_frame = data.get("ptmbSubSurfacesPerFrame", 1) captureInstance.options.ptmb_fso = data.get("ptmFso", 0.0) captureInstance.options.ptmb_fsc = data.get("ptmFsc", 1.0) captureInstance.options.save_alpha = data.get("saveAlpha", False) captureInstance.options.preroll_frames = data.get("preRollFrames", 0) captureInstance.options.range_type = getattr(omni.kit.capture.viewport.CaptureRangeType, data.get("rangeType", "FRAMES")) captureInstance.options.renderer_preset = getattr(omni.kit.capture.viewport.CaptureRenderPreset, data.get("rendererPreset", "PATH_TRACE")) captureInstance.options.movie_type = getattr(omni.kit.capture.viewport.CaptureMovieType, data.get("movieCaptureType", "SEQUENCE")) writeLogMessage("Capturing parameters set") localFile = "" if captureInstance.options.file_type == ".mp4": localFile = os.path.join(captureInstance.options.output_folder, f"{captureInstance.options.file_name}{captureInstance.options.file_type}") else: localFile = os.path.join(captureInstance.options.output_folder, f"{captureInstance.options.file_name}1{captureInstance.options.file_type}") localFolder = os.path.join(captureInstance.options.output_folder, f"{captureInstance.options.file_name}_frames") def onDone(): try: if os.path.exists(localFile) == False: time.sleep(1) req = urllib.request.Request(acceptCapturingResultUri, method="POST") req.add_header('RequestId', requestId) req.add_header('Content-Length', os.stat(localFile).st_size) req.add_header('CameraPath', cameraPath) gcontext = ssl.SSLContext() with open(localFile, 'rb') as f: urllib.request.urlopen(req, f, context=gcontext) except: print(f"[Diomex Framework Kitagent]: {str(sys.exc_info()[0])}") finally: if os.path.exists(localFolder): shutil.rmtree(localFolder) if os.path.exists(localFile): os.remove(localFile) captureInstance.capture_finished_fn = onDone captureInstance.start() writeLogMessage("Capturing started") return {"status": status}
except Exception as e:
return {“status”: “error”,
“message”: str(e)}
@mati-nvidia can you help?