コード例 #1
0
    def __init__(self,
                 id,
                 volume,
                 cacheFolder,
                 top=False,
                 title='',
                 resize=[],
                 textSetting=[True, 20, 2, 6, 0, '【 [ {'],
                 maxCacheSize=2048000,
                 startWithDanmu=True):
        super(VideoWidget, self).__init__()
        self.setAcceptDrops(True)
        self.installEventFilter(self)
        self.id = id
        self.title = '未定义的直播间'
        self.uname = '未定义'
        self.hoverToken = False
        self.roomID = '0'  # 初始化直播间房号
        self.liveStatus = 0  # 初始化直播状态为0
        self.pauseToken = False
        self.quality = 250
        self.audioChannel = 0  # 0 原始音效  5 杜比音效
        self.volume = volume
        self.volumeAmplify = 1.0  # 音量加倍
        self.hardwareDecode = True
        self.leftButtonPress = False
        self.rightButtonPress = False
        self.fullScreen = False
        self.userPause = False  # 用户暂停
        self.cacheName = ''
        self.maxCacheSize = maxCacheSize
        self.startWithDanmu = startWithDanmu
        self.setFrameShape(QFrame.Box)
        self.setObjectName('video')

        self.top = top
        if top:  # 悬浮窗取消关闭按钮 vlc版点关闭后有bug 让用户右键退出
            self.setWindowFlags(Qt.CustomizeWindowHint
                                | Qt.WindowMinimizeButtonHint
                                | Qt.WindowMaximizeButtonHint)
        else:
            self.setStyleSheet(
                '#video{border-width:1px;border-style:solid;border-color:gray}'
            )
        self.textSetting = textSetting
        self.horiPercent = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
                            1.0][self.textSetting[2]]
        self.vertPercent = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
                            1.0][self.textSetting[3]]
        self.filters = textSetting[5].split(' ')
        self.opacity = 100
        if top:
            self.setWindowFlag(Qt.WindowStaysOnTopHint)
        if title:
            if top:
                self.setWindowTitle('%s %s' % (title, id + 1 - 9))
            else:
                self.setWindowTitle('%s %s' % (title, id + 1))
        if resize:
            self.resize(resize[0], resize[1])
        layout = QGridLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        self.textBrowser = TextBrowser(
            self)  # 必须赶在resizeEvent和moveEvent之前初始化textbrowser
        self.setDanmuOpacity(self.textSetting[1])  # 设置弹幕透明度
        self.textBrowser.optionWidget.opacitySlider.setValue(
            self.textSetting[1])  # 设置选项页透明条
        self.textBrowser.optionWidget.opacitySlider.value.connect(
            self.setDanmuOpacity)
        self.setHorizontalPercent(self.textSetting[2])  # 设置横向占比
        self.textBrowser.optionWidget.horizontalCombobox.setCurrentIndex(
            self.textSetting[2])  # 设置选项页占比框
        self.textBrowser.optionWidget.horizontalCombobox.currentIndexChanged.connect(
            self.setHorizontalPercent)
        self.setVerticalPercent(self.textSetting[3])  # 设置横向占比
        self.textBrowser.optionWidget.verticalCombobox.setCurrentIndex(
            self.textSetting[3])  # 设置选项页占比框
        self.textBrowser.optionWidget.verticalCombobox.currentIndexChanged.connect(
            self.setVerticalPercent)
        self.setTranslateBrowser(self.textSetting[4])
        self.textBrowser.optionWidget.translateCombobox.setCurrentIndex(
            self.textSetting[4])  # 设置同传窗口
        self.textBrowser.optionWidget.translateCombobox.currentIndexChanged.connect(
            self.setTranslateBrowser)
        self.setTranslateFilter(self.textSetting[5])  # 同传过滤字符
        self.textBrowser.optionWidget.translateFitler.setText(
            self.textSetting[5])
        self.textBrowser.optionWidget.translateFitler.textChanged.connect(
            self.setTranslateFilter)
        self.textBrowser.closeSignal.connect(self.closeDanmu)
        self.textBrowser.moveSignal.connect(self.moveTextBrowser)
        if not self.startWithDanmu:  # 如果启动隐藏被设置,隐藏弹幕机
            self.textSetting[0] = False
            self.textBrowser.hide()

        self.textPosDelta = QPoint(0, 0)  # 弹幕框和窗口之间的坐标差

        self.videoFrame = VideoFrame()  # 新版本vlc内核播放器
        self.videoFrame.rightClicked.connect(self.rightMouseClicked)
        self.videoFrame.leftClicked.connect(self.leftMouseClicked)
        self.videoFrame.doubleClicked.connect(self.doubleClick)
        layout.addWidget(self.videoFrame, 0, 0, 12, 12)
        self.instance = vlc.Instance()
        self.player = self.instance.media_player_new()  # 视频播放
        self.player.video_set_mouse_input(False)
        self.player.video_set_key_input(False)
        if platform.system() == 'Windows':
            self.player.set_hwnd(self.videoFrame.winId())
        elif platform.system() == 'Darwin':  # for MacOS
            self.player.set_nsobject(int(self.videoFrame.winId()))
        else:
            self.player.set_xwindow(self.videoFrame.winId())

        self.topLabel = QLabel()
        self.topLabel.setFixedHeight(30)
        # self.topLabel.setAlignment(Qt.AlignCenter)
        self.topLabel.setObjectName('frame')
        self.topLabel.setStyleSheet("background-color:#293038")
        # self.topLabel.setFixedHeight(32)
        self.topLabel.setFont(QFont('微软雅黑', 15, QFont.Bold))
        layout.addWidget(self.topLabel, 0, 0, 1, 12)
        self.topLabel.hide()

        self.frame = QWidget()
        self.frame.setObjectName('frame')
        self.frame.setStyleSheet("background-color:#293038")
        self.frame.setFixedHeight(50)
        frameLayout = QHBoxLayout(self.frame)
        frameLayout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.frame, 11, 0, 1, 12)
        self.frame.hide()

        self.titleLabel = QLabel()
        self.titleLabel.setMaximumWidth(150)
        self.titleLabel.setStyleSheet('background-color:#00000000')
        self.setTitle()
        frameLayout.addWidget(self.titleLabel)
        self.play = PushButton(self.style().standardIcon(QStyle.SP_MediaPause))
        self.play.clicked.connect(self.mediaPlay)
        frameLayout.addWidget(self.play)
        self.reload = PushButton(self.style().standardIcon(
            QStyle.SP_BrowserReload))
        self.reload.clicked.connect(self.mediaReload)
        frameLayout.addWidget(self.reload)
        self.volumeButton = PushButton(self.style().standardIcon(
            QStyle.SP_MediaVolume))
        self.volumeButton.clicked.connect(self.mediaMute)
        frameLayout.addWidget(self.volumeButton)
        self.slider = Slider()
        self.slider.setStyleSheet('background-color:#00000000')
        self.slider.value.connect(self.setVolume)
        frameLayout.addWidget(self.slider)
        self.danmuButton = PushButton(text='弹')
        self.danmuButton.clicked.connect(self.showDanmu)
        frameLayout.addWidget(self.danmuButton)
        self.stop = PushButton(self.style().standardIcon(
            QStyle.SP_DialogCancelButton))
        self.stop.clicked.connect(self.mediaStop)
        frameLayout.addWidget(self.stop)

        self.getMediaURL = GetMediaURL(self.id, cacheFolder, maxCacheSize)
        self.getMediaURL.cacheName.connect(self.setMedia)
        self.getMediaURL.downloadError.connect(self.mediaReload)

        self.danmu = remoteThread(self.roomID)

        self.exportCache = ExportCache()
        self.exportCache.finish.connect(self.exportFinish)
        self.exportTip = ExportTip()

        self.moveTimer = QTimer()
        self.moveTimer.timeout.connect(self.initTextPos)
        self.moveTimer.start(50)

        self.checkPlaying = QTimer()  # 检查播放卡住的定时器
        self.checkPlaying.timeout.connect(self.checkPlayStatus)
        logging.info("VLC 播放器构造完毕, 缓存大小: %dkb , 置顶?: %s, 启用弹幕?: %s" %
                     (self.maxCacheSize, self.top, self.startWithDanmu))
