电压

  • 设备电压工作原则:给多少用多少。

电流

  • 设备电压工作原则:用多少拿多少。

电平

  • 指两功率或电压之比的对数,有时也可用来表示两电流之比的对数。常用的电平有功率电平和电压电平两类,它们各自又可分为绝对电平和相对电平两种。

  • 电平主要用于驱动信号传输,它的电流非常小,我们把高于0.7V的叫高电平,低于0.7V的叫低电平。

  • 标准低平为:0V。标准高电平为:3.3V或1.8V

电阻

串联

  • 通过同一电流;
  • 接地形成分压;
  • 串联阻值变大。

并联

  • 承受同一电压;
  • 并联形成分流;
  • 并联阻值变小。

上拉电阻

  • 在电路中一端接电压另一端接信号的电阻叫上拉电阻。(阻值较大)
  • 作用:上拉电阻可以提高电路的驱动能力,在默认状态下,将不确定的信号钳位在高电平。当输入为低时,上拉电阻又可以将信号钳位在低电平,它可以让信号在高低电平之间转换。

下拉电阻

  • 在电路中一端接地另一端接入芯片的电阻叫下拉电阻。
  • 作用:在默认状态,下拉电阻可以将不确定的信号钳位在低电平,当输入为高时,下拉电阻以可以将信号钳位在高电平,它可以让信号在高低电平之间转换。

藕合电阻

  • 在电路中芯片与芯片或芯片与接口之间传递信号经过的电阻叫耦合电阻。
  • 作用:信号匹配或缓冲。
  • 阻值一般在100欧以内(常用33Ω、47Ω、15Ω)

保险电阻

  • 在电路中两端都接电压并且阻值较小(10欧以内)的电阻叫保险电阻。
  • 作用:当输入电压过高或电流过大时,电阻熔断从而保护芯片。

检流电阻

  • 串联在电压输出端,检测电压输出端的电流。

开始准备

目标文件的局域网地址:确保文件可以通过 HTTP 或 FTP 访问。例如,http://192.168.1.100/zhujiang.m3u8

iOS 设备与文件所在设备同处一个局域网。

快捷指令应用(iOS 自带)已安装并设置好权限。

快捷指令设置

  1. 创建快捷指令

打开 iOS 的快捷指令应用。
点击右上角的 “+” 按钮,新建快捷指令。

  1. 添加动作

  2. 获取文件内容

    搜索并添加 “获取URL的内容” 动作。
    在 URL 字段输入目标文件的局域网地址,例如 http://192.168.1.100/zhujiang.m3u8

  3. 保存到文件

    添加 “保存文件” 动作。
    在“存储到”中选择【文件】应用中的目标文件夹。
    如果需要覆盖旧文件,启用“如果文件存在,则替换”选项。

  4. 测试运行

点击右上角 “运行” 按钮,确保文件可以成功下载并保存到指定位置。

自动定时设置

设置方法:

  1. 创建快捷指令:
    按照前述步骤,配置完成一个可用的快捷指令用于下载和保存文件。
    保存快捷指令,命名为如“更新局域网文件”。
  2. 添加日历或提醒任务:
    打开 iOS 的【提醒事项】或【日历】应用。
    创建一个重复的提醒或事件:
    设置提醒时间(例如每月的 1 号上午 10:00)。
    在提醒的“附加操作”中,选择运行“更新局域网文件”快捷指令。
  3. 运行测试:
    在提醒触发时,系统会弹出通知,点击通知即可运行快捷指令。

获取代码

python3.13

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import sys
import os
import django

# 添加项目根目录到 sys.path 中
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../../')))

# 设置 Django 环境变量
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "epg_scraper.settings") # 替换为你的 Django 项目名
django.setup()

import datetime
import requests
import warnings
from bs4 import BeautifulSoup as bs
from epg.models import Channel, EPG
from django.db import IntegrityError

# 定义请求头,模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}

# 忽略 XMLParsedAsHTMLWarning
warnings.filterwarnings('ignore')

