+
27
-

回答

windows mac可以,pywebview 只是“壳”:它嵌入系统 WebView 组件,WebRTC 能力取决于底层浏览器引擎。

必须通过 HTTPS 或 localhost:现代浏览器要求安全上下文才能访问摄像头/屏幕。

Linux 限制最大:大多数 Linux 发行版的 WebKit2 不支持 navigator.mediaDevices.getDisplayMedia()(屏幕共享),仅能访问摄像头。

Windows/macOS:在 localhost 下可正常使用 getUserMedia()(摄像头)和 getDisplayMedia()(屏幕共享)。

这是我在win10上测试的

800_auto

完整代码

main.py

import webview
import threading
from flask import Flask, render_template
import os

# 确保 templates 文件夹存在,并包含 index.html
app = Flask(__name__, template_folder='templates')

@app.route('/')  # ← 修正:必须以 / 开头
def index():
    return render_template('index.html')

def run_server():
    app.run(host='localhost', port=5000, debug=False)

if __name__ == '__main__':
    # 可选:自动创建 templates 目录和示例 index.html(方便测试)
    if not os.path.exists('templates'):
        os.makedirs('templates')
        with open('templates/index.html', 'w', encoding='utf-8') as f:
            f.write('<h1>WebRTC 桌面共享与摄像头控制</h1><p>Flask + pywebview 已成功加载!</p>')

    # 启动 Flask 服务器线程
    server_thread = threading.Thread(target=run_server, daemon=True)
    server_thread.start()
    
    # 创建 pywebview 窗口,加载本地页面
    webview.create_window(
        'WebRTC 桌面共享与摄像头控制',
        'http://localhost:5000',  # ← 修正 URL 格式
        width=1200,
        height=800
    )
    webview.start()

templates/index.html

点击查看全文

<!DOCTYPE html>
<html>
<head>
    <title>WebRTC 控制界面</title>
    <style>
        .video-container {
            display: flex;
            gap: 20px;
            margin: 20px;
        }
        video {
            border: 2px solid #333;
            width: 500px;
            height: 300px;
        }
        button {
            padding: 10px 20px;
            margin: 10px;
            cursor: pointer;
        }
    </style>
</head>
<body>
    <h1>WebRTC 桌面共享与摄像头控制</h1>
    
    <div class="video-container">
        <div>
            <h3>本地摄像头</h3>
            <video id="localCamera" autoplay muted></video>
        </div>
        <div>
            <h3>桌面共享</h3>
            <video id="desktopShare" autoplay></video>
        </div>
    </div>
    
    <button onclick="startCamera()">开启摄像头</button>
    <button onclick="startDesktopShare()">开始桌面共享</button>
    <button onclick="stopStreams()">停止所有流</button>

    <script>
        let mediaStreams = [];

        // 开启摄像头
        async function startCamera() {
            try {
                const stream = await navigator.mediaDevices.getUserMedia({
                    video: true,
                    audio: false
                });
                document.getElementById('localCamera').srcObject = stream;
                mediaStreams.push(stream);
            } catch (err) {
                console.error('开启摄像头失败:', err);
            }
        }

        // 开始桌面共享
        async function startDesktopShare() {
            try {
                const stream = await navigator.mediaDevices.getDisplayMedia({
                    video: true,
                    audio: true
                });
                document.getElementById('desktopShare').srcObject = stream;
                mediaStreams.push(stream);
            } catch (err) {
                console.error('桌面共享失败:', err);
            }
        }

        // 停止所有媒体流
        function stopStreams() {
            mediaStreams.forEach(stream => {
                stream.getTracks().forEach(track => track.stop());
            });
            mediaStreams = [];
            document.getElementById('localCamera').srcObject = null;
            document.getElementById('desktopShare').srcObject = null;
        }
    </script>
</body>
</html>

网友回复

我知道答案,我要回答