windows 可以实现 字幕,时钟,全屏加载图片。
# coding=utf-8
import glob
import sys
import os
import subprocesscurrent_dir = os.path.dirname(os.path.abspath(__file__))
paths = [current_dir, current_dir + '/../']
for path in paths:sys.path.insert(0, path)os.environ['PYTHONPATH'] = (os.environ.get('PYTHONPATH', '') + ':' + path).strip(':')import sys
import os
import time
import subprocess
import threadingfrom PyQt5.QtWidgets import QApplication, QLabel, QWidget
from PyQt5.QtCore import Qt, QTimer, pyqtSignal, QObject
from PyQt5.QtGui import QFont, QPixmapfrom tool_pic.pil_resize import load_img_pathclass TransparentSubtitle(QWidget):"""透明字幕覆盖窗口(支持滚动)"""def __init__(self, text="Hello, World!", scroll=False):super().__init__()self.scroll = scrollself.full_text = textself.offset = 0 # 滚动偏移量# 窗口属性:透明、置顶、不拦截鼠标事件self.setWindowFlags(Qt.WindowType.FramelessWindowHint |Qt.WindowType.WindowStaysOnTopHint |Qt.WindowType.X11BypassWindowManagerHint)self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground, True)self.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)# 字幕标签self.label = QLabel(self)self.label.setFont(QFont("Microsoft YaHei", 28, QFont.Weight.Bold))self.label.setStyleSheet("color: yellow; background-color: rgba(0,0,0,80); padding: 5px; border-radius: 8px;")self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)# 窗口大小 & 位置(底部居中)screen = QApplication.primaryScreen().availableGeometry()self.resize(screen.width(), 80)self.move(0, screen.height() - 120)# 定时器self.timer = QTimer()self.timer.timeout.connect(self.update_subtitle)if self.scroll:self.timer.start(200) # 滚动速度else:self.set_text(self.full_text)self.show()def set_text(self, text):"""设置字幕文本"""self.full_text = textself.label.setText(text)self.label.adjustSize()self.label.move((self.width() - self.label.width()) // 2,(self.height() - self.label.height()) // 2)def update_subtitle(self):"""滚动字幕"""if self.scroll:# 截取部分文本实现滚动display_len = 20 # 显示长度show_text = self.full_text[self.offset:self.offset + display_len]if len(show_text) < display_len:# 循环拼接show_text += " " + self.full_text[:display_len - len(show_text)]self.label.setText(show_text)self.label.adjustSize()self.label.move((self.width() - self.label.width()) // 2,(self.height() - self.label.height()) // 2)self.offset = (self.offset + 1) % len(self.full_text)def show_text(self):"""外部调用:显示字幕"""self.show()def hide_text(self):"""外部调用:隐藏字幕"""self.hide()
class TransparentClock(QWidget):"""右上角透明时钟覆盖"""def __init__(self):super().__init__()self.setWindowFlags(Qt.WindowType.FramelessWindowHint |Qt.WindowType.WindowStaysOnTopHint |Qt.WindowType.Tool)self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)self.setAttribute(Qt.WidgetAttribute.WA_NoSystemBackground, True)self.setAttribute(Qt.WidgetAttribute.WA_TransparentForMouseEvents, True)self.label = QLabel(self)self.label.setFont(QFont("Helvetica", 36, QFont.Weight.Bold))self.label.setStyleSheet("color: white; background-color: rgba(0,0,0,0);")self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)self.resize(250, 100)screen = QApplication.primaryScreen().availableGeometry()self.move(screen.width() - 300, 50)self.timer = QTimer()self.timer.timeout.connect(self.update_time)self.timer.start(1000)self.update_time()self.show()def update_time(self):now = time.strftime("%H:%M:%S")self.label.setText(now)class VideoWorker(QObject):"""子线程播放视频"""finished = pyqtSignal()def __init__(self, video_path):super().__init__()self.video_path = video_pathself._should_stop = Falseself.process = Nonedef play(self):try:cmd = ['ffplay', '-i', self.video_path, '-autoexit', '-loglevel', 'quiet', '-volume', '50']cmd.append('-fs')self.process = subprocess.Popen(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE,creationflags=subprocess.CREATE_NO_WINDOW if os.name == 'nt' else 0)while not self._should_stop and self.process.poll() is None:time.sleep(0.01)if self._should_stop and self.process.poll() is None:self.process.terminate()except Exception as e:print(f"视频播放错误: {e}")finally:self.finished.emit()def stop(self):self._should_stop = Trueif self.process and self.process.poll() is None:self.process.terminate()class FullscreenCover(QWidget):"""全屏封面显示"""def __init__(self, image_path=None):super().__init__()self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.WindowStaysOnTopHint)screen = QApplication.primaryScreen().geometry()self.setGeometry(screen)self.setStyleSheet("background-color: black;")self.label = QLabel(self)self.label.setAlignment(Qt.AlignmentFlag.AlignCenter)self.label.setStyleSheet("background-color: black;")self.label.setGeometry(self.rect())if image_path and os.path.exists(image_path):pix = QPixmap(image_path)if pix.isNull():print("封面加载失败:", image_path)else:QTimer.singleShot(50, lambda: self.label.setPixmap(pix.scaled(self.label.size(), Qt.AspectRatioMode.KeepAspectRatioByExpanding)))self.show()
class VideoPlayerApp(QApplication):"""全屏视频播放器"""def __init__(self, videos, cover_path=None):super().__init__(sys.argv)self.videos = videosself.current_index = 0# 全屏封面self.cover = Noneif cover_path:self.cover = FullscreenCover(cover_path)# 时钟覆盖self.clock = TransparentClock()self.subtitle = TransparentSubtitle("这是滚动字幕示例:麒麟系统 PyQt5 全屏字幕测试", scroll=False)# 播放第一个视频self.play_next_video()def play_next_video(self):if self.current_index >= len(self.videos):print("所有视频播放完成")self.quit()returnvideo_path = self.videos[self.current_index]print("播放视频:", video_path)# Workerself.worker = VideoWorker(video_path)self.worker.finished.connect(self.on_video_finished)# 启动线程播放self.thread = threading.Thread(target=self.worker.play, daemon=True)self.thread.start()# 定时检查视频是否启动,隐藏封面self.check_timer = QTimer()self.check_timer.timeout.connect(self.check_video_started)self.check_timer.start(50)def check_video_started(self):if self.worker.process and self.worker.process.poll() is None:time.sleep(2)if self.cover:self.cover.hide()# self.check_timer.stop()def on_video_finished(self):print("视频播放结束")self.current_index += 1self.clock.hide()self.play_next_video()def stop_current_video(self):if hasattr(self, "worker") and self.worker:self.worker.stop()if self.cover:self.cover.hide()self.clock.hide()if __name__ == "__main__":cover_path = load_img_pathif sys.platform == "win32":videos = [r"C:\Users\Administrator\Videos\f7.mp4"]else:videos = ["/home/yklele/video/aa.mp4"]app = VideoPlayerApp(videos, cover_path)sys.exit(app.exec())