配置托管在 PythonAnywhere 上的视频流 Flask 服务器

问题描述 投票:0回答:1

托管 --> PythonAnywhere

工作:服务器从客户端接收图像并将其更新到网页。另一个客户端访问该网页并可以看到视频流。服务器不会保存图像,它只是在收到图像时将它们显示在网页上。

问题 --> 图片上传到服务器很顺利,但是只要我打开网页,客户端的图片上传就会停止。如果有人访问网页,服务器无法接收图像

服务器代码

from flask import Flask, Response, render_template
from flask import request
import cv2
import numpy as np

app = Flask(__name__)


global current_frame
current_frame = None

def generate_frames():
    while True:
        if current_frame is not None:
            ret, buffer = cv2.imencode('.jpg', current_frame)
            if ret:
                frame_bytes = buffer.tobytes()
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/upload_frame', methods=['POST'])
def upload_frame():
    global current_frame
    frame = request.data
    nparr = np.fromstring(frame, np.uint8)
    current_frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    return "Frame received and displayed"

if __name__ == '__main__':
    app.run('0.0.0.0')

客户端代码

import cv2
import requests
import numpy as np
import time

server_url = "http://danial880.pythonanywhere.com/upload_frame"


cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()

    if not ret:
        print("Failed to capture frame")
        break

    _, buffer = cv2.imencode('.jpg', frame)
    frame_bytes = buffer.tobytes()

    try:
        # Send the frame to the server
        response = requests.post(server_url, data=frame_bytes, headers={"Content-Type": "image/jpeg"})

        if response.status_code == 200:
            print("Frame uploaded successfully")
        else:
            print(f"Frame upload failed with status code {response.status_code}")
    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")

    #cv2.imshow("Webcam Feed", frame)
    time.sleep(0.1)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

我尝试的解决方案:使服务器异步

from flask import Flask, Response, render_template
from flask import request
import cv2
import numpy as np
import asyncio

app = Flask(__name__)


global current_frame
current_frame = None

async def generate_frames():
    while True:
        if current_frame is not None:
            ret, buffer = cv2.imencode('.jpg', current_frame)
            if ret:
                frame_bytes = buffer.tobytes()
                yield (b'--frame\r\n'
                       b'Content-Type: image/jpeg\r\n\r\n' + frame_bytes + b'\r\n')
        await asyncio.sleep(0.01)  # Add a small delay to reduce CPU load

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/video_feed')
def video_feed():
    return Response(generate_frames(), mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/upload_frame', methods=['POST'])
async def upload_frame():
    global current_frame
    frame = request.data
    nparr = np.fromstring(frame, np.uint8)
    current_frame = cv2.imdecode(nparr, cv2.IMREAD_COLOR)
    return "Frame received and displayed"

if __name__ == '__main__':
    app.run()

但是异步服务器之后网页上没有图像显示。简单的服务器显示收到的最后一帧。

我可以对服务器进行哪些更改,以便我可以流畅地进行流传输。

python-3.x flask web server video-streaming
1个回答
0
投票

您无法在 PythonAnywhere Web 应用程序中运行异步代码。

© www.soinside.com 2019 - 2024. All rights reserved.