目录
被控端手机(termux)
控制端手机
主要通过MQTT实现通信。图片的上传和显示使用了服务器。
对于没有服务器的同学,可以进入官网领取免费1个月的轻量云服务器:云产品免费试用;需要选购的进:轻量应用服务器专场;不清楚怎么操作的可以看教程:腾讯云产品免费试用教程
实现效果:
当然这只是一个示例,只要能实现手机间的通信,那就可以借助termux-api实现非常多的功能!
被控端手机(termux)
pip换源:
apt update -y
apt upgrade -y
apt install python -y
apt install python-dev -y
apt install clang -y
apt install libffi-dev -y
apt install openssl-dev -y
apt install libxml2-dev libxslt-dev -y
mkdir ~/.pip
touch ~/.pip/pip.conf
nano ~/.pip/pip.conf
写入内容:
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple/
termux安装mqtt等库:
pip install paho-mqtt requests
apt install imagemagick catimg -y
在termux中的Python代码为:
# coding:utf-8
import paho.mqtt.client as pahomqtt
import os
import base64
import requests
import time
import threading
import socket
from queue import Queue
def get_host_ip():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip = ''
try:
s.connect(('8.8.8.8', 80))
ip = s.getsockname()[0]
finally:
s.close()
return ip
class MQTT:
def __init__(self):
self.CLIENTID = 'redmi8'
self.MQTTHOST = "xfxuezhang.cn"
self.MQTTPORT = 1883
self.USERNAME = 'lh'
self.PASSWORD = "hualala"
self.HEARTBEAT = 60
self.topic_subscribe = f'/mqtt/{self.CLIENTID}'
self.topic_publish = f'/mqtt/{self.CLIENTID}/send/msg'
self.topic_publish_image = f'/mqtt/{self.CLIENTID}/send/image'
self.heart_beat_publish = f'/mqtt/{self.CLIENTID}/heartbeat'
self.client = pahomqtt.Client()
self.CloudAllowRun = 1
self.msg_buffer = Queue()
def get_msg(self):
if self.msg_buffer.empty():
return None
return self.msg_buffer.get()
# MQTT连接回调
def on_connect(self, client, userdata, flags, rc):
if rc == 0:
print("Connected")
client.subscribe(self.topic_subscribe)
# MQTT接收回调
def on_message(self, client, userdata, message):
result = 'ok'
msg = str(message.payload.decode("utf-8")).strip()
print("Received message: " + msg)
self.msg_buffer.put(msg)
def remove_image(self, path="a.png"):
url = 'http://xfxuezhang.cn/web/picture/remove_file.php?name='+path
if os.path.exists(path):
os.remove(path)
return requests.get(url).text
def upload_image(self, path="a.png"):
result = None
try:
url = 'http://xfxuezhang.cn/web/picture/upload_file.php'
os.popen(f'convert {path} -resize 200x150 {path}')
filename = path.split('/')[-1]
files = {"file": (filename, open(path, "rb"), "image/png")}
response = requests.post(url, files=files)
print(response.text)
result = response.json()['data']
except Exception as e:
print(e)
return result
def convert_image(self, path="a.png"):
os.popen(f'convert {path} -resize 200x150 {path}')
# 从文件中读取图片并将其转换为二进制数据
with open(path, "rb") as f:
image_bytes = f.read()
# 将二进制数据编码为base64字符串
image_base64 = base64.b64encode(image_bytes).decode("utf-8")
return image_base64
def heart_beat(self):
msg = 'ip: ' + get_host_ip()
print(f'>> 心跳信息: {msg}')
try:
self.client.publish(topic=self.heart_beat_publish, payload=msg, qos=0)
except Exception as e:
print(e)
def mqtt(self):
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.client.username_pw_set(self.USERNAME, self.PASSWORD)
try:
self.client.connect(self.MQTTHOST, self.MQTTPORT, self.HEARTBEAT)
# self.client.loop_forever() # 阻塞方式
self.client.loop_start() # 线程方式
except:
pass
def publish(self, topic, msg, qos=0):
self.client.publish(topic=topic, payload=msg, qos=qos)
if __name__ == '__main__':
mqtt = MQTT()
while True:
try:
mqtt.mqtt()
break
except Exception as e:
print('异常,5s后重试=>' + str(e))
time.sleep(5)
print('>> MQTT 启动成功')
while True:
msg = mqtt.get_msg()
if not msg:
# 没有消息要处理时,定时上报心跳
mqtt.heart_beat()
time.sleep(1)
continue
# 收到消息
if msg.startswith('cmd:img'):
_, cmd, path = msg.split(' ')
print('>> 图片路径:', path)
if cmd == 'upload':
img = mqtt.upload_image(path)
if img:
mqtt.publish(topic=mqtt.topic_publish_image, msg=img)
result = 'upload ok'
else:
result = 'upload fail'
elif cmd == 'remove':
mqtt.remove_image(path)
result = 'remove ok'
else:
# 执行本地cmd命令,并将结果保存到变量result中
result = os.popen(msg).read().strip() or 'complete'
print(">> 指令结果: " + result)
mqtt.publish(topic=mqtt.topic_publish, msg=result)
运行记录:
控制端手机
另一台控制端的手机上安装“MQTT Dashboard”,并添加一些组件,其中的主题根据上面的代码来填。实现效果:
MQTT Dashboard 中导入上面所示的界面配置:
{"tiles":[{"broker_id":1,"color":-8604862,"compact_layout":false,"confirm":false,"customize_output":false,"enable_pub":false,"icon":"device_vec_home_account","last_update":1688190731101,"name":"执行结果","notificationMessage":"","notificationTitle":"","notifyOnChange":false,"output_template":"","paintBackground":true,"payloadIsJson":false,"payload_path":"","position":0,"qos":0,"retain":false,"show_as_shortcut":false,"tile_details":{},"tile_type":3,"timestamp_path":"","topic":"/mqtt/redmi8/send/msg","topic_pub":"","tunables":{"text_postfix":"","text_prefix":""},"uid":4,"value":""},{"broker_id":1,"color":-16023485,"compact_layout":true,"confirm":true,"customize_output":false,"enable_pub":true,"icon":"mdes_ico_camera_alt","last_update":0,"name":"前置拍照","notificationMessage":"","notificationTitle":"","notifyOnChange":false,"output_template":"","paintBackground":true,"payloadIsJson":false,"payload_path":"","position":1,"qos":0,"retain":false,"show_as_shortcut":false,"tile_details":{},"tile_type":2,"timestamp_path":"","topic":"","topic_pub":"/mqtt/redmi8","tunables":{"click_payload":"termux-camera-photo -c 1 a.png"},"uid":1,"value":""},{"broker_id":1,"color":-538816,"compact_layout":true,"confirm":true,"customize_output":false,"enable_pub":true,"icon":"mdes_ico_collections","last_update":0,"name":"获取照片","notificationMessage":"","notificationTitle":"","notifyOnChange":false,"output_template":"","paintBackground":true,"payloadIsJson":false,"payload_path":"","position":2,"qos":0,"retain":false,"show_as_shortcut":false,"tile_details":{},"tile_type":2,"timestamp_path":"","topic":"","topic_pub":"/mqtt/redmi8","tunables":{"click_payload":"cmd:img upload a.png"},"uid":2,"value":""},{"broker_id":1,"color":-2818048,"compact_layout":true,"confirm":true,"customize_output":false,"enable_pub":true,"icon":"mdes_ico_delete_forever","last_update":0,"name":"删除照片","notificationMessage":"","notificationTitle":"","notifyOnChange":false,"output_template":"","paintBackground":true,"payloadIsJson":false,"payload_path":"","position":3,"qos":0,"retain":false,"show_as_shortcut":false,"tile_details":{},"tile_type":2,"timestamp_path":"","topic":"","topic_pub":"/mqtt/redmi8","tunables":{"click_payload":"cmd:img remove a.png"},"uid":3,"value":""},{"broker_id":1,"color":-16540699,"compact_layout":true,"confirm":true,"customize_output":false,"enable_pub":true,"icon":"device_vec_human_greeting","last_update":0,"name":"自定义指令","notificationMessage":"","notificationTitle":"","notifyOnChange":false,"output_template":"","paintBackground":true,"payloadIsJson":false,"payload_path":"","position":4,"qos":0,"retain":false,"show_as_shortcut":false,"tile_details":{},"tile_type":2,"timestamp_path":"","topic":"","topic_pub":"/mqtt/redmi8","tunables":{"click_payload":""},"uid":5,"value":""},{"broker_id":1,"color":-5792882,"compact_layout":false,"confirm":false,"customize_output":false,"enable_pub":true,"icon":"mdes_ico_filter","last_update":1688190953875,"name":"照片显示","notificationMessage":"","notificationTitle":"","notifyOnChange":false,"output_template":"","paintBackground":true,"payloadIsJson":false,"payload_path":"","position":100,"qos":0,"retain":false,"show_as_shortcut":false,"tile_details":{},"tile_type":9,"timestamp_path":"","topic":"/mqtt/redmi8/send/image","topic_pub":"","tunables":{"auto_refresh_image":"true","refresh_interval":"10"},"uid":6,"value":""}],"groups":[],"groupsTileJoin":[]}
文章来源:https://www.toymoban.com/news/detail-521733.html
文章来源地址https://www.toymoban.com/news/detail-521733.html
到了这里,关于【教程】手机远程连接另一台手机的termux进行拍照的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!