流萤337 2025-02-07 19:06 采纳率: 33.3%
浏览 12
已结题

html文件触摸遇到问题

import cv2
import mss
import numpy as np
from flask import Flask, Response, request, redirect, url_for, send_from_directory
from comet_ml import Experiment

# 初始化Comet实验
experiment = Experiment(api_key="YOUR_API_KEY", project_name="screen-sharing")

# 第二块显示器的编号为1(索引从0开始)
monitor_number = 2

app = Flask(__name__)

def generate_frames():
    with mss.mss() as sct:
        monitor = sct.monitors[monitor_number]

        while True:
            # 捕获屏幕
            screenshot = sct.grab(monitor)
            img = np.array(screenshot)

            # 将图像转换为JPEG格式
            ret, buffer = cv2.imencode('.jpg', img)
            frame = buffer.tobytes()

            # 使用Comet记录图像
            experiment.log_image(img, name="screen_capture")

            yield (b'--frame\r\n'
                   b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n')

@app.route('/')
def index():
    return redirect(url_for('video_feed'))

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

# 添加静态文件路由
@app.route('/static/<path:filename>')
def static_files(filename):
    return send_from_directory('static', filename)

# 假设我们有一个函数可以模拟触摸事件
def simulate_touch_event(event_type, x, y):
    # 这里可以调用某个库或者工具来模拟触摸事件
    # 例如,使用pyautogui库来模拟鼠标点击
    import pyautogui
    if event_type == 'tap':
        pyautogui.click(x, y)
    elif event_type == 'double_tap':
        pyautogui.doubleClick(x, y)
    elif event_type == 'long_press':
        pyautogui.mouseDown(x, y)
        pyautogui.mouseUp(x, y)
    elif event_type == 'swipe_left':
        pyautogui.moveTo(x, y)
        pyautogui.dragTo(x - 100, y, duration=0.5)
    elif event_type == 'swipe_right':
        pyautogui.moveTo(x, y)
        pyautogui.dragTo(x + 100, y, duration=0.5)
    elif event_type == 'swipe_up':
        pyautogui.moveTo(x, y)
        pyautogui.dragTo(x, y - 100, duration=0.5)
    elif event_type == 'swipe_down':
        pyautogui.moveTo(x, y)
        pyautogui.dragTo(x, y + 100, duration=0.5)

@app.route('/tap', methods=['POST'])
def handle_tap():
    # 处理单击事件
    print("Single Tap Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Tap at coordinates: ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('tap', x, y)
    return "OK"

@app.route('/double_tap', methods=['POST'])
def handle_double_tap():
    # 处理双击事件
    print("Double Tap Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Double Tap at coordinates: ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('double_tap', x, y)
    return "OK"

@app.route('/long_press', methods=['POST'])
def handle_long_press():
    # 处理长按事件
    print("Long Press Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Long Press at coordinates: ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('long_press', x, y)
    return "OK"

@app.route('/swipe_left', methods=['POST'])
def handle_swipe_left():
    # 处理左滑事件
    print("Swipe Left Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Swipe Left from ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('swipe_left', x, y)
    return "OK"

@app.route('/swipe_right', methods=['POST'])
def handle_swipe_right():
    # 处理右滑事件
    print("Swipe Right Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Swipe Right from ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('swipe_right', x, y)
    return "OK"

@app.route('/swipe_up', methods=['POST'])
def handle_swipe_up():
    # 处理上滑事件
    print("Swipe Up Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Swipe Up from ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('swipe_up', x, y)
    return "OK"

@app.route('/swipe_down', methods=['POST'])
def handle_swipe_down():
    # 处理下滑事件
    print("Swipe Down Detected")
    data = request.get_json()
    x = data.get('x')
    y = data.get('y')
    print(f"Swipe Down from ({x}, {y})")  # 打印触摸信息
    simulate_touch_event('swipe_down', x, y)
    return "OK"

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Screen Sharing</title>
    <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
</head>
<body>
    <h1>Screen Sharing</h1>
    <img id="screen-capture" src="{{ url_for('video_feed') }}" alt="Screen Capture">
    <script src="{{ url_for('static', filename='js/script.js') }}"></script>
    <script>
        const screenCapture = document.getElementById('screen-capture');

        // 添加全屏显示代码
        document.addEventListener('DOMContentLoaded', () => {
            if (screenCapture.requestFullscreen) {
                screenCapture.requestFullscreen();
            } else if (screenCapture.mozRequestFullScreen) { // Firefox
                screenCapture.mozRequestFullScreen();
            } else if (screenCapture.webkitRequestFullscreen) { // Chrome, Safari and Opera
                screenCapture.webkitRequestFullscreen();
            } else if (screenCapture.msRequestFullscreen) { // IE/Edge
                screenCapture.msRequestFullscreen();
            }
        });

        let touchStartTime;
        let touchStartX, touchStartY;
        let touchEndX, touchEndY;

        screenCapture.addEventListener('touchstart', (event) => {
            console.log('Touch Start');  // 添加调试信息
            touchStartTime = new Date().getTime();
            touchStartX = event.touches[0].clientX;
            touchStartY = event.touches[0].clientY;
        });

        screenCapture.addEventListener('touchend', (event) => {
            console.log('Touch End');  // 添加调试信息
            const touchEndTime = new Date().getTime();
            touchEndX = event.changedTouches[0].clientX;
            touchEndY = event.changedTouches[0].clientY;

            const touchDuration = touchEndTime - touchStartTime;
            const deltaX = touchEndX - touchStartX;
            const deltaY = touchEndY - touchStartY;

            const rect = screenCapture.getBoundingClientRect();
            const x = touchStartX - rect.left;
            const y = touchStartY - rect.top;

            if (touchDuration < 500) {
                if (Math.abs(deltaX) < 30 && Math.abs(deltaY) < 30) {
                    // Tap or Double Tap
                    if (touchDuration < 200) {
                        // Double Tap
                        console.log('Double Tap');  // 添加调试信息
                        fetch('/double_tap', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
                    } else {
                        // Single Tap
                        console.log('Single Tap');  // 添加调试信息
                        fetch('/tap', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
                    }
                } else {
                    // Swipe
                    if (Math.abs(deltaX) > Math.abs(deltaY)) {
                        if (deltaX > 0) {
                            // Swipe Right
                            console.log('Swipe Right');  // 添加调试信息
                            fetch('/swipe_right', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
                        } else {
                            // Swipe Left
                            console.log('Swipe Left');  // 添加调试信息
                            fetch('/swipe_left', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
                        }
                    } else {
                        if (deltaY > 0) {
                            // Swipe Down
                            console.log('Swipe Down');  // 添加调试信息
                            fetch('/swipe_down', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
                        } else {
                            // Swipe Up
                            console.log('Swipe Up');  // 添加调试信息
                            fetch('/swipe_up', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
                        }
                    }
                }
            } else {
                // Long Press
                console.log('Long Press');  // 添加调试信息
                fetch('/long_press', { method: 'POST', body: JSON.stringify({ x: x, y: y }), headers: { 'Content-Type': 'application/json' } });
            }
        });
    </script>
</body>
</html>

我本来想实现与parsecVDisplay的创建虚拟显示器做配合的,但以上代码已经实现了在手机端显示第二个显示器的屏幕信息,但我碰到一个问题,就是不知道为何html文件里的触摸事件总是检测不了,且无法实现手机触摸对虚拟显示屏的控制。

  • 写回答

6条回答 默认 最新

  • 专家-赤兔[在线] 优质创作者: 编程框架技术领域 2025-02-07 19:07
    关注

    以下回复引自免费微信小程序:皆我百晓生。 如问题解决,还请采纳。如仍有疑问,请回复留言或私信博主,以便获得更精准的帮助。

    在HTML文件中使用FLASK时遇到的问题是:无法正确识别触摸事件。这个问题可能是因为你没有正确配置MSSHOT库和FLASK的WEBSOCKET模块。以下是一个简单的解决方法:

    1. 首先确保你的项目中已经安装了MSSHOT库和FLASK的WEBSOCKET模块。
    2. 使用FLASK创建一个WEB服务器,例如HTTP://LOCALHOST:5000/
    3. 在服务器端,编写一个函数来处理触摸事件,并将结果返回给客户端。
    4. 在客户端,使用PYTHON的MSS库读取MSSHOT图像并将其转换为NUMPY数组。
    5. 通过网络将这些NUMPY数组发送给服务器。

    这是一个基本的实现:

    IMPORT SOCKETIO
    IMPORT NUMPY AS NP
    FROM FLASK IMPORT FLASK, RESPONSE, REQUEST, REDIRECT, URL_FOR
    
    SIO = SOCKETIO.SERVER()
    APP = FLASK(__NAME__)
    
    @APP.ROUTE('/')
    DEF INDEX():
        RETURN "HELLO WORLD!"
    
    @SIO.ON('CONNECT')
    DEF CONNECT(SID, ENVIRON):
        PRINT("CONNECTED")
    
    @SIO.ON('MESSAGE')
    DEF MESSAGE(SID, DATA):
        PRINT("RECEIVED MESSAGE FROM %S" % SID)
        
        # 将数据写入WEBSOCKET
        SIO.EMIT('RESPONSE', {'DATA': 'YOU HAVE SENT THE MESSAGE!'})
        
    
    IF __NAME__ == '__MAIN__':
        APP.RUN(HOST='0.0.0.0', PORT=8080)
    

    在这个例子中,我们首先定义了一个SOCKETSIO对象,然后创建了一个WEB服务器SIOSIO.CONNECT()用于连接到SOCKETIO服务器。

    接下来,在INDEX路由下,我们返回一个简单的欢迎信息。

    MESSAGE路由接收来自WEBSOCKET的消息,并将消息内容发送回客户端。

    当服务器启动后,它将在本地地址HTTP://LOCALHOST:5000/上运行。如果需要更复杂的界面或特定功能,可以进一步扩展这个示例。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 3月1日
  • 已采纳回答 2月21日
  • 创建了问题 2月7日