Tutorial7 <<
Previous Next >> Webots Server
Stream
https://cyberbotics.com/doc/guide/web-streaming
Webots 透過 webotsw --stream 所啟動的串流伺服器, 僅允許連接 streaming_viewer 目錄中的 index.html, 若希望直接透過 index.html 啟動 WebSocket 連線, 就必須自行建立 WWW server.
以下利用 Python 程式在 port 8000 建立 WWW server, 並且執行時自動利用 Edge 連線至 index4.html 超文件.
python_www_server.py
import http.server
import socketserver
import threading
import webbrowser
import time
import os
import sys
import subprocess
PORT = 8000
DIRECTORY = os.path.dirname(os.path.abspath(__file__))
class Handler(http.server.SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=DIRECTORY, **kwargs)
def open_edge(url):
# Try common Edge paths on Windows
edge_paths = [
r"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe",
r"C:\Program Files\Microsoft\Edge\Application\msedge.exe"
]
for path in edge_paths:
if os.path.exists(path):
subprocess.Popen([path, url])
return True
# Fallback: try using webbrowser module (may open in default browser)
try:
webbrowser.get('windows-default').open(url)
except:
webbrowser.open(url)
return False
def run_server():
with socketserver.TCPServer(("", PORT), Handler) as httpd:
print(f"Serving at http://localhost:{PORT}")
httpd.serve_forever()
if __name__ == "__main__":
# Start server in a thread
server_thread = threading.Thread(target=run_server, daemon=True)
server_thread.start()
# Wait a moment for the server to start
time.sleep(1)
# Open Edge to the local index.html
url = f"http://localhost:{PORT}/streaming_viewer/index4.html"
print(f"Opening {url} in Edge...")
open_edge(url)
# Keep main thread alive to keep server running
try:
while True:
time.sleep(10)
except KeyboardInterrupt:
print("Shutting down.")
sys.exit(0)
index4.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title>Streaming viewer</title>
<link rel="icon" type="image/png" href="webots_icon.png">
<link type="text/css" rel="stylesheet" href='style.css' />
<style>
html, body {
height: 100%;
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
width: 100vw;
height: 100vh;
min-height: 100vh;
min-width: 100vw;
display: flex;
flex-direction: column;
background: #222;
}
header {
flex: 0 0 auto;
padding: 0;
margin: 0;
background: #181818;
color: #fff;
text-align: center;
}
.title-container {
margin: 0;
padding: 0.5em 0;
}
.webots-view-container {
flex: 1 1 0;
display: flex;
align-items: stretch;
justify-content: stretch;
min-height: 0;
min-width: 0;
}
webots-view {
width: 100vw;
height: 100vh;
flex: 1 1 0;
display: block;
min-width: 0;
min-height: 0;
}
</style>
</head>
<body>
<div class="webots-view-container">
<webots-view></webots-view>
</div>
<script type="module" src="http://localhost:8000/wwi/WebotsView.js"></script>
<script>
// Default WebSocket parameters
const defaultIp = "ws://localhost:1234";
const defaultStreamingMode = "x3d";
const defaultBroadcast = false;
const mobileDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
const defaultThumbnail = 'https://cyberbotics.com/wwi/R2023b/images/loading/default_thumbnail.png';
// Optional: load mobile CSS if on mobile device
if (mobileDevice) {
let head = document.getElementsByTagName('head')[0];
let mobileCss = document.createElement('link');
mobileCss.setAttribute('rel', 'stylesheet');
mobileCss.setAttribute('type', 'text/css');
mobileCss.setAttribute('href', 'https://www.cyberbotics.com/wwi/R2023b/css/wwi_mobile.css');
head.appendChild(mobileCss);
}
// Wait for WebotsView.js to load and custom element to be defined
window.addEventListener('DOMContentLoaded', () => {
customElements.whenDefined('webots-view').then(() => {
const webotsView = document.querySelector('webots-view');
webotsView.onready = () => {
console.log("Connected to Webots streaming server!");
};
webotsView.ondisconnect = () => {
console.log("Disconnected from Webots streaming server!");
};
webotsView.connect(defaultIp, defaultStreamingMode, defaultBroadcast, mobileDevice, -1, defaultThumbnail);
});
});
</script>
</body>
</html>
Tutorial7 <<
Previous Next >> Webots Server