#python #raspberry_pi
Имеется PiCamera с RPi. Пытаюсь написать Python код для управления камерой с помощью веб. В данный момент мой код выглядит вот так #!/usr/bin/env python # -*- coding: utf-8 -*- ''' Test version ''' from flask import Flask from datetime import datetime import io import time import picamera import logging import sys import os app = Flask(__name__) logging.basicConfig(level=logging.INFO, format='%(asctime)s %(levelname)-8s ' + '[%(filename)s:%(lineno)s:%(funcName)s()] %(message)s', datefmt='%Y-%m-%d %H:%M:%S') @app.route("/start", methods=['POST']) def start_capture(): with picamera.PiCamera() as camera: camera.resolution = (1920, 1080) camera.start_preview() time.sleep(300) @app.route("/stop", method=['POST']) def stop_capture(): with picamera.PiCamera() as camera: camera.stop_preview() @app.route("/screenshot", methods=['POST']) def screenshot(): with picamera.PiCamera() as camera: camera.capture('foo.jpg', use_video_port=True) if __name__ == "__main__": app.run(host='192.168.0.198', port='8080') Первое что не работает правильно - если я отправляю POST запрос к примеру на 192.168.192:8080/start, запрос отправляется бесконечно. Далее есть после старта, отправить запрос на стоп, ничего не происходит. Где я что, сделал не правильно? Есть ли способ, каким-то образом записать все в одну функцию, но при это вызывать разным запросом определенные части функции?
Ответы
Ответ 1
Попробую угадать ответ по документации picamera. Согласно ей, при входе в with-блок камера включается, а при выходе выключается, то есть получается: @app.route("/start", methods=['POST']) def start_capture(): with picamera.PiCamera() as camera: # Включили камеру camera.resolution = (1920, 1080) camera.start_preview() # with закончился — выключили камеру Отсюда вывод: надо как-то держать камеру постоянно включенной независимо от http-запросов. Простейший способ — вынести camera в глобальную переменную, где она и будет лежать включенная независимо от http-запросов: from threading import Lock import picamera camera = None # Сразу после запуска камера выключена camlock = Lock() # Блокировка нужна, чтобы нельзя было # лезть в камеру из нескольких запросов одновременно # ... app = Flask(__name__) logging всё такое скопировать сюда из вопроса # @app.route("/start", methods=['POST']) def start_capture(): global camera with camlock: if camera: return 'already started' camera = picamera.PiCamera() camera.resolution = (1920, 1080) return 'ok' @app.route("/stop", methods=['POST']) def stop_capture(): global camera with camlock: if not camera: return 'already stopped' camera.close() camera = None return 'ok' @app.route("/screenshot", methods=['POST']) def screenshot(): # Переменную не меняем — global необязателен with camlock: if not camera: return 'camera is not started' camera.capture('foo.jpg', use_video_port=True) return 'saved to foo.jpg' if __name__ == "__main__": try: app.run(host='192.168.0.198', port='8080') finally: # При завершении работы http-сервера камеру стоит выключить with camlock: if camera: camera.close() Raspberry Pi не имею и проверить работоспособность кода не могу, но вроде не должен был накосячить. (Замечание 1: глобальные переменные — довольно опасная штука, и при увеличении сложности проекта от них можно начать получать множество проблем, когда они начнут меняться непредсказуемо и всё такое.) (Замечание 2: возможно, более хорошим решением будет запуск второго потока, который и будет обслуживать камеру (без глобальной переменной) и принимать сообщения-команды от http-сервера из первого потока вместо непосредственного доступа к камере, но это увеличивает сложность и не факт что целесообразно в данном случае.)
Комментариев нет:
Отправить комментарий