Save progress on backend app
This commit is contained in:
		
							parent
							
								
									eb4ac3e7c4
								
							
						
					
					
						commit
						dcca6ba556
					
				
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					.idea/
 | 
				
			||||||
							
								
								
									
										89
									
								
								application/camera-backend/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										89
									
								
								application/camera-backend/main.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,89 @@
 | 
				
			|||||||
 | 
					import io
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from fastapi import FastAPI, Response
 | 
				
			||||||
 | 
					import uvicorn
 | 
				
			||||||
 | 
					from picamera2 import Picamera2, Preview
 | 
				
			||||||
 | 
					from threading import Condition
 | 
				
			||||||
 | 
					import logging
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from picamera2.encoders import MJPEGEncoder, Quality
 | 
				
			||||||
 | 
					from picamera2.outputs import FileOutput
 | 
				
			||||||
 | 
					from starlette.background import BackgroundTask
 | 
				
			||||||
 | 
					from starlette.responses import StreamingResponse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app = FastAPI()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.get("/image")
 | 
				
			||||||
 | 
					def get_image():
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    Obtain a still image from the camera
 | 
				
			||||||
 | 
					    :return:
 | 
				
			||||||
 | 
					    """
 | 
				
			||||||
 | 
					    picam2 = Picamera2()
 | 
				
			||||||
 | 
					    capture_config = picam2.create_still_configuration(main={"size": (1920,1080)})
 | 
				
			||||||
 | 
					    picam2.configure(capture_config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    data = io.BytesIO()
 | 
				
			||||||
 | 
					    picam2.start()
 | 
				
			||||||
 | 
					    picam2.capture_image(data, format="jpeg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    picam2.stop()
 | 
				
			||||||
 | 
					    picam2.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return Response(content=data.getvalue(), media_type="image/jpeg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StreamingOutput(io.BufferedIOBase):
 | 
				
			||||||
 | 
					    def __init(self):
 | 
				
			||||||
 | 
					        self.frame = None
 | 
				
			||||||
 | 
					        self.condition = Condition()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def write(self, buffer):
 | 
				
			||||||
 | 
					        with self.condition:
 | 
				
			||||||
 | 
					            self.frame = buffer
 | 
				
			||||||
 | 
					            self.condition.notify_all()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def read(self):
 | 
				
			||||||
 | 
					        with self.condition:
 | 
				
			||||||
 | 
					            self.condition.wait()
 | 
				
			||||||
 | 
					            return self.frame
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def generate_frames(output):
 | 
				
			||||||
 | 
					    while True:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            frame = output.read()
 | 
				
			||||||
 | 
					            yield (b"--frame\r\n" b"Content-Type: image/jpeg\r\n\r\n" + frame + b"\r\n")
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            logging.error(f"Error in generate_frames: {str(e)}")
 | 
				
			||||||
 | 
					            break
 | 
				
			||||||
 | 
					    print("done")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.get("/mjpeg")
 | 
				
			||||||
 | 
					async def mjpeg():
 | 
				
			||||||
 | 
					    picam2 = Picamera2()
 | 
				
			||||||
 | 
					    capture_config = picam2.create_still_configuration(main={"size": (1920,1080)})
 | 
				
			||||||
 | 
					    picam2.configure(capture_config)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    output = StreamingOutput()
 | 
				
			||||||
 | 
					    picam2.start_recording(MJPEGEncoder(), FileOutput(output), Quality.VERY_HIGH)
 | 
				
			||||||
 | 
					    def stop():
 | 
				
			||||||
 | 
					        logging.info("Stopping recording")
 | 
				
			||||||
 | 
					        picam2.stop_recording()
 | 
				
			||||||
 | 
					        picam2.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return StreamingResponse(
 | 
				
			||||||
 | 
					        generate_frames(output),
 | 
				
			||||||
 | 
					        media_type="multipare/x-mixed-replace; boundry=frame",
 | 
				
			||||||
 | 
					        background=BackgroundTask(stop)
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    uvicorn.run(
 | 
				
			||||||
 | 
					        "main:app",
 | 
				
			||||||
 | 
					        host="0.0.0.0",
 | 
				
			||||||
 | 
					        port=8080
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == "__main__":
 | 
				
			||||||
 | 
					    main()
 | 
				
			||||||
							
								
								
									
										29
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								requirements.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					annotated-types==0.7.0
 | 
				
			||||||
 | 
					anyio==4.9.0
 | 
				
			||||||
 | 
					attrs==25.3.0
 | 
				
			||||||
 | 
					av==14.4.0
 | 
				
			||||||
 | 
					click==8.2.1
 | 
				
			||||||
 | 
					fastapi==0.115.14
 | 
				
			||||||
 | 
					h11==0.16.0
 | 
				
			||||||
 | 
					idna==3.10
 | 
				
			||||||
 | 
					jsonschema==4.24.0
 | 
				
			||||||
 | 
					jsonschema-specifications==2025.4.1
 | 
				
			||||||
 | 
					libarchive-c==5.3
 | 
				
			||||||
 | 
					numpy==2.3.1
 | 
				
			||||||
 | 
					picamera2==0.3.27
 | 
				
			||||||
 | 
					pidng==4.0.9
 | 
				
			||||||
 | 
					piexif==1.1.3
 | 
				
			||||||
 | 
					pillow==11.2.1
 | 
				
			||||||
 | 
					pydantic==2.11.7
 | 
				
			||||||
 | 
					pydantic_core==2.33.2
 | 
				
			||||||
 | 
					python-prctl==1.8.1
 | 
				
			||||||
 | 
					referencing==0.36.2
 | 
				
			||||||
 | 
					rpds-py==0.25.1
 | 
				
			||||||
 | 
					simplejpeg==1.8.2
 | 
				
			||||||
 | 
					sniffio==1.3.1
 | 
				
			||||||
 | 
					starlette==0.46.2
 | 
				
			||||||
 | 
					tqdm==4.67.1
 | 
				
			||||||
 | 
					typing-inspection==0.4.1
 | 
				
			||||||
 | 
					typing_extensions==4.14.0
 | 
				
			||||||
 | 
					uvicorn==0.35.0
 | 
				
			||||||
 | 
					v4l2-python3==0.3.5
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user