コード例 #2
0
    def __init__(self,
                 id,
                 volume,
                 cacheFolder,
                 top=False,
                 title='',
                 resize=[],
                 textSetting=[True, 20, 2, 6, 0, '【 [ {', 10],
                 maxCacheSize=2048000,
                 saveCachePath='',
                 startWithDanmu=True,
                 hardwareDecode=True):
        super(VideoWidget, self).__init__()
        self.setAcceptDrops(True)
        self.installEventFilter(self)
        self.id = id
        self.title = ''
        self.uname = ''
        self.oldTitle = ''
        self.oldUname = ''
        self.hoverToken = False
        self.roomID = '0'  # 初始化直播间房号
        self.liveStatus = 0  # 初始化直播状态为0
        self.pauseToken = False
        self.quality = 250
        self.audioChannel = 0  # 0 原始音效  5 杜比音效
        self.volume = volume
        self.volumeAmplify = 1.0  # 音量加倍
        self.muted = False
        self.hardwareDecode = hardwareDecode
        self.leftButtonPress = False
        self.rightButtonPress = False
        self.fullScreen = False
        self.userPause = False  # 用户暂停
        self.cacheName = ''
        self.maxCacheSize = maxCacheSize
        self.saveCachePath = saveCachePath
        self.startWithDanmu = startWithDanmu

        # 容器设置
        self.setFrameShape(QFrame.Box)
        self.setObjectName('video')

        self.top = top
        self.name_str = f"悬浮窗{self.id}" if self.top else f"嵌入窗{self.id}"
        if top:
            self.setWindowFlags(Qt.Window)
        else:
            self.setStyleSheet(
                '#video{border-width:1px;border-style:solid;border-color:gray}'
            )
        self.textSetting = textSetting
        self.horiPercent = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
                            1.0][self.textSetting[2]]
        self.vertPercent = [0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9,
                            1.0][self.textSetting[3]]
        self.filters = textSetting[5].split(' ')
        self.opacity = 100
        if top:
            self.setWindowFlag(Qt.WindowStaysOnTopHint)
        if title:
            if top:
                self.setWindowTitle('%s %s' % (title, id + 1 - 9))
            else:
                self.setWindowTitle('%s %s' % (title, id + 1))

        layout = QGridLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)

        # ---- 弹幕机 ----
        self.textBrowser = TextBrowser(
            self)  # 必须赶在resizeEvent和moveEvent之前初始化textbrowser
        self.setDanmuOpacity(self.textSetting[1])  # 设置弹幕透明度
        self.textBrowser.optionWidget.opacitySlider.setValue(
            self.textSetting[1])  # 设置选项页透明条
        self.textBrowser.optionWidget.opacitySlider.value.connect(
            self.setDanmuOpacity)
        self.setHorizontalPercent(self.textSetting[2])  # 设置横向占比
        self.textBrowser.optionWidget.horizontalCombobox.setCurrentIndex(
            self.textSetting[2])  # 设置选项页占比框
        self.textBrowser.optionWidget.horizontalCombobox.currentIndexChanged.connect(
            self.setHorizontalPercent)
        self.setVerticalPercent(self.textSetting[3])  # 设置横向占比
        self.textBrowser.optionWidget.verticalCombobox.setCurrentIndex(
            self.textSetting[3])  # 设置选项页占比框
        self.textBrowser.optionWidget.verticalCombobox.currentIndexChanged.connect(
            self.setVerticalPercent)
        self.setTranslateBrowser(self.textSetting[4])
        self.textBrowser.optionWidget.translateCombobox.setCurrentIndex(
            self.textSetting[4])  # 设置同传窗口
        self.textBrowser.optionWidget.translateCombobox.currentIndexChanged.connect(
            self.setTranslateBrowser)
        self.setTranslateFilter(self.textSetting[5])  # 同传过滤字符
        self.textBrowser.optionWidget.translateFitler.setText(
            self.textSetting[5])
        self.textBrowser.optionWidget.translateFitler.textChanged.connect(
            self.setTranslateFilter)
        self.setFontSize(self.textSetting[6])  # 设置弹幕字体大小
        self.textBrowser.optionWidget.fontSizeCombox.setCurrentIndex(
            self.textSetting[6])
        self.textBrowser.optionWidget.fontSizeCombox.currentIndexChanged.connect(
            self.setFontSize)

        self.textBrowser.closeSignal.connect(self.closeDanmu)
        self.textBrowser.moveSignal.connect(self.moveTextBrowser)
        if not self.startWithDanmu:  # 如果启动隐藏被设置,隐藏弹幕机
            self.textSetting[0] = False
            self.textBrowser.hide()

        self.textPosDelta = QPoint(0, 0)  # 弹幕框和窗口之间的坐标差
        self.deltaX = 0
        self.deltaY = 0

        # ---- 播放器布局设置 ----
        # 播放器
        self.videoFrame = VideoFrame()  # 新版本vlc内核播放器
        self.videoFrame.rightClicked.connect(self.rightMouseClicked)
        self.videoFrame.leftClicked.connect(self.leftMouseClicked)
        self.videoFrame.doubleClicked.connect(self.doubleClick)
        layout.addWidget(self.videoFrame, 0, 0, 12, 12)
        # vlc 实例
        self.instance = vlc.Instance()
        self.newPlayer()  # 实例化 player

        # 直播间标题
        self.topLabel = QLabel()
        self.topLabel.setFixedHeight(30)
        # self.topLabel.setAlignment(Qt.AlignCenter)
        self.topLabel.setObjectName('frame')
        self.topLabel.setStyleSheet("background-color:#293038")
        # self.topLabel.setFixedHeight(32)
        self.topLabel.setFont(QFont('微软雅黑', 15, QFont.Bold))
        layout.addWidget(self.topLabel, 0, 0, 1, 12)
        self.topLabel.hide()

        # 控制栏容器
        self.frame = QWidget()
        self.frame.setObjectName('frame')
        self.frame.setStyleSheet("background-color:#293038")
        self.frame.setFixedHeight(50)
        frameLayout = QHBoxLayout(self.frame)
        frameLayout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.frame, 11, 0, 1, 12)
        self.frame.hide()

        # ---- 嵌入式播放器 控制栏 ----
        # 主播名
        self.titleLabel = QLabel()
        self.titleLabel.setMaximumWidth(150)
        self.titleLabel.setStyleSheet('background-color:#00000000')
        self.setTitle()
        frameLayout.addWidget(self.titleLabel)
        # 播放/暂停
        self.play = PushButton(self.style().standardIcon(QStyle.SP_MediaPause))
        self.play.clicked.connect(self.mediaPlay)
        frameLayout.addWidget(self.play)
        # 刷新
        self.reload = PushButton(self.style().standardIcon(
            QStyle.SP_BrowserReload))
        self.reload.clicked.connect(self.mediaReload)
        frameLayout.addWidget(self.reload)
        # 音量开关
        self.volumeButton = PushButton(self.style().standardIcon(
            QStyle.SP_MediaVolume))
        self.volumeButton.clicked.connect(self.mediaMute)
        frameLayout.addWidget(self.volumeButton)
        # 音量滑条
        self.slider = Slider()
        self.slider.setStyleSheet('background-color:#00000000')
        self.slider.value.connect(self.setVolume)
        frameLayout.addWidget(self.slider)
        # 弹幕开关
        self.danmuButton = PushButton(text='弹')
        self.danmuButton.clicked.connect(self.showDanmu)
        frameLayout.addWidget(self.danmuButton)
        # 关闭窗口
        self.stop = PushButton(self.style().standardIcon(
            QStyle.SP_DialogCancelButton))
        self.stop.clicked.connect(self.mediaStop)
        frameLayout.addWidget(self.stop)

        # ---- IO 交互设置 ----
        # 单开线程获取视频流
        self.getMediaURL = GetMediaURL(self.id, cacheFolder, maxCacheSize,
                                       saveCachePath)
        self.getMediaURL.cacheName.connect(self.setMedia)
        self.getMediaURL.copyFile.connect(self.copyCache)
        self.getMediaURL.downloadError.connect(self.mediaReload)

        self.danmu = remoteThread(self.roomID)

        # 导出配置
        self.exportCache = ExportCache()
        self.exportCache.finish.connect(self.exportFinish)
        self.exportTip = ExportTip()

        # ---- 定时器 ----
        # 弹幕机位置匹配
        self.moveTimer = QTimer()
        self.moveTimer.timeout.connect(self.initTextPos)
        self.moveTimer.start(50)

        # 检查播放卡住的定时器
        self.checkPlaying = QTimer()
        self.checkPlaying.timeout.connect(self.checkPlayStatus)

        # 最后再 resize 避免有变量尚未初始化
        if resize:
            self.resize(resize[0], resize[1])
        logging.info(
            f"{self.name_str} VLC 播放器构造完毕, 缓存大小: %dkb, 缓存路径: %s, 置顶?: %s, 启用弹幕?: %s"
            % (self.maxCacheSize, self.saveCachePath, self.top,
               self.startWithDanmu))

        self.audioTimer = QTimer()
        self.audioTimer.timeout.connect(self.checkAudio)
        self.audioTimer.setInterval(100)