Add webcam functionality to the agent's API and web interface. Implement endpoints for listing available webcams and capturing frames, along with corresponding UI elements for device selection and frame display. Update OpenAPI specification to include new webcam features, enhancing user interaction with webcam devices.
This commit is contained in:
@@ -24,6 +24,7 @@ import (
|
||||
"tea.chunkbyte.com/kato/go-worm/lib/openapi"
|
||||
"tea.chunkbyte.com/kato/go-worm/lib/screenshot"
|
||||
"tea.chunkbyte.com/kato/go-worm/lib/startup"
|
||||
"tea.chunkbyte.com/kato/go-worm/lib/webcam"
|
||||
)
|
||||
|
||||
func (a *Agent) handleHealth(w http.ResponseWriter, r *http.Request) {
|
||||
@@ -290,6 +291,71 @@ func (a *Agent) handleScreenshot(w http.ResponseWriter, r *http.Request) {
|
||||
_, _ = w.Write(frame.Data)
|
||||
}
|
||||
|
||||
func (a *Agent) handleWebcam(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
helpers.WriteError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
devices, err := webcam.List()
|
||||
if err != nil {
|
||||
helpers.Log.Printf("webcam list: %v", err)
|
||||
helpers.WriteError(w, http.StatusServiceUnavailable, "webcam list failed")
|
||||
return
|
||||
}
|
||||
if devices == nil {
|
||||
devices = []webcam.Device{}
|
||||
}
|
||||
helpers.WriteJSON(w, http.StatusOK, map[string]any{"devices": devices})
|
||||
}
|
||||
|
||||
func (a *Agent) handleWebcamFrame(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
helpers.WriteError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
return
|
||||
}
|
||||
format := strings.ToLower(strings.TrimSpace(r.URL.Query().Get("format")))
|
||||
if format == "" {
|
||||
format = "jpeg"
|
||||
}
|
||||
if format != "png" && format != "jpeg" {
|
||||
helpers.WriteError(w, http.StatusBadRequest, "format must be png or jpeg")
|
||||
return
|
||||
}
|
||||
quality := 80
|
||||
if raw := r.URL.Query().Get("quality"); raw != "" {
|
||||
var err error
|
||||
quality, err = strconv.Atoi(raw)
|
||||
if err != nil || quality < 1 || quality > config.MaxImageQuality {
|
||||
helpers.WriteError(w, http.StatusBadRequest, "quality must be between 1 and 100")
|
||||
return
|
||||
}
|
||||
}
|
||||
device := 0
|
||||
if raw := r.URL.Query().Get("device"); raw != "" {
|
||||
var err error
|
||||
device, err = strconv.Atoi(raw)
|
||||
if err != nil || device < 0 {
|
||||
helpers.WriteError(w, http.StatusBadRequest, "device must be 0 or greater")
|
||||
return
|
||||
}
|
||||
}
|
||||
frame, err := webcam.Capture(device, format, quality)
|
||||
if err != nil {
|
||||
if errors.Is(err, webcam.ErrDeviceNotFound) {
|
||||
helpers.WriteError(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
helpers.Log.Printf("webcam capture: %v", err)
|
||||
helpers.WriteError(w, http.StatusServiceUnavailable, "webcam capture failed")
|
||||
return
|
||||
}
|
||||
w.Header().Set("Content-Type", frame.ContentType)
|
||||
w.Header().Set("Content-Length", strconv.Itoa(len(frame.Data)))
|
||||
w.Header().Set("X-Webcam-Width", strconv.Itoa(frame.Width))
|
||||
w.Header().Set("X-Webcam-Height", strconv.Itoa(frame.Height))
|
||||
_, _ = w.Write(frame.Data)
|
||||
}
|
||||
|
||||
func (a *Agent) handleClick(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodPost {
|
||||
helpers.WriteError(w, http.StatusMethodNotAllowed, "method not allowed")
|
||||
|
||||
Reference in New Issue
Block a user