# 获取广东电视台频道列表
def get_channels_gdtv():
url = 'http://epg.gdtv.cn/f/1.xml' # 获取广东电视台频道列表的XML文件
res = requests.get(url, headers=headers)
res.encoding = 'utf-8'
soup = bs(res.text, 'lxml')
contents = soup.select('channel')
channels = []

# 遍历频道内容并检查是否存在
for content in contents:
channel_id = content.attrs['id']
name = content.ctitle.text.strip() # 使用 strip() 清理可能的空格和换行

# 确保频道唯一,避免重复添加
existing_channels = Channel.objects.filter(channel_id=channel_id)
if existing_channels.exists():
print(f"频道 {name} 已存在于数据库。")
else:
Channel.objects.create(name=name, channel_id=channel_id)
print(f"频道 {name} 已添加到数据库。")

channels.append(existing_channels.first() if existing_channels.exists() else Channel.objects.get(channel_id=channel_id))

return channels

# 处理节目标题中的 HTML 实体和标签
def clean_html(text):
# 将 HTML 实体转换为普通字符(例如 & -> &)
text = bs(text, "html.parser").get_text()

# 替换 <br /> 标签为换行符
text = text.replace('<br />', '\n').replace('<br>', '\n')

return text.strip()

# 获取指定日期范围内的节目表
def get_epgs_gdtv(channel, start_date, end_date):
epgs = []
success = 1
try:
# 循环抓取指定日期范围内的节目
current_date = start_date
while current_date <= end_date:
url = f'http://epg.gdtv.cn/f/{channel.channel_id}/{current_date.strftime("%Y-%m-%d")}.xml'
res = requests.get(url, headers=headers, timeout=8)
res.encoding = 'utf-8'
soup = bs(res.text, 'lxml-xml')
epgs_contents = soup.select('content')

# 解析并保存节目数据
for epga in epgs_contents:
starttime = datetime.datetime.fromtimestamp(int(epga.attrs['time1']))
endtime = datetime.datetime.fromtimestamp(int(epga.attrs['time2']))
title = clean_html(epga.get_text()) # 使用清理函数

# 检查数据库中是否已经存在相同的节目
if not EPG.objects.filter(channel=channel, starttime=starttime, title=title).exists():
try:
# 如果不存在,则创建新的节目记录
EPG.objects.create(
channel=channel,
title=title,
starttime=starttime,
endtime=endtime,
program_date=current_date
)
print(f"新增节目: {title} ({starttime} - {endtime})")
except IntegrityError:
print(f"插入节目时发生错误: {title}")

current_date += datetime.timedelta(days=1) # 增加一天

print(f"成功抓取 {channel.name} 的节目表。")
except Exception as e:
print(f"抓取 {channel.name} 的节目表失败: {e}")
success = 0

return success, epgs

# 获取前七天到后两天的节目表
def fetch_all_channels_and_epgs():
today = datetime.datetime.now().date()
start_date = today - datetime.timedelta(days=7) # 七天前
end_date = today + datetime.timedelta(days=2) # 两天后

channels = get_channels_gdtv() # 获取并确保频道存在
for channel in channels:
get_epgs_gdtv(channel, start_date, end_date) # 抓取并保存节目信息

# 执行抓取
if __name__ == "__main__":
fetch_all_channels_and_epgs()

定时配置

项目settings.py添加

1
2
# Celery Beat Scheduler 设置
CELERY_BEAT_SCHEDULER = 'django_celery_beat.schedulers:DatabaseScheduler'

源码地址

1
https://github.com/heiok/epg_scraper

