
树莓派监控画面在鸿蒙智慧屏的多窗口分屏方案
方案概述
此方案将树莓派的监控画面通过WebSocket传输到鸿蒙智慧屏,然后在鸿蒙设备上使用MultiScreenControl组件实现多窗口分屏显示。
树莓派端代码(Python)
import cv2
import numpy as np
from flask import Flask, render_template, Response
import threading
import time
import base64
app = Flask(name)
camera = cv2.VideoCapture(0) # 使用默认摄像头
def get_frame():
ret, frame = camera.read()
if ret:
# 转换为JPEG格式
_, buffer = cv2.imencode(‘.jpg’, frame)
frame = base64.b64encode(buffer).decode(‘utf-8’)
return frame
return None
@app.route(‘/’)
def index():
return render_template(‘index.html’)
def gen():
while True:
frame = get_frame()
if frame is not None:
yield (b’–frame\r\n’
b’Content-Type: text/plain\r\n\r\n’ + frame + b’\r\n’)
@app.route(‘/video_feed’)
def video_feed():
return Response(gen(), mimetype=‘multipart/x-mixed-replace; boundary=frame’)
if name == ‘main’:
app.run(host=‘0.0.0.0’, port=5000, debug=True, threaded=True)
鸿蒙智慧屏端代码(ArkTS)
// MultiScreenControl.ets
import http from ‘@ohos.net.http’;
import media from ‘@ohos.multimedia.media’;
import { Image, ImageSource } from ‘@ohos.multimedia.image’;
@Entry
@Component
struct MultiScreenControlComponent {
@State private splitScreenMode: number = 1; // 1: 1x1, 2: 2x2, 3: 3x3
@State private videoUrls: string[] = [];
private playerMap: Map<number, media.Player> = new Map();
private httpController: http.HttpRequestController = null;
aboutToAppear() {
this.videoUrls = [
‘http://树莓派IP地址:5000/video_feed’,
‘http://树莓派IP地址:5000/video_feed’, // 可以添加更多树莓派源
‘http://树莓派IP地址:5000/video_feed’,
‘http://树莓派IP地址:5000/video_feed’
];
// 初始化播放器
for (let i = 0; i < 4; i++) {
this.initPlayer(i);
}
aboutToDisappear() {
// 释放资源
this.playerMap.forEach((player, key) => {
player.stop();
player.release();
});
this.playerMap.clear();
if (this.httpController) {
this.httpController.cancel();
}
initPlayer(index: number) {
let player = media.createPlayer();
player.on(‘error’, (err) => {
console.error(Player {index} error: {JSON.stringify(err)});
});
// 设置视频源为网络流
let source = media.createUrlSource(this.videoUrls[index % this.videoUrls.length]);
player.setSource(source);
// 监听准备完成事件
player.on('prepared', () => {
console.info(Player ${index} prepared);
player.play();
// 创建ImageSource用于显示
let imageSource = ImageSource.create(source);
let image = this.$w('video_' + index).imageSource;
if (image && imageSource) {
imageSource.on('frameAvailable', (frame) => {
// 更新UI显示最新帧
this.$w('video_' + index).refresh();
});
});
this.playerMap.set(index, player);
changeSplitScreenMode(mode: number) {
this.splitScreenMode = mode;
build() {
Column() {
// 顶部控制栏
Row() {
Button('单窗口')
.onClick(() => this.changeSplitScreenMode(1))
.backgroundColor(this.splitScreenMode === 1 ? '#007DFF' : '#F1F3F5')
Button('双窗口')
.onClick(() => this.changeSplitScreenMode(2))
.backgroundColor(this.splitScreenMode === 2 ? '#007DFF' : '#F1F3F5')
Button('四窗口')
.onClick(() => this.changeSplitScreenMode(3))
.backgroundColor(this.splitScreenMode === 3 ? '#007DFF' : '#F1F3F5')
.width(‘100%’)
.padding(10)
.justifyContent(FlexAlign.SpaceEvenly)
// 视频显示区域
Flex({ direction: FlexDirection.Column, wrap: FlexWrap.Wrap }) {
ForEach([0, 1, 2, 3], (index) => {
// 根据分屏模式决定显示哪些窗口
if (
(this.splitScreenMode = 1 && index = 0) |
(this.splitScreenMode = 2 && (index = 0
index === 1))
|
(this.splitScreenMode === 3 && index < 4)
) {
Column() {
Image(this.videoUrls[index % this.videoUrls.length])
.id(‘video_’ + index)
.width(‘100%’)
.height(‘100%’)
.objectFit(ImageFit.Contain)
.borderRadius(8)
.width(this.splitScreenMode === 1 ? ‘100%’ :
this.splitScreenMode === 2 ? '50%' : '50%')
.height(this.splitScreenMode === 1 ? '100%' :
this.splitScreenMode === 2 ? '50%' : '50%')
})
.width(‘100%’)
.height('90%')
.width(‘100%’)
.height('100%')
}
部署说明
将树莓派代码保存为app.py,在树莓派上运行:
python3 app.py
鸿蒙智慧屏应用需在DevEco Studio中创建并导入上述ArkTS代码
修改鸿蒙代码中的树莓派IP地址为实际树莓派的IP
确保鸿蒙设备与树莓派在同一网络环境下
鸿蒙应用需要申请网络权限和媒体播放权限
此方案实现了通过WebSocket传输树莓派监控画面,并在鸿蒙智慧屏上使用MultiScreenControl组件进行多窗口分屏显示。可根据实际需求扩展更多窗口或添加其他功能。
