欢迎光临散文网 会员登陆 & 注册

自动翻译播放器源码

2023-05-30 09:24 作者:巴拉巴拉大老大  | 我要投稿



# -*- coding:utf-8 -*-

from PyQt5.Qt import pyqtSignal,QApplication,QFileDialog,QMutex,QSlider

from PyQt5.uic import loadUi

from PyQt5.QtCore import pyqtSignal,QObject,QTimer,QThread

from PyQt5.QtGui import QIcon,QPixmap,QColor

from pysubs2 import SSAFile, SSAEvent, make_time

import win32com.client as wincl

import os, platform,threading,sys,time,wave,re , pythoncom , glob

# 设置VLC库路径,需在import vlc之前

if len(sys.argv) > 1:

    os.chdir((sys.argv[0]).replace((sys.argv[0].split('\\'))[-1] , ''))

os.add_dll_directory(os.getcwd())

import vlc

ERROR = ''

qmut_1 = QMutex() # 创建线程锁

class Sound(QThread):  # 线程1

    def __init__(self,text):

        self.text = text

        super().__init__()


    def run(self):

        qmut_1.lock() # 加锁

        pythoncom.CoInitialize()

        (wincl.Dispatch("SAPI.SpVoice")).Speak(self.text)

        pythoncom.CoUninitialize()

        qmut_1.unlock() # 解锁.

class Player:

    '''

        args:设置 options

    '''


    def __init__(self, *args):

        def startplay():

            if args:

                instance = vlc.Instance(*args)

                self.media = instance.media_player_new()

            else:

                self.media = vlc.MediaPlayer()

        thread = threading.Thread(target=startplay())

        thread.start()

    # 设置待播放的url地址或本地文件路径,每次调用都会重新加载资源

    def set_uri(self, uri):

        self.media.set_mrl(uri)

    # 播放 成功返回0,失败返回-1

    def play(self, path=None):

        if path:

            self.set_uri(path)

            return self.media.play()

        else:

            return self.media.play()

    # 暂停

    def pause(self):

        self.media.pause()

    # 恢复

    def resume(self):

        self.media.set_pause(0)

    # 停止

    def stop(self):

        self.media.stop()

    # 释放资源

    def release(self):

        return self.media.release()

    # 是否正在播放

    def is_playing(self):

        return self.media.is_playing()

    # 已播放时间,返回毫秒值

    def get_time(self):

        return self.media.get_time()

    # 拖动指定的毫秒值处播放。成功返回0,失败返回-1 (需要注意,只有当前多媒体格式或流媒体协议支持才会生效)

    def set_time(self, ms):

        return self.media.set_time(ms)

    # 音视频总长度,返回毫秒值

    def get_length(self):

        return self.media.get_length()

    # 获取当前音量(0~100)

    def get_volume(self):

        return self.media.audio_get_volume()

    # 设置音量(0~100)

    def set_volume(self, volume):

        return self.media.audio_set_volume(volume)

    # 返回当前状态:正在播放;暂停中;其他

    def get_state(self):

        state = self.media.get_state()

        if state == vlc.State.Playing:

            return 1

        elif state == vlc.State.Paused:

            return 0

        else:

            return -1

    # 当前播放进度情况。返回0.0~1.0之间的浮点数

    def get_position(self):

        return self.media.get_position()

    # 拖动当前进度,传入0.0~1.0之间的浮点数(需要注意,只有当前多媒体格式或流媒体协议支持才会生效)

    def set_position(self, float_val):

        return self.media.set_position(float_val)

    # 获取当前文件播放速率

    def get_rate(self):

        return self.media.get_rate()

    # 设置播放速率(如:1.2,表示加速1.2倍播放)

    def set_rate(self, rate):

        return self.media.set_rate(rate)

    # 设置宽高比率(如"16:9","4:3")

    def set_ratio(self, ratio):

        self.media.video_set_scale(0)  # 必须设置为0,否则无法修改屏幕宽高

        self.media.video_set_aspect_ratio(ratio)

    # 设置窗口句柄

    def set_window(self, wm_id):

        if platform.system() == 'Windows':

            self.media.set_hwnd(wm_id)

        else:

            self.media.set_xwindow(wm_id)

    # 注册监听器

    def add_callback(self, event_type, callback):

        self.media.event_manager().event_attach(event_type, callback)

        print('这里是监听器')

        Stats().ui.videotime.setMaximum(self.media.get_length())

        Stats().ui.videotime.setValue(self.media.get_time())

    # 移除监听器

    def remove_callback(self, event_type, callback):

        self.media.event_manager().event_detach(event_type, callback)