服务器端设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost ~]# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.25 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::215:5dff:fe01:1106 prefixlen 64 scopeid 0x20<link>
ether 00:15:5d:01:11:06 txqueuelen 1000 (Ethernet)
RX packets 8981591 bytes 5389285998 (5.0 GiB)
RX errors 0 dropped 58 overruns 0 frame 0
TX packets 1369788 bytes 1311502278 (1.2 GiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 407818 bytes 117744700 (112.2 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 407818 bytes 117744700 (112.2 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

[root@localhost ~]#
1
[root@localhost ~]# ssh -D 9527 -fgN -i id_rsa opc@180.223.1.189

代理文件配置

代理自动配置(Proxy auto-config,简称PAC)是一种网页浏览器技术,用于定义浏览器该如何自动选择适当的代理服务器来访问一个网址。

1
2
3
function FindProxyForURL(url, host) {
return "SOCKS 192.168.1.25:9527";
}

以上三行代码保存为proxy.pac文件,放到http服务器。

1
2
3
4
5
6
7
8
DIRECT
直接连接,不使用代理

PROXY host:port
   使用指定的http代理

SOCKS host:port
   使用指定的SOCKS代理

手机终端设置

1
设置-无线局域网-右侧感叹号-配置代理-自动-URL-http://192.168.1.203/proxy.pac-存储

获取电视机基础信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
http://192.168.8.31:6095/request?action=isalive


{
"status": 0,
"msg": "success",
"data": {
"devicename": "E",
"ip": "192.168.8.31:6095",
"feature": [
"power"
],
"url": [
"http://bilibili.kankanews.com/video/av\\d+/",
"http://www.bilibili.tv/video/av\\d+/"
],
"platform": 699,
"build": 3354,
"version": 16777510
}
}

获取电视机安装的APP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
http://192.168.8.31:6095/controller?action=getinstalledapp&count=999&changeIcon=1


{
"status": 0,
"msg": "success",
"data": {
"AppInfo": [
{
"PackageName": "com.mitv.alarmcenter",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.mitv.alarmcenter0.png",
"AppName": "定时提醒",
"Order": 1
},
{
"PackageName": "com.dangbei.lerad.videoposter",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.dangbei.lerad.videoposter0.png",
"AppName": "当贝播放器",
"Order": 2
},
{
"PackageName": "com.qisyun.sunday.cxyp",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.qisyun.sunday.cxyp0.png",
"AppName": "创享云屏",
"Order": 3
},
{
"PackageName": "com.baidu.netdisk.tv",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.baidu.netdisk.tv0.png",
"AppName": "百度网盘",
"Order": 4
},
{
"PackageName": "com.xiaomi.tweather",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.tweather0.png",
"AppName": "天气",
"Order": 5
},
{
"PackageName": "com.duokan.videodaily",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.duokan.videodaily0.png",
"AppName": "视频头条",
"Order": 6
},
{
"PackageName": "com.xiaomi.mitv.handbook",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.mitv.handbook0.png",
"AppName": "玩机手册",
"Order": 7
},
{
"PackageName": "com.mitv.tvhome",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.mitv.tvhome0.png",
"AppName": "桌面",
"Order": 8
},
{
"PackageName": "com.xiaomi.mitv.tvmanager",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.mitv.tvmanager0.png",
"AppName": "电视管家",
"Order": 9
},
{
"PackageName": "com.xiaomi.mitv.calendar",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.mitv.calendar0.png",
"AppName": "日历",
"Order": 10
},
{
"PackageName": "com.xiaomi.voicecontrol",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.voicecontrol0.png",
"AppName": "小爱同学",
"Order": 11
},
{
"PackageName": "com.mitv.gallery",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.mitv.gallery0.png",
"AppName": "相册",
"Order": 12
},
{
"PackageName": "com.xiaomi.mitv.settings",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.mitv.settings0.png",
"AppName": "电视设置",
"Order": 13
},
{
"PackageName": "com.xiaomi.tv.gallery",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.tv.gallery0.png",
"AppName": "时尚画报",
"Order": 14
},
{
"PackageName": "com.xiaomi.mitv.smartshare",
"IconURL": "http://192.168.8.31:6095/request?action=getResource&name=com.xiaomi.mitv.smartshare0.png",
"AppName": "无线投屏",
"Order": 15
}
]
}
}

浏览器远程启动电视APP

1
2
3
4
5
6
7
http://192.168.8.31:6095/controller?action=startapp&type=packagename&packagename=com.xiaomi.tweather

{
"status": 0,
"msg": "success",
"data": null
}

通过浏览器实现按键输入

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
http://192.168.8.31:6095/controller?action=keyevent&keycode=enter

{
"status": 0,
"msg": "success",
"data": {}
}


keycode 功能
power 设备开关
up 控制光标上
down 控制光标下
left 控制光标左
right 控制光标右
enter 确认键
home 返回桌面
back 回退键
menu 打开菜单
volumeup 增加音量
volumedown 减小音量

电视机信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
shell@xmen:/ $ free
total used free shared buffers
Mem: 1703063552 1636855808 66207744 0 63692800
-/+ buffers/cache: 1573163008 129900544
Swap: 524283904 19439616 504844288
shell@xmen:/ $ cat /proc/cpuinfo
Processor : AArch64 Processor rev 4 (aarch64)
processor : 0
processor : 1
processor : 2
processor : 3
Features : fp asimd evtstrm aes pmull sha1 sha2 crc32 wp half thumb fastmult vfp edsp neon vfpv3 tlsi vfpv4 idiva idivt
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4

Hardware : Amlogic
Serial : 230c0200e8748f53c4354026985ac903
shell@xmen:/ $

电视端设置

设置-账号与安全-允许安装未知来源的应用-允许ADB调试。

设置-关于-产品型号-遥控连续按5下OK键-开启开发者模式。

设置-关于-网络信息-查看电视机IPv4网络IP。

电脑端操作

1
https://github.com/Genymobile/scrcpy
1
C:\Users\Administrator>adb connect 192.168.8.31
1
2
3
4
5
6
7
8
9
10
C:\Users\Administrator>adb device
List of devices attached
192.168.8.31:5555 unauthorized

E:\>adb install .\ESFileExplorer-cn.apk
Performing Push Install
adb: error: failed to get feature set: device unauthorized.
This adb server's $ADB_VENDOR_KEYS is not set
Try 'adb kill-server' if that seems wrong.
Otherwise check for a confirmation dialog on your device.

电视机端,遥控器操作,确认OK。

1
2
3
4
5
6
7
8
9
10
11
E:\>adb devices
List of devices attached
192.168.8.31:5555 device


E:\>adb install .\ESFileExplorer-cn.apk
Performing Push Install
.\ESFileExplorer-cn.apk: 1 file pushed, 0 skipped. 0.4 MB/s (43862869 bytes in 107.818s)
pkg: /data/local/tmp/ESFileExplorer-cn.apk
电视机端,遥控器操作,确认OK。
Success

电脑端传文件到电视机,文件名不含中文。

1
2
E:\>adb push .\CA.png /storage/3ED8CA53D8CA08DB
.\CA.png: 1 file pushed, 0 skipped. 10.4 MB/s (106863 bytes in 0.010s)

查看小米电视安卓版本

1
adb shell getprop ro.build.version.release

远程关闭“文档管理”

1
C:\Users\Administrator>adb shell am force-stop com.xiaomi.mitv.mediaexplorer

远程开启小米电视资源管理器(打开默认选中”视频“)

1
2
 C:\Users\Administrator>adb shell am start -n com.xiaomi.mitv.mediaexplorer/.NewScraperMainEntryActivity
Starting: Intent { cmp=com.xiaomi.mitv.mediaexplorer/.NewScraperMainEntryActivity }

远程开启“文档管理”应用中的“远程管理”功能(此功能通过SwiFTP 3.3.14实现,需要root权限)

1
2
3
adb root

adb shell am startservice -n com.xiaomi.mitv.mediaexplorer/com.xiaomi.mitv.media.ftp.FtpServerService

远程查看电视机U盘等外设

1
2
3
4
5
6
7
C:\Users\Administrator>adb shell ls /storage/
09BA-0F01
3ED8CA53D8CA08DB
emulated
self

adb shell ls /storage/3ED8CA53D8CA08DB

远程打开电视机U视频播放(不循环)

1
2
3
C:\Users\Administrator>adb shell am start -a android.intent.action.VIEW -d file:///storage/3ED8CA53D8CA08DB/2023年9月8日新闻.mp4 -n com.mitv.mivideoplayer/com.mitv.videoplayer.VideoPlayerActivity

Starting: Intent { act=android.intent.action.VIEW dat=file:///storage/3ED8CA53D8CA08DB/2023年9月8日新闻.mp4 cmp=com.mitv.mivideoplayer/com.mitv.videoplayer.VideoPlayerActivity }
0%