盲人看电视问题引发的思考:广电的卫星锅经常断信号,维护不方便(锅普遍放在房顶,卡易锁住,更新升级)。对于盲人来讲,处理这些问题,往往难度较大。爬楼顶危险性高,解锁等服务无人愿意提供,请人维修又比较费事。盲人操作电脑似乎也不太现实,为了解决这个问题,计划用废弃电脑连接电视机,将电脑变成简单的电视盒子,具备语音提示功能,使用电视遥控器即可进行节目观看。
总体思路:
将部分电视剧,电影,网页链接等资源放入电脑中指定的文件夹。利用软件配合遥控器的方式,实现普通电视类似功能。当点击遥控器时,提供节目选择窗口和对应的语音提示,程序根据遥控信号打开文件或关闭文件。
作为一个小白,使用python来实现代码部分感觉更简单,所以也就这么干了,总体感觉还好。
提示:盲人使用可删除代码中图像界面部分代码,正常人使用可删除语音提示部分代码。
注:我使用的是python3.7,IDE是:pycharm。
基本组成
软件部分:
1 主程序模块TVC_main.py:负责初始化和命令处理;
2 语音模块voice_BAT.py:负责语音合成,语音播放;
3 图像模块TVC_Window.py:负责图像显示;
4 遥控模块SerialThread.py:负责接收遥控器信号;
5 文件模块open_file_dir.py:负责文件或文件夹的具体操作;
总共包含下面7个py文件,一个图标和一个代码生成的MP3文件。
硬件部分:
电视机,电脑主机,VGA或HDMI数据线,arduino 板,1838红外接收头等。
硬件连接:电视机和电脑主机用数据线直接连,arduino板直接插入到主机USB口即可。arduino和1838的连接网上教程很多,不再赘述。
1 主程序TVC_main.py
主程序模块TVC_main.py主要就是初始化和实现命令处理循环,没有什么好解释的,其实就是一个while循环而已,看代码更容易懂,直接上代码:
import os, time, win32gui
from Command_Class import RemoteCmd
import win32api, win32con
from voice_BAT import convert_mp3, play_mp3, save_mp3
from SerialThread import get_order
from open_file_dir import play, back_dir
from pykeyboard.windows import PyKeyboard
from TVC_Window import TVCWindowThread, get_TVCHWD
# 播放MP3,如果没有就先创建,然后播放;注意区分play_voice() 和 play_mp3()函数
# 参数:1-voice文件路径;2-要搜索的文件名;3-voice文件夹的文件名列表
def play_voice(path_voice, filename, list_voice):
if filename not in list_voice:
# 首先,提醒第一个文件名为语音。该函数负责语音的寻找或生成工作。
convert_mp3(filename)
# 将生成的MP3文件保存到voice文件中
save_mp3(path_voice, filename)
print("语音合成结束!")
# 播放语音,参数是文件路径和文件名,但不包含后缀名
play_mp3(path_voice + filename)
'''
作用:实现对一个文件夹内所有的文件的读取,当用户选择某个文件时,语音提示文件名,如用户选择打开,则打开该文件。
同时具有图形界面显示,辅助选择。盲人可去掉图形界面,正常人则可去掉语音部分。
问题:语音部分暂时依靠网络环境,速度可能较慢,无网络可能不能正常运行。
'''
##############################################
# 【1】 判断两个文件路径是否正确
##############################################
# 根据自己的路径情况修改path和path_voice;
# flag:屏幕刷新标志;index:当前文件名在list中的索引;TVCHWD: 图形界面句柄;PlayHanle:播放器的句柄
lists_dict = {"path": "C:\\movie\\", "strlists": " ", "flag": 0, "index": 0, "TVCHWD": 0, "PlayHanle": 0}
last_path = [] # 路径名栈
path = lists_dict["path"]
path_voice = "C:\\voice\\"
list_voice = []
if os.path.exists(path) & os.path.exists(path_voice):
print("资源 和 voice 文件夹文件夹存在!")
else:
print("资源 或voice文件夹不存在,请确保文件夹的名字和路径正确!")
win32api.MessageBox(0, "资源 或voice文件夹不存在,请联系工作人员!", "提示信息:", win32con.MB_OK)
exit(1)
##################################################################
# 【2】 读取路径中的所有文件名到lists;加载对应的voice文件夹lists_voice
##################################################################
# 加载 资源 文件夹到list###################
if os.path.isdir(path):
lists_dict["strlists"] = os.listdir(path)
print(lists_dict["strlists"])
# 加载voice文件夹到list_voice###################
if os.path.isdir(path_voice):
list_voice = os.listdir(path_voice)
print(list_voice)
# 去掉后缀名 mp3
for index in range(len(list_voice)):
temp = list_voice[index]
# 先按照 '.'切割成多个字符串,然后取其中的第一个字符串
list_voice[index] = temp.split('.')[0]
print(list_voice)
##################################################################
# 【3】 开启图形界面线程;开启后手动对lists_dict["TVCHWD"赋值
##################################################################
TVC = TVCWindowThread(lists_dict)
TVC.start()
lists_dict["TVCHWD"] = get_TVCHWD()
win32gui.SetActiveWindow(lists_dict["TVCHWD"])
##################################################################
# 【4】 语音提示用户第一个文件名,并等待用户动作,即是打开还是选择下一个,或者返回总目录
##################################################################
'''
作用:提示当前位置文件名称;执行时先在voice文件夹搜索有没有对应的MP3,如果有直接播放
如果没有就需要调用 百度AI 来进行识别,识别的语音保存到voice文件夹,然后在播放。
'''
# 播放第一个语音############################
# 播放第一个文件的mp3文件,资料lists 是包含文件名后缀的,音频部分的list_voice是不包含后缀名的,注意区别!
play_voice(path_voice, lists_dict["strlists"][0].split('.')[0], list_voice)
#####################################################################################
# 【5】 等待用户输入,然后执行相应的动作
# ###################################################################################
# order 表示从串口接收到的遥控器的 指令编码
order = 0
cmd = RemoteCmd() # 常量对象,要用到的常量宏,遥控器不同修改该类即可
order_list = [0, 0] # 利用引用变量list来传递命令值,必须初始化为[0,0]
get_order(order_list) # 启动红外命令线程,循环读取命令,并修改order_list[1]的值
while True:
# 每次循环先读取串口传递的命令,若没有新命令等待0.1秒,循环读该命令。
# 若有命令则取出命令,并将命令参数strlist[1]恢复原始值
order = order_list[1]
if order == 0:
time.sleep(0.1)
continue
else:
order_list[1] = 0
print("当前索引:", lists_dict["index"])
if order == cmd.DOWN:
if lists_dict["index"] >= (len(lists_dict["strlists"]) - 1):
print("当前索引:", lists_dict["index"])
play_mp3(path_voice + "请向上选择")
continue
lists_dict["index"] = lists_dict["index"] + 1
# 设置窗口加框标志flag,使得窗口重绘
lists_dict["flag"] = 2
# 播放下一个文件的语音提示
temp_lists = lists_dict["strlists"]
temp_index = lists_dict["index