title: PiCamera Flask, start and stop preview
body: <p>I am creating a little web interface in Flask to control the Raspberry Pi camera using the PiCamera python module. I have a working index page which displays a stream from the camera. However, when I POST stop_preview() via an input button the app fails and I cannot work out what I am doing wrong. Here's some of my code so far.</p>
  
  <p>This is part of my views.py</p>
  
  <pre><code>from flask import redirect, url_for, session, request, \
               render_template, Response
  from simplepam import authenticate
  from app.camera_pi import Camera
  from app import app
  
  
  @app.route('/', methods=['GET', 'POST'])
  @app.route('/index',  methods=['GET', 'POST'])
  def index():
      if request.method == 'POST':
          if request.form['submit']:
              Camera.StopPreview()
      elif request.method == 'GET':
          return render_template("index.html", title="Home")
  
  
  def gen(camera):
      """Video streaming generator function."""
      while True:
          frame = camera.get_frame()
          yield (b'--frame\r\n'
                 b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')
  
  
  @app.route('/video_feed')
  def video_feed():
      """Video streaming route. Put this in the src attribute of an img tag."""
      return Response(gen(Camera()),
                      mimetype='multipart/x-mixed-replace; boundary=frame')
  </code></pre>
  
  <p>This is my index.html template.</p>
  
  <pre><code>&lt;!DOCTYPE html&gt;
  
  
   &lt;html&gt;
        &lt;head&gt;
        &lt;/head&gt;
        &lt;body&gt;
          &lt;img id="video_feed" src="{{ url_for('video_feed') }}"&gt;
          &lt;form method="post"&gt;
            &lt;p&gt;&lt;input type="submit" name="submit" value="StopPreview"&gt;&lt;/p&gt;
          &lt;/form&gt;
        &lt;/body&gt;
      &lt;/html&gt;
  </code></pre>
  
  <p>This is the camera_pi.py file (taken from Miguel Grinberg's github repo <a href="https://github.com/miguelgrinberg/flask-video-streaming" rel="nofollow">https://github.com/miguelgrinberg/flask-video-streaming</a>)</p>
  
  <pre><code># The MIT License (MIT)
  #
  # Copyright (c) 2014 Miguel Grinberg
  #
  # Permission is hereby granted, free of charge, to any person obtaining a copy
  # of this software and associated documentation files (the "Software"), to deal
  # in the Software without restriction, including without limitation the rights
  # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  # copies of the Software, and to permit persons to whom the Software is
  # furnished to do so, subject to the following conditions:
  #
  # The above copyright notice and this permission notice shall be included in
  # all copies or substantial portions of the Software.
  #
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  # SOFTWARE.
  
  
  import time
  import io
  import threading
  import picamera
  from app import camera_config
  
  
  class Camera(object):
      thread = None  # background thread that reads frames from camera
      frame = None  # current frame is stored here by background thread
      last_access = 0  # time of last client access to the camera
      stop_camera = False
  
      def initialize(self):
          if Camera.thread is None:
              # start background frame thread
              Camera.thread = threading.Thread(target=self._thread)
              Camera.thread.start()
  
              # wait until frames start to be available
              while self.frame is None:
                  time.sleep(0)
  
      def get_frame(self):
          Camera.last_access = time.time()
          self.initialize()
          return self.frame
  
      def StopPreview():
          Camera.stop_camera = True
  
      @classmethod
      def _thread(cls):
          with picamera.PiCamera() as camera:
              # camera setup
              camera.resolution = camera_config.camera_resolution
  
              # let camera warm up
              camera.start_preview()
              time.sleep(2)
  
              stream = io.BytesIO()
              for foo in camera.capture_continuous(stream, 'jpeg',
                                                   use_video_port=True):
                  # store frame
                  stream.seek(0)
                  cls.frame = stream.read()
  
                  # reset stream for next frame
                  stream.seek(0)
                  stream.truncate()
  
                  # if there hasn't been any clients asking for frames in
                  # the last 10 seconds stop the thread
                  if time.time() - cls.last_access &gt; 10:
                      break
                  elif Camera.stop_camera is True:
                      break
          cls.thread = None
  </code></pre>
  
  <p>I have added the "def StopPreview()" section and it is being called when I POST a submit button from the index page, but the app just crashes at this point. </p>
  
  <p>Thanks in advance for any help you can provide.</p>