



一款基于 PyQt5 + MySQL + VLC 的全功能网络电视频道管理与播放一体化桌面应用
网络电视频道管理系统(Channel Manager Pro)是一款面向网络电视爱好者和运维管理人员的桌面级工具。它将频道数据管理与实时播放功能深度融合,打破了传统电视播放器只能"看"不能"管"的局限。用户既可以像操作数据库管理工具一样对频道分组、频道信息、播放地址进行精细化的增删改查操作,也可以一键切换到在线直播模式实时观看节目,还能打开本地媒体文件享受完整的播放器体验。系统采用多Tab页架构,每个功能模块独立运行互不干扰,数据全部从MySQL数据库动态获取,实现了真正的数据驱动。三套精心调校的主题样式让长时间使用也不觉疲劳,暗夜蓝沉稳大气、经典白清爽明朗、护眼绿温润养目,总有一款适合你的工作场景。
tv-manager/
├── tv_manager.py # 核心程序 - 管理系统GUI + 本地播放 + 在线直播
├── tv.py # 原始独立播放器(PyQt5 + VLC,可独立运行)
├── init.sql # 数据库初始化脚本(DDL + 初始数据)
└── README.md # 项目文档
# 1. 安装Python依赖
pip install PyQt5 pymysql python-vlc
# 2. 初始化数据库(修改密码后执行)
mysql -u root -p < init.sql
# 3. 编辑 tv_manager.py 中的数据库连接配置
# DB_CONFIG -> host / port / user / password / database
# 4. 启动管理系统
python tv_manager.py
数据库操作全部封装在 Database 类中,采用 pymysql 的 DictCursor 模式,查询结果直接以字典列表返回,上层无需关心SQL细节。
classDatabase:
"""MySQL数据库操作封装"""
def__init__(self, config):
self.config = config
defget_connection(self):
return pymysql.connect(**self.config, cursorclass=pymysql.cursors.DictCursor)
defexecute(self, sql, params=None):
"""执行写操作(INSERT/UPDATE/DELETE)"""
conn = self.get_connection()
try:
with conn.cursor() as cursor:
cursor.execute(sql, params)
conn.commit()
finally:
conn.close()
deffetch_all(self, sql, params=None):
"""查询多条记录"""
conn = self.get_connection()
try:
with conn.cursor() as cursor:
cursor.execute(sql, params)
return cursor.fetchall()
finally:
conn.close()
definsert(self, sql, params=None):
"""插入并返回自增ID"""
conn = self.get_connection()
try:
with conn.cursor() as cursor:
cursor.execute(sql, params)
last_id = cursor.lastrowid
conn.commit()
return last_id
finally:
conn.close()
设计要点:
%s 占位符),防止SQL注入攻击ON DELETE CASCADE,代码层无需手动清理子表本地播放器基于 python-vlc 封装,延迟初始化策略确保在未安装 VLC 时不影响其他管理功能。
def_init_vlc_player(self):
"""延迟初始化VLC播放器"""
if self.vlc_player isnotNone:
returnTrue
try:
import vlc
self.vlc_instance = vlc.Instance("--no-xlib", "--quiet")
self.vlc_player = self.vlc_instance.media_player_new()
# 将VLC视频输出绑定到Qt的Frame控件
if sys.platform == "win32":
self.vlc_player.set_hwnd(int(self.player_frame.winId()))
elif sys.platform == "darwin":
self.vlc_player.set_nsobject(int(self.player_frame.winId()))
else:
self.vlc_player.set_xwindow(int(self.player_frame.winId()))
self.vlc_player.audio_set_volume(80)
# 500ms定时器驱动进度更新
self.player_timer = QTimer()
self.player_timer.timeout.connect(self._player_update_state)
self.player_timer.start(500)
returnTrue
except Exception as e:
QMessageBox.critical(self, "VLC初始化失败", f"...")
returnFalse
播放控制功能矩阵:
set_time(current ± 5000) | ||
set_rate(speed) | ||
set_position(0~1.0) | ||
audio_get_track_description()audio_set_track() | ||
video_get_spu_description()video_set_spu() | ||
video_take_snapshot() | ||
在线直播Tab从数据库动态加载频道树,支持搜索过滤和多备用源自动切换。主题系统通过字典配置颜色方案,一键切换全部UI元素。
# 主题配置(颜色方案字典)
LIVE_THEMES = {
"暗夜蓝": {
"left_bg": "#1a1a2e", "left_title_bg": "#16213e",
"tree_bg": "#1a1a2e", "tree_fg": "#e0e0e0",
"tree_hover": "#0f3460", "tree_sel": "#e94560",
"ctrl_bg": "#16213e", "accent": "#e94560",
"video_bg": "#000", "status_fg": "#888",
},
"经典白": { ... },
"护眼绿": { ... },
}
def_live_apply_theme(self, theme_name):
"""将主题方案应用到所有UI控件"""
t = LIVE_THEMES.get(theme_name)
self.live_left.setStyleSheet(f"background:{t['left_bg']};")
self.live_tree.setStyleSheet(f"""
QTreeWidget {{ background:{t['tree_bg']}; color:{t['tree_fg']}; }}
QTreeWidget::item:hover {{ background:{t['tree_hover']}; }}
QTreeWidget::item:selected {{ background:{t['tree_sel']}; color:#fff; }}
""")
# ... 更多控件样式应用
备用源自动切换逻辑:
def_live_check_state(self):
"""每3秒检测播放状态,错误时自动切换备用源"""
state = self.live_vlc_player.get_state()
if state == vlc.State.Error:
self.live_error_count += 1
if self.live_error_count >= 2:
self.live_current_url_idx += 1
if self.live_current_url_idx < len(self.live_current_urls):
# 还有备用源,自动切换
url = self.live_current_urls[self.live_current_url_idx]
media = self.live_vlc_instance.media_new(url)
self.live_vlc_player.set_media(media)
self.live_vlc_player.play()
else:
# 所有源失败
self.live_state_label.setText("❌ 所有源均不可用")
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ channel_groups │ 1:N │ channels │ 1:N │ channel_urls │
├─────────────────┤──────>├─────────────────┤──────>├─────────────────┤
│ id (PK) │ │ id (PK) │ │ id (PK) │
│ name │ │ group_id (FK) │ │ channel_id (FK) │
│ sort_order │ │ name │ │ url │
│ created_at │ │ sort_order │ │ sort_order │
│ updated_at │ │ is_favorite │ │ is_active │
└─────────────────┘ │ created_at │ │ created_at │
└─────────────────┘ └─────────────────┘
| 合计 | 14 | 14 |
setSelectionBehavior(SelectRows) 实现整行选中setData(Qt.UserRole) 存储业务数据clicked.connect(handler) 实现事件驱动%s 占位符而非字符串拼接ON DELETE CASCADE 自动清理关联数据set_hwnd (Win) / set_nsobject (Mac) / set_xwindow (Linux)get_state() 驱动UI状态更新programs 表关联频道,展示节目时间表⭐ 如果觉得有帮助,欢迎关注公众号获取更多Python实战项目 ⭐
© 2024-2026 Python学在坚持 All Rights Reserved