class Stats:

    def __init__(self):

        # 从文件中加载UI定义 从 UI 定义中动态 创建一个相应的窗口对象 注意:里面的控件对象也成为窗口对象的属性了 比如 self.ui.button , self.ui.textEdit

        self.ui = loadUi('plugins\\UI\\main.ui')

        self.ui.setWindowIcon(QIcon('plugins\\UI\\logo.png'))

        self.path = ''

        self.loging = ''

        self.Enable = True

        self.player = Player()

        self.player.set_window(self.ui.frame.winId())

        self.tw = timework()

        self.tw.videotime.connect(self.videotime)

        self.ui.answer.setText('朗读已启用')

        self.ui.cmd.returnPressed.connect(self.playButton)

        self.ui.openButton.clicked.connect(self.openFileDialog)     #打开

        self.ui.backButton.clicked.connect(self.backButton)         #后退

        self.ui.playButton.clicked.connect(self.playButton)         #播放/暂停

        self.ui.flowordButton.clicked.connect(self.flowordButton)   #前进

        # self.ui.stopButton.setIcon(QIcon('UI\stop.png'))        #停止

        self.ui.stopButton.clicked.connect(self.stopButton)         #停止

        self.ui.sound.valueChanged.connect(self.sound)              #声音

        self.ui.videotime.sliderMoved.connect(self.videotime)    #拖动进度条同步刷新画面

        # self.ui.videotime.sliderReleased.connect(self.videotime)    #拖动进度条完毕刷新界面

        self.ui.frame.setStyleSheet("background-color: rgb(0, 0, 0);")#设置播放控件背景色

        self.ui.answer.clicked.connect(self.victostr)  # 回答问题

        self.clock_time = 0

        self.timer = QTimer()  # 生成定时器

        self.timer.start(200)

        self.File = sys.argv

        self.timetime = 0

        self.skip = 0

        self.timer.timeout.connect(self.clock)  # 绑定计时函数 self.clock

    def clock(self):

        num = self.player.get_time()        #获取播放进度

        if num < 0 :

            num = 0

        if num > 0:

            self.ui.videotime.setValue(num)     #同步进度条

            self.ui.minlcd.display(str(num//60000+100)[1:])         #显示分钟数

            self.ui.slcd.display(':' + str(num//1000%60+100)[1:])   #显示秒数

            self.playsubs(num)

    def playsubs(self , num):

        for i in self.subs:

            if (i.start) <= num <= (i.end):

                sub = i.text.replace(r'\N' , '\n')

                # if not self.is_chinese(sub):

                #     sub = self.translate(sub)

                if '\n' in sub:

                    sub = sub.split('\n')[0]

                if self.Enable and self.loging != sub:

                    print(f'进度:{str(num)}    开始时间:{str(i.start)}  结束时间:{str(i.end)}    字幕:{sub}')


                    self.ui.echoanswer.setText(sub)

                    self.loging = sub

                    self.thread_1 = Sound(sub)  # 创建线程

                    self.thread_1.start()  # 开始线程

    def victostr(self):

        if self.Enable:

            self.ui.answer.setText('朗读已禁用')

            self.Enable = False

            self.ui.echoanswer.setText('')

        else:

            self.ui.answer.setText('朗读已启用')

            self.Enable = True

    def backButton(self):                                       #后退

        self.player.set_time(self.player.get_time() - 5000)

        self.ui.videotime.setValue(self.player.get_time())

    def playButton(self):                                       #播放/暂停

        if self.path:

            if self.player.is_playing()  == 1 :

                self.player.pause()

                self.ui.playButton.setText('播放')

            else:

                self.player.resume()

                self.ui.playButton.setText('暂停')

            self.ui.videotime.setValue(self.player.get_time())

        else:

            self.openFileDialog()

    def flowordButton(self):                                    #前进

        self.player.set_time(self.player.get_time() +5000)

        self.ui.videotime.setValue(self.player.get_time())

    def stopButton(self):                                       #停止ian

        self.player.stop()

        self.ui.videotime.setValue(self.player.get_time())

    def sound(self):

        self.player.set_volume(self.ui.sound.value())

    def videotime(self):

        self.ui.cmd.setText('')

        self.player.set_time(self.ui.videotime.value())

    def initialization(self): #初始化,等待接收文件

        pass

    def openFile(self):#类型关联打开文件

        self.getsubs(self.File[1])

    def timehandle(self,timestr):

        if ':' in timestr:

            stoptime =timestr.split(':')

            second = float((stoptime)[0]) * 60 + float((stoptime)[1])  # 获得暂停时间

        else:

            second = float(timestr)

        return second

    def openFileDialog(self):#打开文件

        # 生成文件对话框对象

        dialog = QFileDialog()

        # 设置文件过滤器,这里是任何文件,包括目录噢

        dialog.setFileMode(QFileDialog.AnyFile)

        # 设置显示文件的模式,这里是详细模式

        dialog.setViewMode(QFileDialog.Detail)

        if dialog.exec_():

            fileNames = dialog.selectedFiles()

            self.getsubs(fileNames[0])

    def getsubs(self , path = ''):

        self.path = path

        self.ui.setWindowTitle(path)#将路径显示到标题栏上

        self.player.play(path)

        self.ui.playButton.setText('暂停')

        time.sleep(0.1)

        self.ui.sound.setValue(self.player.get_volume())

        self.ui.videotime.setMaximum(self.player.get_length())

        self.ui.videotime.setValue(self.player.get_time())

        P = os.path.dirname(path)

        if subpath := glob.glob(f'{P}/*.srt'):

            self.subs = SSAFile.load(subpath[0])

        elif subpath := glob.glob(f'{P}/*.ass'):

            self.subs = SSAFile.load(subpath[0])

        elif subpath := glob.glob(f'{P}/*.ssa'):

            self.subs = SSAFile.load(subpath[0])

class timework(QObject):

    videotime = pyqtSignal(QSlider,int)

app = QApplication([])

stats = Stats()

stats.ui.show()

stats.initialization()

sys.exit(app.exec_())


自动翻译播放器源码的评论 (共 条)

分享到微博请遵守国家法律