update changelog
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 196 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 276 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 126 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 36 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 29 KiB |
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 49 KiB |
Before Width: | Height: | Size: 191 KiB After Width: | Height: | Size: 64 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 41 KiB |
After Width: | Height: | Size: 94 KiB |
After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 461 KiB After Width: | Height: | Size: 360 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 364 KiB |
Before Width: | Height: | Size: 93 KiB After Width: | Height: | Size: 397 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 739 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 740 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 749 KiB |
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 676 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 35 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 4.4 KiB |
After Width: | Height: | Size: 487 B |
After Width: | Height: | Size: 794 B |
After Width: | Height: | Size: 738 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 412 B |
After Width: | Height: | Size: 396 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 502 B |
After Width: | Height: | Size: 711 B |
After Width: | Height: | Size: 388 B |
After Width: | Height: | Size: 676 B |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 5.5 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 10 KiB |
|
@ -1,174 +1,147 @@
|
|||
# 影音
|
||||
## 概 述
|
||||
影音是一款界面美观,互动性好的一款音视频播放器,它基于qt5开发,使用mpv作为播放引擎。影音支持几乎所有格式的音频和视频,具有强大的解码能力。影音还有迷你模式以满足不同的播放需求。
|
||||
影音是一款界面美观,互动性友好的音视频播放器,支持.mkv、.avi、.mp4、 .mp3、.wmv等主流音视频格式,具有强大的解码能力;功能齐全,支持播放顺序设置、屏幕截图、字幕载入、画面设置、添加文件书签、无痕播放等,还可以设
|
||||
置迷你播放窗口以满足不同的播放需求。<br>
|
||||
![图 1 影音-big](image/1.png)
|
||||
|
||||
<br>
|
||||
|
||||
## 主界面
|
||||
## 打开方式
|
||||
● “开始菜单”![](image/icon1.png)>“影音”![](image/icon2.png);<br>
|
||||
● 选中视频文件 > 双击 > 默认打开“影音”![](image/icon2.png);<br>
|
||||
● 选中音视频文件 > 右键单击 > “打开方式”>“影音”![](image/icon2.png);<br>
|
||||
● “任务栏”>“搜索”![](image/icon3.png)>“影音”![](image/icon2.png)> 选择“打开”。<br>
|
||||
|
||||
<br>
|
||||
|
||||
主界面功能简洁,如下图所示。
|
||||
## 基本操作
|
||||
|
||||
<br>
|
||||
|
||||
![图 1 主界面-big](image/1.png)
|
||||
### 播放界面
|
||||
打开影音后,点击“打开文件”或“打开文件夹”或使用组合键“Ctrl”+“O”/“Ctrl”+“F”打开文件或文件夹,选择音视频文件后可直接进行播放,并将文件添加到右侧可伸缩的播放列表中。双击播放界面可以放大窗口至全屏播放,再次双击可退出全屏。光标在播放界面无停留时,界面简洁,只保留视频播放窗口。<br>
|
||||
![图 2 播放界面-光标无停留-big](image/2.png)
|
||||
|
||||
<br>
|
||||
|
||||
主界面主要有打开文件和打开文件夹两个功能,在主界面中也可以点击右侧列表按钮弹出播放列表。
|
||||
光标停留在视频播放界面时,显示当前播放文件的文件名,同时呼出播放栏、播放列表按钮和操作栏。<br>
|
||||
界面顶部为操作栏,可以执行的操作有:打开菜单栏,开启迷你模式,最小化/最大化窗口、关闭应用。<br>
|
||||
播放栏悬浮于界面底部,可以执行的操作有:开始/暂停/切换视频、选择播放进度、设置倍速、调节音量、截图、添加书签、设置全屏,详细功能说明请见播放栏功能说明表。<br>
|
||||
![图 3 播放界面-光标停留-big](image/3.png)
|
||||
|
||||
<br>
|
||||
|
||||
## 播放界面
|
||||
在播放界面中单击右键可以打开播放界面的右键菜单栏,可选择打开文件、打开文件夹,所在文件夹、置顶,可以设置播放顺序(单个循环、列表循环、随机播放),画面(顺时针/逆时针旋转90°、水平/垂直翻转、画面还原、显示简介),声音(音轨、声道、音频设置),字幕(载入字幕、字幕选择、字幕设置),播放(播放/暂停、升高/降低音量、快进/快退),还可以打开播放器设置,查看媒体信息。<br>
|
||||
![图 4 播放界面右键菜单栏-big](image/4.png)
|
||||
|
||||
<br>
|
||||
|
||||
播放界面简洁,只保留了播放列表展开按钮。
|
||||
表1 播放界面右键菜单栏<br>
|
||||
|
||||
| 一级菜单 | 二级菜单 | 描述 |
|
||||
| :----: | :----: | :---- |
|
||||
| 打开文件 | | 打开文件选择 |
|
||||
| 打开文件夹 | |打开文件选择 |
|
||||
| 播放顺序|单个循环|循环播放单个视频 |
|
||||
| | 列表循环 | 循环播放列表中的视频 |
|
||||
| | 随机播放 | 随机播放列表中的视频 |
|
||||
| 画面 | 默认 | 默认的原始比例 |
|
||||
| | 4:3 | 画面比例4:3 |
|
||||
| | 16:9 | 画面比例16:9 |
|
||||
| | 满屏 | 画面比例塞满整个屏幕 |
|
||||
| | 画面还原 | 还原至默认的原始画面 |
|
||||
| | 顺时针旋转90° | 画面顺时针旋转90° |
|
||||
| | 逆时针旋转90° | 画面逆时针旋转90° |
|
||||
| | 水平翻转 | 画面水平翻转 |
|
||||
| | 垂直翻转 | 画面垂直翻转 |
|
||||
| | 显示简介 | 画面中显示文件简介,包括文件名、分辨率、fps、比特率、音频、采样率、声道、比特率、音视频同步差 |
|
||||
| 声音 | 音轨 | 保存现有画板的图像内容 |
|
||||
| | 音道 | 立声道、左声道、右声道 |
|
||||
| | 声音设置 | 打开声音设置菜单栏,设置音频 |
|
||||
| 字幕 | 载入字幕 | 载入视频字幕 |
|
||||
| | 字幕选择 | 选择视频字幕 |
|
||||
| | 字幕设置 | 打开字幕设置 |
|
||||
| 播放 | 播放/暂停|播放/暂停视频,可使用键盘空格键快捷操作 |
|
||||
| | 升高/降低音量 | 升高/降低音量,可使用键盘“Up”/“Down”键快速操作 |
|
||||
| | 快进/快退 | 快进/快退音视频进度 |
|
||||
| 播放器设置 | 播放设置 | 打开播放设置 |
|
||||
| 媒体信息 | | 打文件信息,查看文件名、文件类型、文件大小、文件时长和文件位置 |
|
||||
|
||||
<br>
|
||||
|
||||
![图 2 播放界面-big](image/2.png)
|
||||
### 播放栏
|
||||
播放栏放置于影音界面底部,在观看视频时可避免鼠标与视频界面交叉,提升您的体验感,影音播放栏功能栏说明如下表所示。<br>
|
||||
表2 影音播放栏功能说明
|
||||
|
||||
| 图标 | 功能 | 描述 |
|
||||
| :----: | :----: | :---- |
|
||||
| ![](image/icon4.png) | 上一个 | 切换到播放列表中的上一个部 |
|
||||
| ![](image/icon5.png) | 下一个 | 切换到播放列表中的下一步 |
|
||||
| ![](image/icon6.png) | 开始播放 | 开始播放当前视频 |
|
||||
| ![](image/icon7.png) | 暂停播放 | 开始播放当前视频 |
|
||||
| ![](image/icon8.png) | 进度条 | 显示当前播放进度,可以拖动进度条按钮调整进度 |
|
||||
| ![](image/icon9.png) | 时长 | 显示当前时长/总时长 |
|
||||
| ![](image/icon10.png) | 音量 | 调整音量大小 |
|
||||
| ![](image/icon11.png) | 倍速 | 设置倍速播放,可选择的速度:0.5X、0.75、1.0X、1.25X、1.5X、2.0X |
|
||||
| ![](image/icon12.png) | 工具箱 | 对当前播放的界面截图、添加书签,截图默认保存至“图片”文件夹中。 |
|
||||
| ![](image/icon13.png) | 全屏 | 全屏播放 |
|
||||
|
||||
<br>
|
||||
|
||||
播放界面主要功能:单击暂停播放,双击全屏和取消全屏,右击呼出右键菜单,鼠标移动呼出标题栏和控制面板。
|
||||
光标指在进度条中的任一处可显示该进度处的画面缩略图及时长,拖动进度即可调整当前的播放进度。<br>
|
||||
![图 5 播放进度条-big](image/5.png)
|
||||
|
||||
<br>
|
||||
|
||||
## 控制面板
|
||||
### 播放列表
|
||||
点击播放界面右侧的按钮即可展开播放列表,播放列表中“视频”界面展示已添加的音视频文件,“书签”页面展示已添加书签的文件。双击播放列表中的任一文件即可开始播放。点击播放列表中的“![](image/icon22.png)”可以添加文件,点击“![](image/icon14.png)”可清除列表中所有文件,选中播放别表中的任一文件,点击文件右侧的“×”即可删除列表中的该文件。<br>
|
||||
播放列表提供“单个循环”、“列表循环”、“随机播放”三种播放顺序,选择对应的图标即可切换:“![](image/icon15.png)”,“![](image/icon16.png)”,“![](image/icon17.png)”。<br>
|
||||
播放列表还提供文件的列表视图和缩略图视图两种视图方式,对应播放列表顶部的图标分别为“![](image/icon18.png)”和“![](image/icon19.png)”。<br>
|
||||
![图 6 播放列表-列表视图-big](image/6.png)
|
||||
![图 7 播放列表-缩略图视图-big](image/7.png)
|
||||
|
||||
<br>
|
||||
|
||||
控制面板在播放界面悬浮显示,半透明样式减少控制面板对视频的遮挡。
|
||||
选中播放别表中的任一文件单击右键可以打开播放列表的右键菜单栏,可选择移除选中项,移除无效文件、清空播放列表、打开文件所在文件夹。<br>
|
||||
![图 8 播放列表右键菜单栏-big](image/8.png)
|
||||
|
||||
<br>
|
||||
|
||||
![图 3 控制面板-big](image/3.png)
|
||||
### 菜单栏
|
||||
点击界面右上角“![](image/icon20.png)”可打开影音菜单栏,菜单栏功能说明如下表所示。<br>
|
||||
表3 影音菜单栏功能说明
|
||||
|
||||
| 一级菜单 | 二级菜单 | 描述 |
|
||||
| :----: | :----: | :---- |
|
||||
| 隐私 | 清理痕迹 | 清理文件播放记录 |
|
||||
| | 无痕播放 | 无记录播放文件 |
|
||||
| 帮助 | 帮助手册 | 连接到用户手册,选择“影音”打开手册 |
|
||||
| | 意见反馈 | 反馈相关意见 |
|
||||
| | 官方网站 | 链接到麒麟软件官方网站 |
|
||||
| 关于 | | 影音版本信息 |
|
||||
| 设置 | 系统 | 设置是否最小化到系统托盘、最小化时暂停视频播放及睡眠、休眠、锁屏唤醒之后保持播放状态。 |
|
||||
| | 播放 | 设置退出时是否清空播放列表、自动从文件上次停止的位置播放。 |
|
||||
| | 截图 | 截图保存的路径、格式 |
|
||||
| | 字幕 | 是否自动载入同名字幕,设置指定路径、字幕字体样式。 |
|
||||
| | 音频 | 设置输出驱动 |
|
||||
| | 解码器 | 设置视频输出驱动、视频解码器、解码线程 |
|
||||
| | 字幕 | 加载字幕文件,字幕编码格式,是否自动检测语言。 |
|
||||
| | 快捷键 | 设置按钮功能快捷键 |
|
||||
|
||||
<br>
|
||||
|
||||
控制面板主要功能:上一个下一个切换,暂停播放控制,进度控制,音量设置,倍速播放,截图和全屏。
|
||||
![图 9 影音设置-big](image/12.png)
|
||||
|
||||
<br>
|
||||
|
||||
## 播放列表
|
||||
### 迷你模式
|
||||
点击播放界面顶部的“![](image/icon21.png)”,可以缩小播放界面至更精简的迷你播放模式,方便在桌面进行其他操作。光标离开迷你播放窗口的显示界面如下图所示:
|
||||
|
||||
<br>
|
||||
|
||||
播放列表支持列表模式(左)和预览模式(右)。
|
||||
![图 10 迷你模式-光标无停留-big](image/13.png)
|
||||
|
||||
<br>
|
||||
|
||||
![图 4 播放列表-big](image/4.png)
|
||||
|
||||
<br>
|
||||
|
||||
播放列表主要功能:双击播放,单条删除,删除无效文件,清空列表,播放顺序设置,显示模式切换。
|
||||
|
||||
<br>
|
||||
|
||||
## 设置
|
||||
|
||||
<br>
|
||||
|
||||
设置界面主要包括系统设置,播放设置,截图设置,字幕设置,音频设置,解码器设置和快捷键设置
|
||||
|
||||
<br>
|
||||
|
||||
### 系统设置
|
||||
|
||||
<br>
|
||||
|
||||
系统设置支持设置项:最小化到系统托盘,最小化暂停,休眠/睡眠暂停。
|
||||
|
||||
<br>
|
||||
|
||||
![图 5 系统设置-big](image/5.png)
|
||||
|
||||
<br>
|
||||
|
||||
### 播放设置
|
||||
|
||||
<br>
|
||||
|
||||
播放设置支持设置项:播放时自动全屏,退出时清空播放列表,从上次停止的位置继续播放。
|
||||
|
||||
<br>
|
||||
|
||||
![图 6 播放设置-big](image/6.png)
|
||||
|
||||
<br>
|
||||
|
||||
### 截图设置
|
||||
|
||||
<br>
|
||||
|
||||
截图设置支持设置项:截图文件夹,截图格式。
|
||||
|
||||
<br>
|
||||
|
||||
![图 7 截图设置-big](image/7.png)
|
||||
|
||||
<br>
|
||||
|
||||
### 字幕设置
|
||||
|
||||
<br>
|
||||
|
||||
字幕设置支持设置项:加载同名字幕,加载文件夹下所有字幕,字幕默认文件夹,字幕字体。
|
||||
|
||||
<br>
|
||||
|
||||
![图 8 字幕设置-big](image/8.png)
|
||||
|
||||
<br>
|
||||
|
||||
### 音频设置
|
||||
|
||||
<br>
|
||||
|
||||
音频设置支持设置项:输出驱动选择。
|
||||
|
||||
<br>
|
||||
|
||||
![图 9 音频设置-big](image/9.png)
|
||||
|
||||
<br>
|
||||
|
||||
### 解码器设置
|
||||
|
||||
<br>
|
||||
|
||||
解码器设置支持设置项:视频解码器选择。
|
||||
|
||||
<br>
|
||||
|
||||
![图 10 解码器设置-big](image/10.png)
|
||||
|
||||
<br>
|
||||
|
||||
### 快捷键设置
|
||||
|
||||
<br>
|
||||
|
||||
快捷键设置支持设置项:快捷键自定义。
|
||||
|
||||
<br>
|
||||
|
||||
![图 11 快捷键设置-big](image/11.png)
|
||||
|
||||
<br>
|
||||
|
||||
## 迷你模式
|
||||
|
||||
<br>
|
||||
|
||||
为了更好的体验您可以切换为Mini模式。
|
||||
|
||||
<br>
|
||||
|
||||
![图 12 迷你模式](image/12.png)
|
||||
|
||||
<br>
|
||||
![图 11 迷你模式-光标停留-big](image/14.png)
|
||||
|
||||
|
|
|
@ -1,3 +1,25 @@
|
|||
kylin-video (3.1.4.2k1-ok16) yangtze; urgency=medium
|
||||
|
||||
* BUG号:
|
||||
# 137299【wayland】【影音】播放视频时鼠标悬停在进度条或拖动进度条,在左上角显示进度条缩略图和时间
|
||||
* 需求号:无.
|
||||
* 其他改动:无.
|
||||
|
||||
-- liucong <liucong1@kylinos.cn> Tue, 23 May 2023 20:17:21 +0800
|
||||
|
||||
kylin-video (3.1.4.2k1-ok15) yangtze; urgency=medium
|
||||
|
||||
* BUG号:
|
||||
# I5XM2I 【影音】wayland模式下和X模式下,影音的最大化最小化按钮功能失效
|
||||
# I64PJ2 【影音】【次要】清空列表时的确认弹窗出现位置不固定
|
||||
# I64P19 【影音】【次要】rmvb格式视频无法默认使用影音打开
|
||||
# I64OL2 【影音】【次要】媒体信息页面层级显示问题
|
||||
# I64U3T 【影音】【次要】视频暂停时,移除当前文件,不会回到首页
|
||||
* 需求号:无.
|
||||
* 其他改动:无.
|
||||
|
||||
-- liucong <liucong1@kylinos.cn> Tue, 20 May 2023 20:14:02 +0800
|
||||
|
||||
kylin-video (3.1.4.2k1-ok14) v101; urgency=medium
|
||||
|
||||
* BUG号:【影音】【主要】【UKUI4.0】双指滑动无法调节音量
|
||||
|
|
|
@ -5,35 +5,36 @@ Maintainer: Kylin Team <team+kylin@tracker.debian.org>
|
|||
Uploaders: Aron Xu <aron@debian.org>,
|
||||
handsome_feng <jianfengli@ubuntukylin.com>
|
||||
Build-Depends: debhelper-compat (= 12),
|
||||
qtbase5-dev (>= 5.1),
|
||||
qt5-qmake,
|
||||
qtchooser,
|
||||
qtscript5-dev,
|
||||
qttools5-dev-tools,
|
||||
qtbase5-dev-tools,
|
||||
qtbase5-private-dev,
|
||||
libqt5x11extras5-dev,
|
||||
libx11-dev,
|
||||
libcrystalhd-dev [amd64 i386],
|
||||
zlib1g-dev,
|
||||
libavdevice-dev,
|
||||
libavfilter-dev,
|
||||
libavformat-dev,
|
||||
libavresample-dev,
|
||||
libavutil-dev,
|
||||
libcrystalhd-dev [amd64 i386],
|
||||
libffmpegthumbnailer-dev,
|
||||
libgsettings-qt-dev,
|
||||
libkf5wayland-dev,
|
||||
libkf5windowsystem-dev,
|
||||
libmediainfo-dev,
|
||||
libmpv-dev,
|
||||
libqt5x11extras5-dev,
|
||||
libukui-log4qt-dev,
|
||||
libgsettings-qt-dev,
|
||||
libmpv-dev,
|
||||
libkf5windowsystem-dev,
|
||||
libkf5wayland-dev,
|
||||
libwayland-dev,
|
||||
libx11-dev,
|
||||
libzen-dev,
|
||||
qt5-qmake,
|
||||
qtbase5-dev (>= 5.1),
|
||||
qtbase5-dev-tools,
|
||||
qtbase5-private-dev,
|
||||
qtchooser,
|
||||
qtscript5-dev,
|
||||
qttools5-dev-tools,
|
||||
zlib1g-dev,
|
||||
libkysdk-qtwidgets-dev,
|
||||
libkysdk-waylandhelper-dev,
|
||||
libmediainfo-dev,
|
||||
libmpv-dev,
|
||||
libukui-log4qt-dev,
|
||||
libqtav-dev,
|
||||
libqtav-private-dev,
|
||||
libkysdk-sysinfo-dev (>= 1.1),
|
||||
libqtavwidgets1,
|
||||
libkysdk-qtwidgets-dev,
|
||||
Standards-Version: 4.5.0
|
||||
Rules-Requires-Root: no
|
||||
Homepage: https://github.com/ukui/kylin-video
|
||||
|
@ -46,11 +47,10 @@ Depends: mesa-vdpau-drivers,
|
|||
libcrystalhd3 [amd64 i386],
|
||||
libmpv1,
|
||||
libqtavwidgets1,
|
||||
libffmpegthumbnailer4v5,
|
||||
ffmpegthumbnailer,
|
||||
${misc:Depends},
|
||||
${shlibs:Depends}
|
||||
Suggests: libcrystalhd3 | firmware-crystalhd
|
||||
Suggests: libcrystalhd3 | firmware-crystalhd,
|
||||
Description: Front-end for MPV
|
||||
Qt5 MPV front-end, with basic features like playing
|
||||
videos and audios to more advanced features.
|
||||
|
|
|
@ -10,7 +10,7 @@ GenericName[zh_CN]=影音
|
|||
GenericName[bo_CN]=བརྙན་ཆས།
|
||||
Exec=kylin-video %U
|
||||
Icon=kylin-video
|
||||
MimeType=audio/ac3;audio/mp4;audio/mpeg;audio/vnd.rn-realaudio;audio/vorbis;audio/x-adpcm;audio/x-matroska;audio/x-mp2;audio/x-mp3;audio/x-ms-wma;audio/x-vorbis;audio/x-wav;audio/mpegurl;audio/x-mpegurl;audio/x-pn-realaudio;audio/x-scpls;audio/aac;audio/flac;audio/ogg;audio/amr;audio/x-aiff;audio/basic;audio/midi;audio/amr-wb;audio/x-realaudio;audio/3gpp;audio/x-pn-realaudio-plugin;audio/x-gsm;audio/x-ms-wax;audio/prs.sid;audio/x-musepack;audio/x-ape;audio/x-m4a;audio/x-mod;audio/x-s3m;audio/x-flac;audio/x-vorbis+ogg;audio/x-wavpack;audio/mp2;audio/x-ms-asx;audio/x-tta;audio/x-mpeg;audio/m4a;audio/mp1;audio/mp3;audio/mpg;audio/scpls;audio/wav;audio/webm;audio/x-aac;audio/x-it;audio/x-mp1;audio/x-mpg;audio/x-ms-asf;audio/x-pn-au;audio/x-pn-wav;audio/x-shorten;audio/x-speex;audio/x-xm;audio/3gpp2;audio/dv;audio/eac3;audio/opus;audio/x-pn-aiff;audio/x-pn-windows-acm;audio/x-real-audio;audio/vnd.dolby.heaac.1;audio/vnd.dolby.heaac.2;audio/vnd.dts;audio/vnd.dts.hd;audio/x-m4b;audio/x-stm;audio/m3u;audio/rn-mpeg;audio/vnd.dolby.mlp;audio/x-pls;audio/x-pn-windows-pcm;audio/x-sbc;audio/x-voc;audio/aiff;audio/mpeg2;audio/mpeg3;audio/musepack;audio/x-flac+ogg;audio/x-m3u;audio/x-oggflac;audio/x-opus+ogg;video/avi;video/mp4;video/flv;video/mpeg;video/quicktime;video/vnd.rn-realvideo;video/x-matroska;video/x-ms-asf;video/x-msvideo;video/x-ms-wmv;video/x-ogm;video/x-theora;video/webm;video/x-flv;video/ogg;video/3gpp;video/x-mng;video/mp2t;video/dv;video/mp4v-es;video/x-ms-wmx;video/vnd.mpegurl;video/fli;video/x-ms-wm;video/x-ms-wvx;video/vnd.vivo;video/x-fli;video/x-flc;video/x-m4v;video/3gpp2;video/x-ogm+ogg;video/x-avi;video/msvideo;video/x-theora+ogg;video/x-flic;video/x-mpeg;video/x-mpeg2;video/x-nsv;video/x-anim;video/3gp;video/divx;video/vnd.divx;video/x-ms-asx;video/mpeg-system;video/x-ms-afs;video/x-ms-asf-plugin;video/x-ms-wvxvideo;video/vivo;video/x-mpeg-system;video/x-totem-stream;video/mediaplayer;video/mkv;video/x-mjpeg;video/x-mpeg3;video/x-ms-wmp;audio/AMR;audio/amr;audio/m4p;audio/x-m4p;audio/au;audio/x-au;audio/voc;audio/x-voc;application/x-shockwave-flash;
|
||||
MimeType=audio/ac3;audio/mp4;audio/mpeg;audio/vnd.rn-realaudio;audio/vorbis;audio/x-adpcm;audio/x-matroska;audio/x-mp2;audio/x-mp3;audio/x-ms-wma;audio/x-vorbis;audio/x-wav;audio/mpegurl;audio/x-mpegurl;audio/x-pn-realaudio;audio/x-scpls;audio/aac;audio/flac;audio/ogg;audio/amr;audio/x-aiff;audio/basic;audio/midi;audio/amr-wb;audio/x-realaudio;audio/3gpp;audio/x-pn-realaudio-plugin;audio/x-gsm;audio/x-ms-wax;audio/prs.sid;audio/x-musepack;audio/x-ape;audio/x-m4a;audio/x-mod;audio/x-s3m;audio/x-flac;audio/x-vorbis+ogg;audio/x-wavpack;audio/mp2;audio/x-ms-asx;audio/x-tta;audio/x-mpeg;audio/m4a;audio/mp1;audio/mp3;audio/mpg;audio/scpls;audio/wav;audio/webm;audio/x-aac;audio/x-it;audio/x-mp1;audio/x-mpg;audio/x-ms-asf;audio/x-pn-au;audio/x-pn-wav;audio/x-shorten;audio/x-speex;audio/x-xm;audio/3gpp2;audio/dv;audio/eac3;audio/opus;audio/x-pn-aiff;audio/x-pn-windows-acm;audio/x-real-audio;audio/vnd.dolby.heaac.1;audio/vnd.dolby.heaac.2;audio/vnd.dts;audio/vnd.dts.hd;audio/x-m4b;audio/x-stm;audio/m3u;audio/rn-mpeg;audio/vnd.dolby.mlp;audio/x-pls;audio/x-pn-windows-pcm;audio/x-sbc;audio/x-voc;audio/aiff;audio/mpeg2;audio/mpeg3;audio/musepack;audio/x-flac+ogg;audio/x-m3u;audio/x-oggflac;audio/x-opus+ogg;video/avi;video/mp4;video/flv;video/mpeg;video/quicktime;video/vnd.rn-realvideo;video/x-matroska;video/x-ms-asf;video/x-msvideo;video/x-ms-wmv;video/x-ogm;video/x-theora;video/webm;video/x-flv;video/ogg;video/3gpp;video/x-mng;video/mp2t;video/dv;video/mp4v-es;video/x-ms-wmx;video/vnd.mpegurl;video/fli;video/x-ms-wm;video/x-ms-wvx;video/vnd.vivo;video/x-fli;video/x-flc;video/x-m4v;video/3gpp2;video/x-ogm+ogg;video/x-avi;video/msvideo;video/x-theora+ogg;video/x-flic;video/x-mpeg;video/x-mpeg2;video/x-nsv;video/x-anim;video/3gp;video/divx;video/vnd.divx;video/x-ms-asx;video/mpeg-system;video/x-ms-afs;video/x-ms-asf-plugin;video/x-ms-wvxvideo;video/vivo;video/x-mpeg-system;video/x-totem-stream;video/mediaplayer;video/mkv;video/x-mjpeg;video/x-mpeg3;video/x-ms-wmp;audio/AMR;audio/amr;audio/m4p;audio/x-m4p;audio/au;audio/x-au;audio/voc;audio/x-voc;application/x-shockwave-flash;application/vnd.smaf;application/vnd.rn-realmedia;
|
||||
Type=Application
|
||||
Categories=Qt;KDE;AudioVideo;Player;Video;
|
||||
Keywords=movie;player;media;kde;qt;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
HEADERS += \
|
||||
$$PWD/dbusadapter.h \
|
||||
$$PWD/ffutil.h \
|
||||
$$PWD/mediahandle.h \
|
||||
$$PWD/mpvcore.h \
|
||||
$$PWD/mpvtypes.h \
|
||||
|
@ -9,7 +8,6 @@ HEADERS += \
|
|||
|
||||
SOURCES += \
|
||||
$$PWD/dbusadapter.cpp \
|
||||
$$PWD/ffutil.cpp \
|
||||
$$PWD/mediahandle.cpp \
|
||||
$$PWD/mpvcore.cpp \
|
||||
$$PWD/playlist.cpp \
|
||||
|
|
|
@ -1,227 +0,0 @@
|
|||
#include "ffutil.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QProcess>
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QFileInfo>
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
#include <libavformat/avformat.h> //封装格式
|
||||
#include <libavcodec/avcodec.h> //解码
|
||||
#include <libswscale/swscale.h> //缩放
|
||||
#include <libavutil/opt.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
FFUtil::FFUtil(QObject *parent) : QObject(parent)
|
||||
{
|
||||
av_register_all();
|
||||
m_videoTbr = new VideoThumbnailer;
|
||||
m_videoTbr->setThumbnailSize(176);
|
||||
pFormatCtx = nullptr;
|
||||
pCodecCtx = nullptr;
|
||||
}
|
||||
|
||||
FFUtil::~FFUtil()
|
||||
{
|
||||
close();
|
||||
}
|
||||
|
||||
int FFUtil::open(QString _file)
|
||||
{
|
||||
m_fileName = _file;
|
||||
return 0;
|
||||
|
||||
if(_file.length() == 0)
|
||||
return -1;
|
||||
if(pFormatCtx)
|
||||
avformat_close_input(&pFormatCtx);
|
||||
if(pCodecCtx)
|
||||
avcodec_free_context(&pCodecCtx);
|
||||
|
||||
videoDuration = 0;
|
||||
videoStream = -1;
|
||||
pFormatCtx = nullptr;
|
||||
pCodecCtx = nullptr;
|
||||
AVDictionary *opts = nullptr;
|
||||
int t_seekTime = 0;
|
||||
if (avformat_open_input(&pFormatCtx, _file.toStdString().c_str(), 0, &opts) != 0)
|
||||
{
|
||||
KyInfo("can't open the file.");
|
||||
return -3;
|
||||
}
|
||||
|
||||
// 找流信息
|
||||
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0)
|
||||
{
|
||||
printf("Could't find stream infomation.");
|
||||
return -2;
|
||||
}
|
||||
|
||||
videoStream = -1;
|
||||
videoStream = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
|
||||
if (videoStream < 0)
|
||||
{
|
||||
KyInfo("Can't find a video stream.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
pCodec = avcodec_find_decoder_by_name(avcodec_get_name(pFormatCtx->streams[videoStream]->codecpar->codec_id));
|
||||
if(!pCodec) {
|
||||
pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);
|
||||
if(!pCodec)
|
||||
{
|
||||
KyInfo("find decodec error");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
pCodecCtx = avcodec_alloc_context3(pCodec);
|
||||
if(!pCodecCtx)
|
||||
{
|
||||
KyInfo("Codec context alloc error.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar);
|
||||
|
||||
int re = avcodec_open2(pCodecCtx, pCodec, 0);
|
||||
if (re != 0)
|
||||
{
|
||||
KyInfo("Open decodec error.");
|
||||
avcodec_free_context(&pCodecCtx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 可能前几帧是黑屏,所以向后跳转
|
||||
videoDuration = pFormatCtx->duration/1000000;
|
||||
t_seekTime = fitTime(videoDuration);
|
||||
if(t_seekTime > 0)
|
||||
{
|
||||
int re = av_seek_frame(pFormatCtx, -1, t_seekTime*AV_TIME_BASE, 0);
|
||||
if(re < 0) {
|
||||
KyInfo("get view seek error.");
|
||||
}
|
||||
avcodec_flush_buffers(pCodecCtx);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int FFUtil::getDuration()
|
||||
{
|
||||
QFileInfo fi(m_fileName);
|
||||
if (!fi.exists()) {
|
||||
return 0;
|
||||
}
|
||||
if(!pFormatCtx)
|
||||
return -1;
|
||||
return pFormatCtx->duration/1000000;
|
||||
}
|
||||
|
||||
void FFUtil::close()
|
||||
{
|
||||
if(pCodecCtx)
|
||||
{
|
||||
avcodec_close(pCodecCtx);
|
||||
avcodec_free_context(&pCodecCtx);
|
||||
}
|
||||
}
|
||||
|
||||
void FFUtil::saveIFrame(QString _savePath)
|
||||
{
|
||||
QProcess p;
|
||||
p.start(QString("ffmpegthumbnailer -i %1 -o %2").arg("\"" + m_fileName + "\"").arg(_savePath));
|
||||
p.waitForFinished();
|
||||
close();
|
||||
return;
|
||||
|
||||
#if 0
|
||||
AVFrame *pFrame = nullptr;
|
||||
AVFrame *pFrameRGB = nullptr;
|
||||
uint8_t *outBuffer = nullptr;
|
||||
AVPacket *packet = nullptr;
|
||||
int numBytes = 0;
|
||||
|
||||
if(videoStream < 0)
|
||||
return;
|
||||
|
||||
if(!pCodecCtx)
|
||||
{
|
||||
qDebug() << "codec context is nullptr!";
|
||||
return;
|
||||
}
|
||||
pFrame = av_frame_alloc();
|
||||
pFrameRGB = av_frame_alloc();
|
||||
numBytes = avpicture_get_size(AV_PIX_FMT_RGB32, pCodecCtx->width,pCodecCtx->height);
|
||||
outBuffer = (uint8_t *)av_malloc(numBytes);
|
||||
|
||||
avpicture_fill((AVPicture *) pFrameRGB, outBuffer, AV_PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height);
|
||||
|
||||
packet = av_packet_alloc();
|
||||
av_init_packet(packet);
|
||||
int tryNum = 0;
|
||||
while (true) {
|
||||
if (av_read_frame(pFormatCtx, packet) < 0)//从流中读取读取数据到Packet中
|
||||
{
|
||||
KyInfo("read end, but no frame get");
|
||||
break; //这里认为视频读取完了
|
||||
}
|
||||
if (packet->stream_index != videoStream) {
|
||||
av_packet_unref(packet);
|
||||
continue;
|
||||
}
|
||||
// if (packet->stream_index == videoStream)
|
||||
{
|
||||
// 解码
|
||||
avcodec_send_packet(pCodecCtx, packet);
|
||||
// 获取解码数据
|
||||
int ret = avcodec_receive_frame(pCodecCtx, pFrame);
|
||||
if (ret < 0 || !pFrame->key_frame)
|
||||
{
|
||||
if(tryNum > 2000)
|
||||
{
|
||||
break;
|
||||
}
|
||||
// 最多尝试解码 200 帧,如果没获取到正确的帧就不要预览图了,否则解码占用时间过长,后面放到线程里面去就可以一直解码了。
|
||||
tryNum++;
|
||||
continue;
|
||||
}
|
||||
SwsContext *img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height,
|
||||
(AVPixelFormat)pFrame->format, pCodecCtx->width, pCodecCtx->height,
|
||||
AV_PIX_FMT_RGB32, SWS_BICUBIC, nullptr, nullptr, nullptr);
|
||||
sws_scale(img_convert_ctx, (const uint8_t *const*)pFrame->data,
|
||||
pFrame->linesize, 0, pCodecCtx->height,
|
||||
pFrameRGB->data, pFrameRGB->linesize);
|
||||
sws_freeContext(img_convert_ctx);
|
||||
{
|
||||
QImage img((uchar *)pFrameRGB->data[0], pCodecCtx->width, pCodecCtx->height, QImage::Format_RGB32);
|
||||
img.save(_savePath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
free(outBuffer);
|
||||
av_packet_free(&packet);
|
||||
av_frame_free(&pFrame);
|
||||
av_frame_free(&pFrameRGB);
|
||||
avformat_flush(pFormatCtx);
|
||||
avcodec_flush_buffers(pCodecCtx);
|
||||
#endif
|
||||
}
|
||||
|
||||
int FFUtil::fitTime(int _duration)
|
||||
{
|
||||
if(_duration < 1)
|
||||
return 0;
|
||||
else if(_duration < 5)
|
||||
return 1;
|
||||
else
|
||||
return 3;
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
#ifndef FFUTIL_H
|
||||
#define FFUTIL_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <libffmpegthumbnailer/videothumbnailer.h>
|
||||
using namespace ffmpegthumbnailer;
|
||||
|
||||
struct AVCodec;
|
||||
struct AVCodecContext;
|
||||
struct AVFormatContext;
|
||||
|
||||
class FFUtil : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit FFUtil(QObject *parent = nullptr);
|
||||
~FFUtil();
|
||||
int open(QString _file);
|
||||
int getDuration();
|
||||
void close();
|
||||
void saveIFrame(QString _savePath);
|
||||
|
||||
private:
|
||||
QString m_fileName;
|
||||
VideoThumbnailer *m_videoTbr;
|
||||
AVFormatContext *pFormatCtx;
|
||||
AVCodecContext *pCodecCtx;
|
||||
AVCodec *pCodec;
|
||||
int videoStream;
|
||||
int videoDuration;
|
||||
|
||||
int fitTime(int _duration);
|
||||
|
||||
signals:
|
||||
|
||||
};
|
||||
|
||||
#endif // FFUTIL_H
|
|
@ -4,8 +4,9 @@
|
|||
#include <QProcess>
|
||||
#include <QDateTime>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusConnection>
|
||||
#include <QApplication>
|
||||
#include <QStandardPaths>
|
||||
#include <QDBusConnection>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <ukui-log4qt.h>
|
||||
|
@ -43,12 +44,13 @@ MpvCore::MpvCore(QWidget *pw, QObject *parent) :
|
|||
|
||||
m_playWidget = pw;
|
||||
|
||||
m_volume = 100;
|
||||
m_duration = -1;
|
||||
|
||||
initMpvHandle();
|
||||
initGlobalSig();
|
||||
initVolumeDBus();
|
||||
|
||||
m_volume = 100;
|
||||
|
||||
m_isLoaded = false;
|
||||
m_osdShow = true;
|
||||
m_isHFlip = false;
|
||||
|
@ -60,6 +62,9 @@ MpvCore::MpvCore(QWidget *pw, QObject *parent) :
|
|||
m_isSinkVolumeChange = true;
|
||||
m_isPauseWhenNeedSeek = false;
|
||||
m_canSaveScreenShot = true;
|
||||
m_changeVolumeForce = false;
|
||||
|
||||
ScreenshotDirectory(g_config->screenShotPath.first);
|
||||
}
|
||||
|
||||
void MpvCore::ShowText(QString text, int duration)
|
||||
|
@ -129,14 +134,19 @@ void MpvCore::VideoDecoder(QString vd)
|
|||
|
||||
void MpvCore::VideoOutput(QString vo)
|
||||
{
|
||||
#ifdef JJM_GRAPHICS
|
||||
if (vo == "auto") {
|
||||
SetOption("vo", "");
|
||||
if (g_config->videoOutputType() == GlobalConfig::VO_WID) {
|
||||
if (vo == "auto") {
|
||||
if (g_config->hardwareType() == GlobalConfig::JM7X_VDPAU)
|
||||
SetOption("vo", "vdpau,xv,x11");
|
||||
else if (g_config->hardwareType() == GlobalConfig::JM9X_VAAPI)
|
||||
SetOption("vo", "vaapi,xv,x11");
|
||||
else
|
||||
SetOption("vo", "");
|
||||
}
|
||||
else {
|
||||
SetOption("vo", vo + ",vaapi,vdpau,x11,xv");
|
||||
}
|
||||
}
|
||||
else {
|
||||
SetOption("vo", output);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MpvCore::DecodeThreads(int threads)
|
||||
|
@ -458,7 +468,6 @@ void MpvCore::Open(QString file, int start)
|
|||
m_lastTime = 0;
|
||||
m_rotate = 0;
|
||||
m_fps = 0;
|
||||
m_vid = m_aid = m_sid = -1;
|
||||
|
||||
if (start > 0) {
|
||||
m_needSeek = true;
|
||||
|
@ -472,6 +481,15 @@ void MpvCore::Open(QString file, int start)
|
|||
QThread::msleep(20);
|
||||
}
|
||||
LoadOptions();
|
||||
if (m_playingFile.endsWith("iso")) {
|
||||
// iso 文件判断下有没有音频和视频流
|
||||
MediaHandle mi(m_playingFile);
|
||||
if (mi.getAudioCount() <= 0 && mi.getVideoCount() <= 0) {
|
||||
g_core_signal->notifyFileLoadedError(m_playingFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
m_vid = m_aid = m_sid = -1;
|
||||
Command(QStringList() << "loadfile" << this->m_playingFile);
|
||||
})->start();
|
||||
}
|
||||
|
@ -560,27 +578,36 @@ void MpvCore::Seek(int pos, bool relative, bool osd)
|
|||
{
|
||||
if(osd)
|
||||
{
|
||||
Command(QVariantList() << "osd-msg" << "seek" << pos << "absolute");
|
||||
const char *args[] = {"osd-msg", "seek", QString::number(pos).toStdString().c_str(), "absolute", NULL};
|
||||
AsyncCommand(args);
|
||||
// Command(QVariantList() << "osd-msg" << "seek" << pos << "absolute");
|
||||
}
|
||||
else
|
||||
{
|
||||
Command(QVariantList() << "seek" << pos << "absolute");
|
||||
const char *args[] = {"seek", QString::number(pos).toStdString().c_str(), "absolute", NULL};
|
||||
AsyncCommand(args);
|
||||
// Command(QVariantList() << "seek" << pos << "absolute");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MpvCore::Restart()
|
||||
{
|
||||
m_restartOkState = false;
|
||||
// 重启需要有间隔,不然会报错
|
||||
static int64_t restartTime = 0;
|
||||
if (QDateTime::currentMSecsSinceEpoch() - restartTime < 300)
|
||||
if (QDateTime::currentMSecsSinceEpoch() - restartTime < 300) {
|
||||
m_restartOkState = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_playingFile == QString() || g_playstate < 0)
|
||||
if (m_playingFile == QString() || g_playstate < 0) {
|
||||
m_restartOkState = true;
|
||||
return;
|
||||
}
|
||||
|
||||
KyInfo() << "[Restart] file play restart...";
|
||||
m_isPauseWhenNeedSeek = g_playstate == Mpv::Paused;
|
||||
QThread::create([this](){
|
||||
std::unique_lock<std::mutex> lk(m_mtxStop);
|
||||
|
@ -590,10 +617,13 @@ void MpvCore::Restart()
|
|||
SetOption("volume", "0");
|
||||
m_needSeek = true;
|
||||
}
|
||||
KyInfo() << "[Restart] open file...";
|
||||
Open(m_playingFile);
|
||||
KyInfo() << "[Restart] open file command ok.";
|
||||
lk.unlock();
|
||||
})->start();
|
||||
|
||||
KyInfo() << "[Restart] stop file...";
|
||||
Stop();
|
||||
|
||||
// 因为 open 是非阻塞的 所以跳转要在播放状态为 加载之后.
|
||||
|
@ -621,9 +651,17 @@ void MpvCore::Volume(int level)
|
|||
if(level > 100) level = 100;
|
||||
else if(level < 0) level = 0;
|
||||
|
||||
if (m_volume == level)
|
||||
if (m_volume == level && !m_changeVolumeForce)
|
||||
return;
|
||||
|
||||
m_changeVolumeForce = false;
|
||||
|
||||
// 如果是 alsa 输出,直接调节 mpv 音量
|
||||
if (g_config->audioOut.first == "alsa") {
|
||||
SetOption("volume", QString::number(level));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_isSinkVolumeChange) {
|
||||
// 设置音量,此音量和系统同步,不单独设置mpv音量
|
||||
QDBusMessage message = QDBusMessage::createSignal("/", "org.kylin.video", "sinkInputVolumeChanged");
|
||||
|
@ -633,8 +671,6 @@ void MpvCore::Volume(int level)
|
|||
}
|
||||
else
|
||||
m_isSinkVolumeChange = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void MpvCore::Channel(Mpv::Channel c)
|
||||
|
@ -710,7 +746,12 @@ void MpvCore::SpeedDown()
|
|||
|
||||
void MpvCore::BrightnessUp()
|
||||
{
|
||||
if(m_brightness < 100)
|
||||
// 如果是jjw显卡,vdpau 和 vaapi 亮度调节不生效,提示一下
|
||||
if ((g_config->hardwareType() == GlobalConfig::JM7X_VDPAU || g_config->hardwareType() == GlobalConfig::JM9X_VAAPI) && g_config->videoOutput.first != "x11") {
|
||||
ShowText(tr("not support brightness set."));
|
||||
return;
|
||||
}
|
||||
if (m_brightness < 100)
|
||||
{
|
||||
m_brightness += 2;
|
||||
g_settings->setValue("General/brightness", m_brightness);
|
||||
|
@ -721,7 +762,13 @@ void MpvCore::BrightnessUp()
|
|||
|
||||
void MpvCore::BrightnessDown()
|
||||
{
|
||||
if(m_brightness > -100)
|
||||
// 如果是jjw显卡,vdpau 和 vaapi 亮度调节不生效,提示一下
|
||||
if ((g_config->hardwareType() == GlobalConfig::JM7X_VDPAU ||
|
||||
g_config->hardwareType() == GlobalConfig::JM9X_VAAPI) && g_config->videoOutput.first != "x11") {
|
||||
ShowText(tr("not support brightness set."));
|
||||
return;
|
||||
}
|
||||
if (m_brightness > -100)
|
||||
{
|
||||
m_brightness -= 2;
|
||||
g_settings->setValue("General/brightness", m_brightness);
|
||||
|
@ -812,6 +859,7 @@ void MpvCore::SetAspect(QString scale)
|
|||
|
||||
void MpvCore::RestoreFrame()
|
||||
{
|
||||
mpv_set_option_string(m_mpvHandle, "keepaspect", "yes");
|
||||
Command(QStringList() << "set" << "video-rotate" << "0");
|
||||
m_rotate = 0;
|
||||
if(m_isHFlip)
|
||||
|
@ -975,7 +1023,8 @@ void MpvCore::AddBookMark(QString desc)
|
|||
ShowText(tr("Add mark error"));
|
||||
return;
|
||||
}
|
||||
if ((int)m_lastTime <= 0 || m_marks.find((int)m_lastTime) != m_marks.end())
|
||||
// 第一秒和最后一秒不能添加书签
|
||||
if ((int)m_lastTime <= 0 || (int)m_lastTime >= (int)m_duration || m_marks.find((int)m_lastTime) != m_marks.end())
|
||||
return;
|
||||
KyInfo() << "add book mark " << m_lastTime;
|
||||
// 获取一个截图,作为预览图
|
||||
|
@ -1153,13 +1202,20 @@ void MpvCore::slotVolumeChange(QString app, int value, bool mute)
|
|||
m_isSinkMuteChange = false;
|
||||
if (value != m_volume)
|
||||
ShowText(QString(tr("volume : %1")).arg(value));
|
||||
// if (mute != this->mute && volume == value) {
|
||||
if (mute != m_mute) {
|
||||
m_mute = mute;
|
||||
g_core_signal->notifyMute(mute);
|
||||
ShowText(mute ? tr("Mute") : tr("Cancel Mute"));
|
||||
}
|
||||
m_volume = value;
|
||||
// 如果是重启之后有了音量信号,则是pulse主动发过来的
|
||||
if (m_restartOkState) {
|
||||
m_isSinkVolumeChange = true;
|
||||
m_changeVolumeForce = true;
|
||||
Volume(m_volume);
|
||||
m_restartOkState = false;
|
||||
}
|
||||
else
|
||||
m_volume = value;
|
||||
g_core_signal->notifyVolume(value);
|
||||
m_isSinkVolumeChange = true;
|
||||
m_isSinkMuteChange = true;
|
||||
|
@ -1181,11 +1237,11 @@ void MpvCore::initMpvHandle()
|
|||
|
||||
mpv_set_option_string(m_mpvHandle, "terminal", "yes");
|
||||
mpv_set_option_string(m_mpvHandle, "msg-level", "all=v");
|
||||
// mpv_set_option_string(m_mpvHandle, "msg-level", "all=error");
|
||||
mpv_set_option_string(m_mpvHandle, "input-cursor", "no");
|
||||
mpv_set_option_string(m_mpvHandle, "hwdec-codecs", "all");
|
||||
mpv_set_option_string(m_mpvHandle, "cursor-autohide", "no");
|
||||
mpv_set_option_string(m_mpvHandle, "input-vo-keyboard", "no");
|
||||
mpv_set_option_string(m_mpvHandle, "gpu-context", "x11egl");
|
||||
mpv_set_option_string(m_mpvHandle, "input-vo-keyboard", "no");
|
||||
mpv_set_option_string(m_mpvHandle, "input-default-bindings ", "no");
|
||||
|
||||
mpv_observe_property(m_mpvHandle, 0, "mute", MPV_FORMAT_FLAG);
|
||||
|
@ -1200,7 +1256,7 @@ void MpvCore::initMpvHandle()
|
|||
mpv_observe_property(m_mpvHandle, 0, "paused-for-cache",MPV_FORMAT_FLAG);
|
||||
mpv_set_wakeup_callback(m_mpvHandle, wakeup, this);
|
||||
|
||||
if (g_config->hardwareType() == GlobalConfig::JMX200_VDPAU || g_config->hardwareType() == GlobalConfig::X100_GPU)
|
||||
if (g_config->videoOutputType() == GlobalConfig::VO_WID)
|
||||
SetOption("wid", QString::number(m_playWidget->winId()));
|
||||
else {
|
||||
SetOption("vo", "opengl-cb");
|
||||
|
@ -1304,8 +1360,9 @@ void MpvCore::initVolumeDBus()
|
|||
QDBusConnection::sessionBus().connect(QString(), "/", "org.ukui.media", "sinkVolumeChanged", this, SLOT(slotVolumeChange(QString,int,bool)));
|
||||
// 初始化静音状态和音量
|
||||
m_mute = g_settings->value("General/mute").toBool();
|
||||
g_core_signal->notifyMute(m_mute);
|
||||
m_volume = g_settings->value("General/volume").toInt();
|
||||
|
||||
g_core_signal->notifyMute(m_mute);
|
||||
g_core_signal->notifyVolume(m_volume);
|
||||
}
|
||||
|
||||
|
@ -1317,7 +1374,7 @@ void MpvCore::LoadOptions()
|
|||
SetOption("screenshot-template", "cap_%F_%p_%02n");
|
||||
|
||||
SetOption("screenshot-directory", g_config->screenShotPath.first == ""
|
||||
? QDir::homePath().append("/").append(tr("Pictures"))
|
||||
? QStandardPaths::writableLocation(QStandardPaths::PicturesLocation)
|
||||
: g_config->screenShotPath.first);
|
||||
|
||||
// 2.设置字幕
|
||||
|
@ -1353,23 +1410,26 @@ void MpvCore::LoadOptions()
|
|||
SetOption("hwdec", g_config->videoDecoder.first);
|
||||
}
|
||||
|
||||
if (g_config->hardwareType() == GlobalConfig::JMX200_VDPAU || g_config->hardwareType() == GlobalConfig::X100_GPU) {
|
||||
if (g_config->videoOutputType() == GlobalConfig::VO_WID) {
|
||||
#if 1
|
||||
if (g_config->videoOutput.first == tr("auto") || g_config->videoOutput.first == "auto") {
|
||||
SetOption("vo", "");
|
||||
if (g_config->hardwareType() == GlobalConfig::JM7X_VDPAU)
|
||||
SetOption("vo", "vdpau,xv,x11");
|
||||
else if (g_config->hardwareType() == GlobalConfig::JM9X_VAAPI)
|
||||
SetOption("vo", "vaapi,xv,x11");
|
||||
else
|
||||
SetOption("vo", "");
|
||||
#ifdef __loongarch__
|
||||
SetOption("vo", "x11,");
|
||||
#endif
|
||||
#ifdef __mips64
|
||||
SetOption("vo", "x11,");
|
||||
#endif
|
||||
if (g_config->hardwareType() == GlobalConfig::AMD_R7_SOFTWARE ||
|
||||
g_config->hardwareType() == GlobalConfig::AMD_VDPAU ||
|
||||
g_config->hardwareType() == GlobalConfig::JMX200_VDPAU)
|
||||
if (g_config->videoOutputType() == GlobalConfig::VO_WID)
|
||||
SetOption("vo", "");
|
||||
}
|
||||
else {
|
||||
SetOption("vo", g_config->videoOutput.first + ",");
|
||||
SetOption("vo", g_config->videoOutput.first + ",vaapi,vdpau,x11,xv");
|
||||
#ifdef __loongarch__
|
||||
SetOption("vo", g_config->videoOutput.first + ",x11,");
|
||||
#endif
|
||||
|
@ -1381,7 +1441,10 @@ void MpvCore::LoadOptions()
|
|||
}
|
||||
|
||||
SetOption("vd-lavc-threads", QString::number(g_config->videoDecodeThreads.first));
|
||||
SetOption("volume", "100");
|
||||
if (g_config->audioOut.first == "alsa")
|
||||
SetOption("volume", QString::number(g_settings->value("General/volume").toInt()));
|
||||
else
|
||||
SetOption("volume", "100");
|
||||
|
||||
SetOption("sub-file-paths", g_config->subDir.first);
|
||||
// 是否自动加载字幕
|
||||
|
@ -1445,26 +1508,27 @@ bool MpvCore::event(QEvent *event)
|
|||
{
|
||||
if(prop->format == MPV_FORMAT_DOUBLE)
|
||||
{
|
||||
double tmp_duration = -0.1;
|
||||
if (m_duration == 0) {
|
||||
tmp_duration = g_sqlite->getDuration(m_playingFile);
|
||||
}
|
||||
if (tmp_duration <= 0) {
|
||||
tmp_duration = *(double*)prop->data;
|
||||
double tmp_duration = *(double*)prop->data;
|
||||
if (m_duration <= 0) {
|
||||
m_duration = g_sqlite->getDuration(m_playingFile);
|
||||
}
|
||||
|
||||
if (tmp_duration > m_duration) {
|
||||
m_duration = tmp_duration;
|
||||
g_core_signal->notifyDuration(m_playingFile, m_duration);
|
||||
m_fileInfo.length = m_duration;
|
||||
}
|
||||
g_core_signal->notifyDuration(m_playingFile, m_duration);
|
||||
|
||||
// 重启之后是否需要跳转,获取到总长度才能跳转
|
||||
if (m_needSeek) {
|
||||
Seek(m_seekTime);
|
||||
if (m_isPauseWhenNeedSeek)
|
||||
Pause();
|
||||
SetOption("volume", "100");
|
||||
if (g_config->audioOut.first == "alsa")
|
||||
SetOption("volume", QString::number(m_volume));
|
||||
else
|
||||
SetOption("volume", "100");
|
||||
m_restartOkState = true;
|
||||
}
|
||||
m_needSeek = false;
|
||||
}
|
||||
|
@ -1483,11 +1547,14 @@ bool MpvCore::event(QEvent *event)
|
|||
}
|
||||
else if(QString(prop->name) == "volume")
|
||||
{
|
||||
#if 0
|
||||
if(prop->format == MPV_FORMAT_INT64)
|
||||
{
|
||||
g_core_signal->notifyVolume(*(int*)prop->data);
|
||||
ShowText(QString(tr("volume : %1")).arg(*(int*)prop->data));
|
||||
#if 1
|
||||
if (g_config->audioOut.first == "alsa") {
|
||||
if (prop->format == MPV_FORMAT_INT64)
|
||||
{
|
||||
m_volume = *(int*)prop->data;
|
||||
g_core_signal->notifyVolume(m_volume);
|
||||
ShowText(QString(tr("volume : %1")).arg(*(int*)prop->data));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
#include <mpv/client.h>
|
||||
#include <mpv/opengl_cb.h>
|
||||
#include <mpv/qthelper.hpp>
|
||||
#include <libffmpegthumbnailer/videothumbnailer.h>
|
||||
|
||||
using namespace ffmpegthumbnailer;
|
||||
using namespace KMedia;
|
||||
|
||||
#define MPV_REPLY_COMMAND 1
|
||||
|
@ -45,7 +43,7 @@ public slots:
|
|||
void Seek(int pos, bool relative = false, bool osd = false);
|
||||
void Restart();
|
||||
void Mute(bool);
|
||||
void Volume(int/*, bool osd = false*/);
|
||||
void Volume(int);
|
||||
void Channel(Mpv::Channel c);
|
||||
void Speed(double);
|
||||
void SpeedUp();
|
||||
|
@ -85,6 +83,7 @@ public slots:
|
|||
|
||||
int getVid(){return m_vid;}
|
||||
int getRotate(){return m_rotate;}
|
||||
bool getRestartState() {return m_restartOkState;}
|
||||
QString getMediaInfo();
|
||||
|
||||
private:
|
||||
|
@ -144,6 +143,8 @@ private:
|
|||
bool m_isSinkVolumeChange;
|
||||
bool m_isPauseWhenNeedSeek;
|
||||
bool m_canSaveScreenShot;
|
||||
bool m_restartOkState;
|
||||
bool m_changeVolumeForce;
|
||||
|
||||
private slots:
|
||||
void initMpvHandle();
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
#include "global/globalsignal.h"
|
||||
#include "global/global.h"
|
||||
#include "global/path.h"
|
||||
#include "core/ffutil.h"
|
||||
|
||||
using namespace Global;
|
||||
|
||||
|
@ -61,16 +60,6 @@ void PlayList::addItem(QString file, int duration, int lastStopTime, QString vie
|
|||
// 是否需要写入数据库
|
||||
if(writeToDatabase)
|
||||
{
|
||||
// 如果是无痕浏览的话不要添加到数据库和界面.
|
||||
if(g_config->seamlessBrowsing.first)
|
||||
{
|
||||
if(m_needPlayFile == file)
|
||||
{
|
||||
g_user_signal->stop();
|
||||
g_user_signal->open(m_needPlayFile, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
g_sqlite->insertPlayList(file, file.split("/").last(), duration, viewPath);
|
||||
}
|
||||
|
||||
|
@ -169,7 +158,7 @@ void PlayList::deleteFile(QString file)
|
|||
|
||||
// 删除列表中书签内容
|
||||
QString markPath = "";
|
||||
for (int i=0; i<m_bookmarks.size();) {
|
||||
for (int i=m_bookmarks.size()-1; i>=0; i--) {
|
||||
if (m_bookmarks.at(i).m_filePath == file) {
|
||||
if (markPath == "") {
|
||||
QStringList sl = m_bookmarks.at(i).m_previewPath.split("/");
|
||||
|
@ -178,7 +167,6 @@ void PlayList::deleteFile(QString file)
|
|||
m_bookmarks.remove(i);
|
||||
continue;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
emit sigMarkClear();
|
||||
emit sigMarkUpdate(m_bookmarks);
|
||||
|
@ -301,17 +289,29 @@ void PlayList::addFiles(QStringList files)
|
|||
// 修复一直往里拖动播放问题 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
|
||||
QStringList valiableFiles = files;
|
||||
|
||||
// 如果是无痕浏览的话不要添加到数据库和界面.
|
||||
if (g_config->seamlessBrowsing.first && files.size() > 0)
|
||||
{
|
||||
g_user_signal->stop();
|
||||
g_user_signal->open(files.first(), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (QString filename, files) {
|
||||
if (m_allFile.find(filename) != m_allFile.end())
|
||||
valiableFiles.removeOne(filename);
|
||||
else
|
||||
m_allFile.insert(filename);
|
||||
}
|
||||
if (valiableFiles.size() <= 0)
|
||||
if (valiableFiles.size() <= 0) {
|
||||
g_user_signal->stop();
|
||||
g_user_signal->open(files.first(), 0);
|
||||
return;
|
||||
}
|
||||
// 修复一直往里拖动播放问题 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||
|
||||
// 添加后播放第一个添加的文件
|
||||
m_needPlayFile = valiableFiles.first();
|
||||
// 修复一直往里拖动播放问题 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑
|
||||
|
||||
foreach (QString filename, valiableFiles) {
|
||||
QFileInfo fileInfo(filename);
|
||||
|
@ -373,7 +373,8 @@ void PlayList::addDirectory(QString dir)
|
|||
}
|
||||
++itemIterator;
|
||||
}
|
||||
addFiles(dirFiles);
|
||||
if (dirFiles.size() != 0)
|
||||
addFiles(dirFiles);
|
||||
}
|
||||
|
||||
/** **********************************************
|
||||
|
@ -383,13 +384,15 @@ void PlayList::addDirectory(QString dir)
|
|||
*************************************************/
|
||||
void PlayList::playNext(bool manual)
|
||||
{
|
||||
if (m_availableIndexVec.size() == 0 || (QDateTime::currentMSecsSinceEpoch()-m_lastFileChange < 300 && manual)) {
|
||||
KyInfo() << " available index size " << m_availableIndexVec.size();
|
||||
if (m_availableIndexVec.size() == 0)
|
||||
g_user_signal->showStopFrame();
|
||||
// 无痕浏览不能播放下一首,并且清空列表
|
||||
if (!manual && (g_config->seamlessBrowsing.first || m_availableIndexVec.size() == 0)) {
|
||||
clearList();
|
||||
return;
|
||||
}
|
||||
if (m_availableIndexVec.size() == 0 || (QDateTime::currentMSecsSinceEpoch() - m_lastFileChange < 300 && manual)) {
|
||||
KyInfo() << " available index size " << m_availableIndexVec.size();
|
||||
return;
|
||||
}
|
||||
g_user_signal->play();
|
||||
if(m_playOrder == ONE_LOOP)
|
||||
{
|
||||
if (m_availableIndexVec.indexOf(m_playIndex) < 0)
|
||||
|
@ -454,7 +457,6 @@ void PlayList::playPrev(bool manual)
|
|||
{
|
||||
if (m_availableIndexVec.size() == 0 || QDateTime::currentMSecsSinceEpoch()-m_lastFileChange < 300)
|
||||
return;
|
||||
g_user_signal->play();
|
||||
if(manual && m_playOrder == ONE_LOOP)
|
||||
{
|
||||
do
|
||||
|
@ -669,10 +671,11 @@ void PlayList::newFile(QString file)
|
|||
// 添加 item
|
||||
emit sigAddItem(file, 0, 0, filePath, true);
|
||||
QThread::create([this, file, filePath](){
|
||||
// 缩略图获取
|
||||
FFUtil fuz;
|
||||
fuz.open(file);
|
||||
fuz.saveIFrame(filePath);
|
||||
// 缩略图获取,执行命令获取缩略图
|
||||
QProcess p;
|
||||
p.start(QString("ffmpegthumbnailer -i %1 -o %2").arg("\"" + file + "\"").arg(filePath));
|
||||
p.waitForFinished();
|
||||
|
||||
emit sigReloadView(file);
|
||||
// 时长获取
|
||||
KMedia::MediaHandle mediaHandle;
|
||||
|
@ -738,6 +741,19 @@ void PlayList::initGlobalSig()
|
|||
|
||||
connect(g_core_signal, &GlobalCoreSignal::sigFileInfoChange , this, &PlayList::slotFileInfoChange);
|
||||
|
||||
|
||||
connect(g_core_signal, &GlobalCoreSignal::sigFileLoadedError, this, [this](QString file){
|
||||
int err_index = 0;
|
||||
foreach (auto path, m_fileList) {
|
||||
if (path == file) {
|
||||
m_playIndex = err_index;
|
||||
break;
|
||||
}
|
||||
err_index++;
|
||||
}
|
||||
playNext(false);
|
||||
});
|
||||
|
||||
connect(g_core_signal, &GlobalCoreSignal::sigMarkAdded, this, &PlayList::addMark);
|
||||
connect(g_core_signal, &GlobalCoreSignal::sigDuration, this, [this](QString file, int duration){
|
||||
if ((m_playFile == file && duration <= m_duration))
|
||||
|
|
|
@ -63,7 +63,7 @@ Extensions::Extensions()
|
|||
|
||||
_audio << "mp3" << "ogg" << "oga" << "ac3" << "aiff" << "voc" << "au" << "m4p"
|
||||
<< "ra" << "ape" << "flac" << "thd" << "mka" << "opus" << "mmf" << "mp2" << "wv"
|
||||
<< "m4r" << "wav" << "dts" << "wma" << "m4a" << "aac" << "amr";
|
||||
<< "m4r" << "wav" << "dts" << "wma" << "m4a" << "aac" << "amr" << "mpa";
|
||||
|
||||
_subtitles << "aqt" << "srt" << "sub" << "ssa" << "ass" << "idx" << "smi"
|
||||
<< "rt" << "utf" << "vtt" << "sup";
|
||||
|
@ -72,7 +72,7 @@ Extensions::Extensions()
|
|||
|
||||
_multimedia = _video;
|
||||
for (int n = 0; n < _audio.count(); n++) {
|
||||
if (!_multimedia.contains(_audio[n])) _multimedia << _audio[n];
|
||||
if (!_multimedia.contains(_audio[n])) _multimedia << _audio[n];
|
||||
}
|
||||
|
||||
_all_playable << _multimedia << _playlist;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include <QWindow>
|
||||
#include <QLibrary>
|
||||
#include <QProcess>
|
||||
#include <QMessageBox>
|
||||
#include <QStyleOption>
|
||||
|
||||
#include <ukui-log4qt.h>
|
||||
|
@ -129,8 +128,61 @@ bool Functions::isQingsongDevice()
|
|||
return processComand("lsmod | grep qs | wc -l").toInt() > 0;
|
||||
}
|
||||
|
||||
static inline void strstripspace_kv(char *str)
|
||||
{
|
||||
if (strlen(str) == 0)
|
||||
return;
|
||||
char *startPos = str;
|
||||
while (*startPos != '\0' && isspace(*startPos))
|
||||
startPos++;
|
||||
if (*startPos == '\0') {
|
||||
str[0] = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
char *endPos = str + strlen(str) - 1;
|
||||
while (endPos != str && isspace(*endPos))
|
||||
endPos--;
|
||||
|
||||
memmove(str, startPos, endPos - startPos + 1);
|
||||
*(str + (endPos - startPos) + 1) = 0;
|
||||
}
|
||||
|
||||
static char* kdk_system_get_hostVirtType_kv()
|
||||
{
|
||||
char *virtType = (char*)malloc(sizeof(char) * 65);
|
||||
assert(virtType);
|
||||
#ifdef __linux__
|
||||
FILE *pipeLine = popen("systemd-detect-virt", "r"); // 建立流管道
|
||||
if (!pipeLine)
|
||||
{
|
||||
free(virtType);
|
||||
return NULL;
|
||||
}
|
||||
if (fgets(virtType, 64 * sizeof(char), pipeLine) == NULL)
|
||||
{
|
||||
free(virtType);
|
||||
pclose(pipeLine);
|
||||
return NULL;
|
||||
}
|
||||
pclose(pipeLine);
|
||||
strstripspace_kv(virtType);
|
||||
if (strcmp(virtType, "microsoft") == 0)
|
||||
strcpy(virtType, "hyper-v");
|
||||
else if (strcmp(virtType, "oracle") == 0)
|
||||
strcpy(virtType, "orcale virtualbox");
|
||||
#endif
|
||||
return virtType;
|
||||
|
||||
}
|
||||
|
||||
bool Functions::isVirtualSuppotGpu()
|
||||
{
|
||||
char* type = kdk_system_get_hostVirtType_kv();
|
||||
QString t = type;
|
||||
free(type);
|
||||
return t != "none";
|
||||
|
||||
QString command = "lspci | grep -i vga";
|
||||
bool vgpu = false;
|
||||
|
||||
|
@ -162,9 +214,43 @@ QString Functions::humanSize(const qint64 &size)
|
|||
QString unit("bytes");
|
||||
|
||||
while(num >= 1024.0 && i.hasNext())
|
||||
{
|
||||
{
|
||||
unit = i.next();
|
||||
num /= 1024.0;
|
||||
}
|
||||
return QString().setNum(num,'f',2)+" "+unit;
|
||||
}
|
||||
|
||||
int Functions::executeCMD(QString command, QString &result)
|
||||
{
|
||||
QProcess p;
|
||||
QStringList args;
|
||||
args << "-c" << command;
|
||||
p.start("bash", args);
|
||||
p.waitForFinished();
|
||||
p.waitForReadyRead();
|
||||
result = p.readAll();
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString Functions::getVersion()
|
||||
{
|
||||
QString version;
|
||||
executeCMD("dpkg -l kylin-video | grep kylin-video", version);
|
||||
QStringList fields = version.split(QRegularExpression("[ \t]+"));
|
||||
if (fields.size() >= 3)
|
||||
version = fields.at(2);
|
||||
else
|
||||
version = "none";
|
||||
|
||||
return version;
|
||||
}
|
||||
|
||||
bool Functions::isGreatwallDevice()
|
||||
{
|
||||
QProcess p;
|
||||
p.start("cat /sys/class/dmi/id/modalias");
|
||||
p.waitForFinished();
|
||||
QString str(p.readAll());
|
||||
return str.indexOf("greatwall", Qt::CaseInsensitive) > 0;
|
||||
}
|
||||
|
|
|
@ -32,15 +32,18 @@ namespace Functions
|
|||
using ChecksumList = QVector<quint64>;
|
||||
QString Url(QString, const QString &pth = QString());
|
||||
QString getUrlType(const QString &url);
|
||||
QString getVersion();
|
||||
QString timeToStr(const double t, const bool decimals = false);
|
||||
|
||||
QString filePath(const QString &);
|
||||
QString fileExt(const QString &);
|
||||
QString processComand(const QString &);
|
||||
QString humanSize(const qint64 &);
|
||||
int executeCMD(QString, QString&);
|
||||
bool isVirtualSuppotGpu();
|
||||
bool isKirinCpu();
|
||||
bool isQingsongDevice();
|
||||
bool isGreatwallDevice();
|
||||
}
|
||||
|
||||
#endif // FUNCTIONS_H
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
#include "global.h"
|
||||
|
||||
#include <QSettings>
|
||||
#include <QDBusReply>
|
||||
#include <QGSettings>
|
||||
#include <QApplication>
|
||||
#include <QDBusInterface>
|
||||
#include <QFile>
|
||||
#include <QDebug>
|
||||
#include "translator.h"
|
||||
#include "path.h"
|
||||
|
||||
#include <kysdk/kysdk-system/libkysysinfo.h>
|
||||
|
||||
QSettings *Global::g_settings = nullptr;
|
||||
Translator *Global::translator = nullptr;
|
||||
SqliteHandle *Global::g_sqlite = nullptr;
|
||||
GlobalConfig *Global::g_config = nullptr;
|
||||
QGSettings *Global::g_gsettings = nullptr;
|
||||
ShortCutSetting *Global::g_shortCut = nullptr;
|
||||
ShortCutSetting *Global::g_shortcut = nullptr;
|
||||
QGSettings *Global::g_gsettings_control_center = nullptr;
|
||||
Mpv::PlayState Global::g_playstate = Mpv::Idle;
|
||||
bool Global::isWayland = false;
|
||||
bool Global::isTablet = false;
|
||||
//KPlayControl *Global::k_playcontrol = KPlayControl::getInstanece();
|
||||
|
||||
using namespace Global;
|
||||
|
||||
void Global::global_init() {
|
||||
|
||||
// Translator
|
||||
translator = new Translator();
|
||||
void Global::initGlobal() {
|
||||
|
||||
// g_settings
|
||||
QString filename = Paths::iniPath() + "/kylin-video3.ini";
|
||||
|
@ -43,16 +43,18 @@ void Global::global_init() {
|
|||
isWayland = QString(qgetenv("XDG_SESSION_TYPE")) == "wayland";
|
||||
|
||||
g_gsettings = new QGSettings(ORG_UKUI_STYLE);
|
||||
g_gsettings_control_center = new QGSettings(PERSONALISE_SHEME);
|
||||
if (QGSettings::isSchemaInstalled(PERSONALISE_SHEME))
|
||||
g_gsettings_control_center = new QGSettings(PERSONALISE_SHEME);
|
||||
|
||||
g_shortCut = ShortCutSetting::getInstance(g_settings);
|
||||
g_shortcut = ShortCutSetting::getInstance(g_settings);
|
||||
g_sqlite = SqliteHandle::getInstance(dbname);
|
||||
g_config = GlobalConfig::getInstance();
|
||||
}
|
||||
|
||||
void Global::global_end() {
|
||||
delete g_gsettings;
|
||||
delete g_gsettings_control_center;
|
||||
delete g_settings;
|
||||
delete translator;
|
||||
QDBusInterface dbus("com.kylin.statusmanager.interface",
|
||||
"/",
|
||||
"com.kylin.statusmanager.interface",
|
||||
QDBusConnection::sessionBus(),
|
||||
nullptr);
|
||||
QDBusReply<bool> tmp_val = dbus.call("get_current_tabletmode");
|
||||
isTablet = tmp_val.value();
|
||||
}
|
||||
|
|
|
@ -17,20 +17,26 @@
|
|||
#define MENUWIDTH 180
|
||||
#define MENU_BAR_BTN_SIZE 30
|
||||
#define CONTRAL_BAR_BTN_SIZE 16
|
||||
#define THEME_BUTTON_SIZE 36
|
||||
#define THEME_BUTTON_SIZE_TABLET 48
|
||||
|
||||
class QSettings;
|
||||
class Translator;
|
||||
class QGSettings;
|
||||
class ShortCutSetting;
|
||||
|
||||
//using namespace Control;
|
||||
#define KYLIN_USER_GUIDE_PATH "/"
|
||||
#define KYLIN_USER_GUIDE_SERVICE "com.kylinUserGuide.hotel"
|
||||
#define KYLIN_USER_GUIDE_INTERFACE "com.guide.hotel"
|
||||
|
||||
#define PERSONALISE_SHEME "org.ukui.control-center.personalise"
|
||||
#define ORG_UKUI_STYLE "org.ukui.style"
|
||||
#define STYLE_UKUI_DEFAULT "ukui-default"
|
||||
#define STYLE_UKUI_BLACK "ukui-black"
|
||||
#define STYLE_UKUI_LIGHT "ukui-light"
|
||||
#define STYLE_UKUI_BLACK "ukui-dark"
|
||||
#define ICO_DIR_DEFAULT "ico_light"
|
||||
#define ICO_DIR_DBLACK "ico"
|
||||
#define FOLLOW_SYS_THEME false
|
||||
#define FOLLOW_SYS_THEME true
|
||||
|
||||
namespace Global {
|
||||
|
||||
|
@ -46,14 +52,11 @@ extern QGSettings *g_gsettings_control_center;
|
|||
extern QSettings *g_settings;
|
||||
extern SqliteHandle *g_sqlite;
|
||||
extern GlobalConfig *g_config;
|
||||
extern ShortCutSetting *g_shortCut;
|
||||
extern ShortCutSetting *g_shortcut;
|
||||
extern bool isWayland;
|
||||
extern bool isTablet;
|
||||
|
||||
//! Translator (for changing language)
|
||||
extern Translator * translator;
|
||||
|
||||
void global_init();
|
||||
void global_end();
|
||||
void initGlobal();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
#include "global/global.h"
|
||||
#include "global/globalsignal.h"
|
||||
#include "global/functions.h"
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
#include <thread>
|
||||
#include <QStandardPaths>
|
||||
|
||||
using namespace Global;
|
||||
|
||||
|
@ -231,17 +233,34 @@ void GlobalConfig::updatePredefinedList()
|
|||
|
||||
QStringList itemList;
|
||||
itemList.append("1002:6611:-1:300:AMD Graphics Card R7");
|
||||
itemList.append("1002:6613:-1:300:AMD Graphics Card R7");
|
||||
// 下面这个显卡老,共性说不走硬解,不然的话 s3 回来会卡,需要重启才行
|
||||
itemList.append("1002:6766:-1:300:AMD Graphics Card Caicos");
|
||||
|
||||
// 这个显卡也不走硬解,共性确认过
|
||||
itemList.append("1002:6779:-1:300:AMD Graphics Card Caicos");
|
||||
|
||||
itemList.append("1002:-1:-1:300:AMD Graphics Card");
|
||||
itemList.append("0709:0201:30000:0:709 Graphics Card");
|
||||
itemList.append("10de:-1:-1:0:Nvidia Graphics Card");
|
||||
itemList.append("1ed5:0101:-1:0:Moore Threads Graphics Card");
|
||||
itemList.append("1ed5:0102:-1:0:Moore Threads Graphics Card");
|
||||
itemList.append("1ed5:0105:-1:0:Moore Threads Graphics Card");
|
||||
itemList.append("1ed5:0106:-1:0:Moore Threads Graphics Card");
|
||||
itemList.append("8086:9a49:-1:0:Iris Xe Graphics");
|
||||
itemList.append("0731:-1:-1:0:JINGJIA MICRO JMX200 Graphics Card");
|
||||
itemList.append("126f:-1:-1:0:SM750/SM768");
|
||||
itemList.append("0731:-1:-1:0:JINGJIA MICRO Graphics Card");
|
||||
// itemList.append("126f:-1:-1:0:SM750/SM768"); // 暂时不要这个显卡判断
|
||||
itemList.append("0709:0001:-1:0:709 GP101 Graphics Card");
|
||||
itemList.append("1a03:-1:-1:0:BMCd");
|
||||
itemList.append("1d17:3d00:30000:0:Zhaoxin Device 3d00");
|
||||
itemList.append("6766:3d00:30000:0:Zhaoxin Device 3d00");
|
||||
itemList.append("6766:3d02:30000:0:Zhaoxin Device 3d00");
|
||||
itemList.append("1d17:3d00:30000:0:ZhaoXin Graphics Card");
|
||||
itemList.append("1d17:3d01:30000:0:ZhaoXin Graphics Card");
|
||||
itemList.append("1d17:3a04:30000:0:ZhaoXin Graphics Card");
|
||||
itemList.append("6766:3d00:30000:0:GlenFly Graphics Card");
|
||||
itemList.append("6766:3d02:30000:0:GlenFly Graphics Card");
|
||||
itemList.append("1db7:dc20:-1:0:X100 Series");
|
||||
itemList.append("1ec8:9800:-1:0:XinDong Card");
|
||||
itemList.append("0014:7a06:-1:0:LongXin 7a1000 Card");
|
||||
itemList.append("0014:7a36:-1:0:LongXin 7a2000 Card");
|
||||
itemList.append("1a03:-1:-1:0:BMCd");
|
||||
|
||||
foreach (QString item, itemList) {
|
||||
item = item.trimmed();
|
||||
|
@ -330,7 +349,8 @@ void GlobalConfig::updatePcieList()
|
|||
GlobalConfig::HardwareDecodecType GlobalConfig::getHardwareDecodingType()
|
||||
{
|
||||
//默认值为-1,表示使用软解
|
||||
HwType = DEFAULT_SOFTWARE;
|
||||
m_hardware_type = DEFAULT_SOFTWARE;
|
||||
m_video_output_type = VO_OPENGL;
|
||||
|
||||
updatePredefinedList();
|
||||
|
||||
|
@ -346,48 +366,137 @@ GlobalConfig::HardwareDecodecType GlobalConfig::getHardwareDecodingType()
|
|||
KyInfo("Find %s device(%04x:%04x.%04x), "
|
||||
"use predefine score: %d\n",
|
||||
predefined.description.toUtf8().data(),
|
||||
predefined.vid, predefined.pid,
|
||||
predefined.cid, predefined.score);
|
||||
char vidstr[128] = {0}, pidstr[128] = {0};
|
||||
snprintf(vidstr, sizeof(vidstr), "%04x", predefined.vid);
|
||||
snprintf(pidstr, sizeof(pidstr), "%04x", predefined.pid);
|
||||
info.vid, info.pid,
|
||||
info.cid, predefined.score);
|
||||
char vidstr[128] = {0}, pidstr[128] = {0}, cidstr[128] = {0};
|
||||
snprintf(vidstr, sizeof(vidstr), "%04x", info.vid);
|
||||
snprintf(pidstr, sizeof(pidstr), "%04x", info.pid);
|
||||
snprintf(cidstr, sizeof(cidstr), "%04x", info.cid);
|
||||
QString vid = QString::fromStdString(std::string(vidstr));
|
||||
QString pid = QString::fromStdString(std::string(pidstr));
|
||||
QString cid = QString::fromStdString(std::string(cidstr));
|
||||
//Find AMD Graphics Card device(1002:ffff.ffffff), use predefine score: 300
|
||||
if (predefined.description == "AMD Graphics Card R7" && vid == "1002" && pid == "6611") {
|
||||
HwType = AMD_R7_SOFTWARE;
|
||||
if (predefined.description == "AMD Graphics Card R7" && vid == "1002" && (pid == "6611" || pid == "6613")) {
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = AMD_SOFTWARE;
|
||||
KyInfo() << "AMD_SOFTWARE";
|
||||
}
|
||||
if (predefined.description == "AMD Graphics Card Caicos" && vid == "1002" && (pid == "6766" || pid == "6779")) {
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = AMD_SOFTWARE;
|
||||
KyInfo() << "AMD_SOFTWARE";
|
||||
}
|
||||
if (predefined.description == "AMD Graphics Card Lexa" && vid == "1002" && pid == "6987") {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = AMD_VAAPI;
|
||||
KyInfo() << "AMD_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "AMD Graphics Card" && vid == "1002") {
|
||||
HwType = AMD_VDPAU;
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = AMD_VDPAU;
|
||||
KyInfo() << "AMD_VDPAU";
|
||||
}
|
||||
else if (predefined.description == "Iris Xe Graphics" && vid == "8086" && pid == "9a49") {
|
||||
HwType = INTEL_IrisXe_VAAPI;
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = INTEL_IrisXe_VAAPI;
|
||||
KyInfo() << "INTEL_IrisXe_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "JINGJIA MICRO JMX200 Graphics Card" && vid == "0731") {
|
||||
HwType = JMX200_VDPAU;
|
||||
else if (predefined.description == "Moore Threads Graphics Card"
|
||||
&& vid == "1ed5"
|
||||
&& (pid == "0101" || pid == "0102" || pid == "0105" || pid == "0106")) {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = MooreThreads_VAAPI;
|
||||
KyInfo() << "MooreThreads_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "JINGJIA MICRO Graphics Card" && vid == "0731" && pid.startsWith("9")) {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = JM9X_VAAPI;
|
||||
KyInfo() << "JM9X_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "JINGJIA MICRO Graphics Card" && vid == "0731" && pid.startsWith("7")) {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = JM7X_VDPAU;
|
||||
KyInfo() << "JM7X_VDPAU";
|
||||
}
|
||||
else if (predefined.description == "709 GP101 Graphics Card" && vid == "0709") {
|
||||
HwType = GP101_SOFTWARE;
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = GP101_SOFTWARE;
|
||||
KyInfo() << "GP101_SOFTWARE";
|
||||
}
|
||||
else if (predefined.description == "Zhaoxin Device 3d00" && (vid == "1d17" || vid == "6766")) {
|
||||
HwType = ZDE_VDPAU; // zxe3d00, 默认走 VDPAU 硬件解码
|
||||
else if (predefined.description == "ZhaoXin Graphics Card"
|
||||
&& vid == "1d17"
|
||||
&& pid == "3d01"
|
||||
&& cid == "30000") {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = ZDE_VAAPI; // zxe3d01, 默认走 VAAPI 硬件解码
|
||||
KyInfo() << "ZDE_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "X100 Series" && vid == "1db7") {
|
||||
HwType = X100_GPU; // X100
|
||||
else if (predefined.description == "ZhaoXin Graphics Card"
|
||||
&& vid == "1d17"
|
||||
&& pid == "3d00"
|
||||
&& cid == "30000") {
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = ZDE_VDPAU; // zxe3d00, 默认走 VDPAU 硬件解码
|
||||
KyInfo() << "ZDE_VDPAU";
|
||||
}
|
||||
else if (predefined.description == "ZhaoXin Graphics Card"
|
||||
&& vid == "1d17"
|
||||
&& pid == "3a04"
|
||||
&& cid == "30000") {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = ZDE_VAAPI; // zxe3a04, 默认走 VAAPI 硬件解码
|
||||
KyInfo() << "ZDE_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "GlenFly Graphics Card"
|
||||
&& vid == "6766"
|
||||
&& (pid == "3d00" || pid == "3d02")
|
||||
&& cid == "30000") {
|
||||
// 格兰菲显卡 vaapi 输出效果好一点,很多显卡都是 vaapi 输出效果优于 opengl,mpv可能需要优化,支持vaapi输出
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = GlenFly_VAAPI; // 格兰菲显卡, 默认走 VAAPI 硬件解码
|
||||
KyInfo() << "GlenFly_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "X100 Series" && vid == "1db7" && pid == "dc20") {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = X100_GPU; // X100
|
||||
KyInfo() << "X100_GPU";
|
||||
}
|
||||
else if (predefined.description == "Nvidia Graphics Card" && vid == "10de") {
|
||||
HwType = Nvidia_VDPAU_COPY;
|
||||
m_video_output_type = VO_OPENGL;
|
||||
m_hardware_type = Nvidia_VDPAU_COPY;
|
||||
KyInfo() << "Nvidia_VDPAU_COPY";
|
||||
}
|
||||
else if (predefined.description == "709 Graphics Card" && vid == "0709" && pid == "0201" && cid == "30000") {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = GPU_709_VAAPI;
|
||||
KyInfo() << "GPU_709_VAAPI";
|
||||
}
|
||||
else if (predefined.description == "SM750/SM768" && vid == "126f") {
|
||||
HwType = Sm768_SOFTWARE;
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = Sm768_SOFTWARE;
|
||||
KyInfo() << "Sm768_SOFTWARE";
|
||||
}
|
||||
return HwType;
|
||||
else if (predefined.description == "XinDong Card" && vid == "1ec8") {
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = XINDONG_GPU;
|
||||
KyInfo() << "XINDONG_GPU";
|
||||
}
|
||||
else if ((predefined.description == "LongXin 7a1000 Card" || predefined.description == "LongXin 7a2000 Card")
|
||||
&& vid == "0014"
|
||||
&& (pid == "7a06" || pid == "7a36")) {
|
||||
// 龙芯集显不要直接返回接着循环判断是否有独显
|
||||
m_video_output_type = VO_WID;
|
||||
m_hardware_type = LONGXIN_INTEGRATED_GRAPHICS;
|
||||
KyInfo() << "LONGXIN_INTEGRATED_GRAPHICS";
|
||||
continue;
|
||||
}
|
||||
return m_hardware_type;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HwType;
|
||||
return m_hardware_type;
|
||||
}
|
||||
|
||||
void GlobalConfig::reset()
|
||||
|
@ -407,6 +516,9 @@ void GlobalConfig::reset()
|
|||
|
||||
screenShotSaveToClip.first = screenShotSaveToClip.second = g_settings->value("General/screenshot_save_to_file").toBool();
|
||||
screenShotPath.first = screenShotPath.second = g_settings->value("General/screenshot_path").toString();
|
||||
if (screenShotPath.first.length() == 0) {
|
||||
screenShotPath.second = QStandardPaths::writableLocation(QStandardPaths::PicturesLocation);
|
||||
}
|
||||
screenShotFormat.first = screenShotFormat.second = g_settings->value("General/screenshot_format").toString();
|
||||
screenShotCurrentSize.first = screenShotCurrentSize.second = g_settings->value("General/screenshot_size").toBool();
|
||||
|
||||
|
@ -424,7 +536,7 @@ void GlobalConfig::reset()
|
|||
videoOutput.first = videoOutput.second = g_settings->value("General/video_output").toString();
|
||||
if (videoDecoder.first == "") {
|
||||
HardwareDecodecType decodeType = getHardwareDecodingType();
|
||||
if (decodeType == AMD_R7_SOFTWARE) {
|
||||
if (decodeType == AMD_SOFTWARE) {
|
||||
videoOutput.second = tr("auto");
|
||||
videoDecoder.second = "no";
|
||||
}
|
||||
|
@ -432,15 +544,45 @@ void GlobalConfig::reset()
|
|||
videoOutput.second = "gpu";
|
||||
videoDecoder.second = "vdpau";
|
||||
}
|
||||
else if (decodeType == AMD_VAAPI) {
|
||||
videoOutput.second = "vaapi";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
else if (decodeType == INTEL_IrisXe_VAAPI) {
|
||||
videoOutput.second = "gpu";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
else if (decodeType == MooreThreads_VAAPI) {
|
||||
videoOutput.second = "gpu";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
else if (decodeType == ZDE_VDPAU_WID) {
|
||||
videoOutput.second = "vdpau";
|
||||
videoDecoder.second = "vdpau";
|
||||
}
|
||||
else if (decodeType == ZDE_VDPAU) {
|
||||
videoOutput.second = tr("auto");
|
||||
videoDecoder.second = "vdpau";
|
||||
}
|
||||
else if (decodeType == JMX200_VDPAU) {
|
||||
else if (decodeType == ZDE_VAAPI) {
|
||||
videoOutput.second = "vaapi";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
else if (decodeType == GlenFly_VAAPI) {
|
||||
videoOutput.second = "vaapi";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
else if (decodeType == JM9X_VAAPI) {
|
||||
if (Functions::isQingsongDevice()) {
|
||||
videoOutput.second = tr("auto");
|
||||
videoDecoder.second = "no";
|
||||
}
|
||||
else {
|
||||
videoOutput.second = "vaapi";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
}
|
||||
else if (decodeType == JM7X_VDPAU) {
|
||||
if (Functions::isQingsongDevice()) {
|
||||
videoOutput.second = tr("auto");
|
||||
videoDecoder.second = "no";
|
||||
|
@ -458,6 +600,10 @@ void GlobalConfig::reset()
|
|||
videoOutput.second = "x11";
|
||||
videoDecoder.second = "no";
|
||||
}
|
||||
else if (decodeType == GPU_709_VAAPI) {
|
||||
videoOutput.second = "vaapi";
|
||||
videoDecoder.second = "vaapi";
|
||||
}
|
||||
else if (decodeType == Nvidia_VDPAU_COPY) {
|
||||
videoOutput.second = tr("auto");
|
||||
videoDecoder.second = "vdpau-copy";
|
||||
|
@ -488,7 +634,8 @@ void GlobalConfig::reset()
|
|||
#if defined(__loongarch__)
|
||||
videoDecodeThreads.second = sysconf(_SC_NPROCESSORS_ONLN) * 2 + 1;
|
||||
#else
|
||||
videoDecodeThreads.second = 4;
|
||||
int hardwareMaxThread = std::thread::hardware_concurrency();
|
||||
videoDecodeThreads.second = hardwareMaxThread == 0 ? 4 : hardwareMaxThread;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef GLOBALCONFIG_H
|
||||
#define GLOBALCONFIG_H
|
||||
|
||||
|
||||
#include <QObject>
|
||||
#include <QMap>
|
||||
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
// 预设 pcie 设备
|
||||
struct PciePredefined {
|
||||
int vid;
|
||||
|
@ -28,26 +29,49 @@ public:
|
|||
enum HardwareDecodecType {
|
||||
NO_TYPE = -1,
|
||||
DEFAULT_SOFTWARE = 0,
|
||||
AMD_R7_SOFTWARE,
|
||||
AMD_SOFTWARE,
|
||||
AMD_VAAPI,
|
||||
AMD_VDPAU,
|
||||
JMX200_VDPAU,
|
||||
JM7X_VDPAU,
|
||||
JM9X_VAAPI,
|
||||
GP101_SOFTWARE,
|
||||
Sm768_SOFTWARE,
|
||||
Nvidia_VDPAU_COPY,
|
||||
MooreThreads_VAAPI,
|
||||
ZDE_VDPAU_WID,
|
||||
ZDE_VDPAU,
|
||||
ZDE_VAAPI,
|
||||
GPU_709_VAAPI,
|
||||
GlenFly_VAAPI,
|
||||
X100_GPU,
|
||||
INTEL_IrisXe_VAAPI,
|
||||
XINDONG_GPU,
|
||||
LONGXIN_INTEGRATED_GRAPHICS,
|
||||
OTHER_SOFTWARE
|
||||
};
|
||||
|
||||
enum VideoOutputType {
|
||||
VO_UNKNOW,
|
||||
VO_OPENGL,
|
||||
VO_WID
|
||||
};
|
||||
|
||||
static GlobalConfig* getInstance();
|
||||
void reset();
|
||||
|
||||
void clearChange();
|
||||
void flushChange();
|
||||
|
||||
HardwareDecodecType hardwareType(){
|
||||
return HwType == NO_TYPE ? getHardwareDecodingType() : HwType;
|
||||
HardwareDecodecType hardwareType() {
|
||||
return m_hardware_type == NO_TYPE ? getHardwareDecodingType() : m_hardware_type;
|
||||
}
|
||||
|
||||
VideoOutputType videoOutputType() {
|
||||
if (m_video_output_type == VO_UNKNOW) {
|
||||
getHardwareDecodingType();
|
||||
}
|
||||
KyInfo() << "set video out " << (m_video_output_type == VO_OPENGL ? "opengl" : "wid");
|
||||
return m_video_output_type;
|
||||
}
|
||||
|
||||
QPair<bool, bool> miniToTray; // 缩小到托盘
|
||||
|
@ -94,7 +118,8 @@ private:
|
|||
private:
|
||||
void updatePredefinedList();
|
||||
void updatePcieList();
|
||||
HardwareDecodecType HwType = NO_TYPE;
|
||||
VideoOutputType m_video_output_type = VO_UNKNOW;
|
||||
HardwareDecodecType m_hardware_type = NO_TYPE;
|
||||
HardwareDecodecType getHardwareDecodingType();
|
||||
};
|
||||
|
||||
|
|
|
@ -40,6 +40,8 @@ public:
|
|||
void play_pause() {emit sigPlayPause();}
|
||||
void nFrame() {emit sigNFrame();}
|
||||
void pFrame() {emit sigPFrame();}
|
||||
void progressUp(int sec) {emit sigProgressUp(sec);}
|
||||
void progressDown(int sec) {emit sigProgressDown(sec);}
|
||||
void forword(bool b) {emit sigForword(b);}
|
||||
void backword(bool b) {emit sigBackword(b);}
|
||||
void seek(int seek_time) {emit sigSeek(seek_time);}
|
||||
|
@ -48,6 +50,7 @@ public:
|
|||
void selectFile() {emit sigSelectFile();}
|
||||
void selectDir() {emit sigSelectDir();}
|
||||
void selectSub() {emit sigSelectSub();}
|
||||
void openUrl() {emit sigOpenUrl();}
|
||||
void addSub(QString file) {emit sigAddSub(file);}
|
||||
void setSubId(int id) {emit sigSubId(id);}
|
||||
void setSubNext() {emit sigSubNext();}
|
||||
|
@ -111,6 +114,7 @@ signals:
|
|||
void sigPlayWidgetClicked(); // 播放界面被单击
|
||||
void sigSelectFile(); // 选择一个文件
|
||||
void sigSelectDir(); // 选择一个目录
|
||||
void sigOpenUrl(); // 打开 Url
|
||||
void sigTheme(int); // 设置主题 (0:跟随系统/1:亮色主题/2:暗色主题)
|
||||
void sigRightMenuShow(); // 显示右键菜单
|
||||
void sigOpen(QString, int); // 打开文件
|
||||
|
@ -119,6 +123,8 @@ signals:
|
|||
void sigPlayPause(); // 播放暂停 给不知道播放状态的人用
|
||||
void sigSeek(int); // 跳转
|
||||
void sigRestart(); // 重新播放
|
||||
void sigProgressUp(int); // 进度加
|
||||
void sigProgressDown(int); // 进度减
|
||||
void sigBackword(bool); // 快退 true:10秒 false:30秒
|
||||
void sigForword(bool); // 快进 true:10秒 false:30秒
|
||||
void sigPFrame(); // 上一帧
|
||||
|
|
|
@ -8,12 +8,12 @@
|
|||
|
||||
#include <ukui-log4qt.h>
|
||||
|
||||
QString Paths::app_path = "";
|
||||
QString Paths::config_path = "";
|
||||
QString Paths::log_path = "";
|
||||
QString Paths::m_app_path = "";
|
||||
QString Paths::m_log_path = "";
|
||||
QString Paths::m_config_path = "";
|
||||
|
||||
void Paths::setAppPath(QString path) {
|
||||
app_path = path;
|
||||
m_app_path = path;
|
||||
}
|
||||
|
||||
QString Paths::previewPath()
|
||||
|
@ -27,15 +27,15 @@ QString Paths::previewPath()
|
|||
}
|
||||
|
||||
QString Paths::appPath() {
|
||||
return app_path;
|
||||
return m_app_path;
|
||||
}
|
||||
|
||||
QString Paths::translationPath()
|
||||
{
|
||||
QString path;
|
||||
QString t_path;
|
||||
if (QDir("/usr/share/kylin-video/translations").exists()) {
|
||||
path = "/usr/share/kylin-video/translations";
|
||||
return path;
|
||||
t_path = "/usr/share/kylin-video/translations";
|
||||
return t_path;
|
||||
}
|
||||
else {
|
||||
return appPath() + "/translations";
|
||||
|
@ -51,27 +51,27 @@ QString Paths::qtTranslationPath() {
|
|||
}
|
||||
|
||||
void Paths::setConfigPath(QString path) {
|
||||
config_path = path;
|
||||
QDir dir(config_path);
|
||||
m_config_path = path;
|
||||
QDir dir(m_config_path);
|
||||
if(!dir.exists())
|
||||
{
|
||||
dir.mkdir(config_path);
|
||||
dir.mkdir(m_config_path);
|
||||
}
|
||||
}
|
||||
|
||||
void Paths::setLogPath(QString path)
|
||||
{
|
||||
log_path = path;
|
||||
QDir dir(config_path);
|
||||
m_log_path = path;
|
||||
QDir dir(m_config_path);
|
||||
if(!dir.exists())
|
||||
{
|
||||
dir.mkdir(log_path);
|
||||
dir.mkdir(m_log_path);
|
||||
}
|
||||
}
|
||||
|
||||
QString Paths::configPath() {
|
||||
if (!config_path.isEmpty()) {
|
||||
return config_path;
|
||||
if (!m_config_path.isEmpty()) {
|
||||
return m_config_path;
|
||||
} else {
|
||||
QDir dir(QDir::homePath() + "/.config/kylin-video");
|
||||
if(!dir.exists())
|
||||
|
@ -88,8 +88,8 @@ QString Paths::iniPath() {
|
|||
|
||||
QString Paths::logPath()
|
||||
{
|
||||
if (!log_path.isEmpty()) {
|
||||
return log_path;
|
||||
if (!m_log_path.isEmpty()) {
|
||||
return m_log_path;
|
||||
} else {
|
||||
QDir dir(QDir::homePath() + "/.cache/kylin-video");
|
||||
if(!dir.exists())
|
||||
|
|
|
@ -28,9 +28,9 @@ public:
|
|||
static QString subtitleStyleFile();
|
||||
|
||||
private:
|
||||
static QString app_path;
|
||||
static QString config_path;
|
||||
static QString log_path;
|
||||
static QString m_app_path;
|
||||
static QString m_log_path;
|
||||
static QString m_config_path;
|
||||
};
|
||||
|
||||
#endif // PATH_H
|
||||
|
|
|
@ -45,6 +45,7 @@ void ShortCutSetting::initData()
|
|||
// 文件
|
||||
m_shortcut_map[m_open_file] = newShortCut("open file", tr("open file"), "Ctrl+O");
|
||||
m_shortcut_map[m_open_dir] = newShortCut("open dir", tr("open dir"), "Ctrl+F");
|
||||
m_shortcut_map[m_open_url] = newShortCut("open url", tr("open url"), "Ctrl+U");
|
||||
m_shortcut_map[m_prev_file] = newShortCut("prev file", tr("prev file"), "Page Up");
|
||||
m_shortcut_map[m_next_file] = newShortCut("next file", tr("next file"), "Page Down");
|
||||
|
||||
|
@ -180,6 +181,7 @@ void ShortCutSetting::initShortCutFunc()
|
|||
// 文件
|
||||
m_open_file = [](){g_user_signal->selectFile();};
|
||||
m_open_dir = [](){g_user_signal->selectDir();};
|
||||
m_open_url = [](){g_user_signal->openUrl();};
|
||||
m_prev_file = [](){g_user_signal->playPrev(true);};
|
||||
m_next_file = [](){g_user_signal->playNext(true);};
|
||||
|
||||
|
@ -197,7 +199,8 @@ void ShortCutSetting::initShortCutFunc()
|
|||
|
||||
// 图像
|
||||
m_fullscreen = [](){g_user_signal->fullScreen();};
|
||||
m_mini_mode = [](){g_user_signal->changeShowMode();};
|
||||
if (!Global::isTablet)
|
||||
m_mini_mode = [](){g_user_signal->changeShowMode();};
|
||||
m_screenshot = [](){g_user_signal->screenShot(false);};
|
||||
m_cut = [](){;};
|
||||
m_light_up = [](){g_user_signal->brightnessUp();};
|
||||
|
@ -212,7 +215,8 @@ void ShortCutSetting::initShortCutFunc()
|
|||
// 声音
|
||||
m_volume_up = [](){g_user_signal->setVolumeUp(10);};
|
||||
m_volume_down = [](){g_user_signal->setVolumeDown(10);};
|
||||
m_mute = [](){g_user_signal->setMute();};
|
||||
if (!Global::isTablet)
|
||||
m_mute = [](){g_user_signal->setMute();};
|
||||
m_audio_next = [](){g_user_signal->setAudioNext();};
|
||||
m_default_channel = [](){g_user_signal->setChannel(Mpv::Stereo);};
|
||||
m_left_channel = [](){g_user_signal->setChannel(Mpv::Left);};
|
||||
|
|
|
@ -65,10 +65,11 @@ private:
|
|||
|
||||
// 所有快捷键事件,快捷键主要和右键菜单联系,QFunctionPointer - QShortCut - 右键菜单QAction
|
||||
QFunctionPointer m_exit; // 关闭
|
||||
QFunctionPointer m_helpDoc; // 打开帮助文档
|
||||
QFunctionPointer m_helpDoc; // 打开帮助文档
|
||||
// 文件
|
||||
QFunctionPointer m_open_file; // 打开文件 默认: Ctrl+O
|
||||
QFunctionPointer m_open_dir; // 打开文件夹 默认: Ctrl+F
|
||||
QFunctionPointer m_open_url; // 打开url 默认: Ctrl+U
|
||||
QFunctionPointer m_prev_file; // 上一个文件 默认: Page Up
|
||||
QFunctionPointer m_next_file; // 下一个文件 默认: Page Down
|
||||
|
||||
|
|
|
@ -47,7 +47,6 @@ bool Translator::loadCatalog(QTranslator & t, QString name, QString locale, QStr
|
|||
void Translator::load(const QString &snap)
|
||||
{
|
||||
QString locale = QLocale::system().name();
|
||||
|
||||
QString trans_path = Paths::translationPath();
|
||||
|
||||
QString qt_trans_path;
|
||||
|
|
46
src/main.cpp
|
@ -5,9 +5,10 @@
|
|||
#include <QScreen>
|
||||
#include <QIcon>
|
||||
|
||||
#include "testwidget.h"
|
||||
#include "mainwindow.h"
|
||||
#include "global/translator.h"
|
||||
#include "global/global.h"
|
||||
#include "global/functions.h"
|
||||
#include "global/globalconfig.h"
|
||||
|
||||
#include <ukui-log4qt.h>
|
||||
|
@ -15,8 +16,9 @@
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
initUkuiLog4qt("kylin-video");
|
||||
Global::initGlobal();
|
||||
|
||||
if(Global::isWayland)
|
||||
if(QString(qgetenv("XDG_SESSION_TYPE")) == "wayland")
|
||||
{
|
||||
#if 0
|
||||
qputenv("QT_QPA_PLATFORM", "wayland");
|
||||
|
@ -29,36 +31,44 @@ int main(int argc, char *argv[])
|
|||
#endif
|
||||
}
|
||||
|
||||
// if (Global::g_config->hardwareType() == GlobalConfig::INTEL_IrisXe_VAAPI)
|
||||
if (!Functions::isVirtualSuppotGpu() && GlobalConfig::getInstance()->hardwareType() != GlobalConfig::Nvidia_VDPAU_COPY)
|
||||
qputenv("QT_XCB_GL_INTEGRATION", "xcb_egl");
|
||||
|
||||
QApplication a(argc, argv);
|
||||
a.setWindowIcon(QIcon::fromTheme("kylin-video"));
|
||||
|
||||
Global::global_init();
|
||||
// Translator
|
||||
Translator *translator = new Translator();
|
||||
translator->load("");
|
||||
|
||||
// 加载 sdk 翻译
|
||||
QTranslator *tran = new QTranslator;
|
||||
if (QLocale::system().name() == "zh_CN")
|
||||
tran->load(":/translations/gui_zh_CN.qm");
|
||||
else if (QLocale::system().name() == "bo_CN")
|
||||
tran->load(":/translations/gui_bo_CN.qm");
|
||||
else if (QLocale::system().name() == "zh_HK")
|
||||
tran->load(":/translations/gui_bo_CN.qm");
|
||||
a.installTranslator(tran);
|
||||
|
||||
QStringList arg_list;
|
||||
for(int i=1; i<argc; i++)
|
||||
for (int i=1; i<argc; i++)
|
||||
{
|
||||
if (QString(argv[i]).startsWith("http"))
|
||||
{
|
||||
arg_list << QString(argv[i]);
|
||||
continue;
|
||||
}
|
||||
QFileInfo f(QString(argv[i]));
|
||||
if(f.isFile())
|
||||
arg_list << f.absoluteFilePath();
|
||||
}
|
||||
|
||||
MainWindow w(arg_list);
|
||||
// QWidget w;
|
||||
|
||||
if (Global::isWayland) {
|
||||
kdk::UkuiStyleHelper::self()->removeHeader(&w);
|
||||
w.show();
|
||||
kdk::WindowManager::setGeometry(w.windowHandle(),
|
||||
QRect(qApp->desktop()->geometry().center() - w.geometry().center(),
|
||||
QSize(w.size())));
|
||||
}
|
||||
else {
|
||||
w.show();
|
||||
w.move(qApp->primaryScreen()->availableGeometry().center() - w.geometry().center());
|
||||
}
|
||||
w.show();
|
||||
kdk::WindowManager::setGeometry(w.windowHandle(),
|
||||
QRect(qApp->desktop()->geometry().center() - w.geometry().center(),
|
||||
QSize(w.size())));
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#define MiniModeSize QSize(400, 225)
|
||||
|
||||
class HomePage;
|
||||
class AboutDialog;
|
||||
class ContralBar;
|
||||
class PlayXWidget;
|
||||
class PlayGLWidget;
|
||||
|
@ -21,6 +20,7 @@ class TitleWidget;
|
|||
class MusicWidget;
|
||||
class PlayListWidget;
|
||||
class MiniModeShade;
|
||||
class MediaInfoDialog;
|
||||
class QDBusInterface;
|
||||
class QLabel;
|
||||
|
||||
|
@ -36,42 +36,43 @@ public:
|
|||
signals:
|
||||
|
||||
private:
|
||||
QStackedWidget *m_stackedWidget;
|
||||
HomePage *m_homePage; // 主界面
|
||||
TitleMenu *m_titleMenu; // 标题栏菜单
|
||||
KRightClickMenu *m_rightClickMenu; // 右键菜单
|
||||
TitleWidget *m_titleWidget; // 标题栏
|
||||
ContralBar *m_contralBar; // 控制栏
|
||||
MusicWidget *m_musicWidget; // 音乐播放界面
|
||||
PlayListWidget *m_playListWidget; // 播放列表界面
|
||||
SystemTrayIcon *m_trayIcon;
|
||||
AboutDialog *m_aboutDialog;
|
||||
QStackedWidget *m_stacked_widget;
|
||||
HomePage *m_home_page; // 主界面
|
||||
TitleMenu *m_title_menu; // 标题栏菜单
|
||||
KRightClickMenu *m_right_click_menu; // 右键菜单
|
||||
TitleWidget *m_title_widget; // 标题栏
|
||||
ContralBar *m_contral_bar; // 控制栏
|
||||
MusicWidget *m_music_widget; // 音乐播放界面
|
||||
PlayListWidget *m_playlist_widget; // 播放列表界面
|
||||
SystemTrayIcon *m_tray_icon;
|
||||
|
||||
QString m_currentFile;
|
||||
MediaInfoDialog *m_dialog_media_info;
|
||||
QString m_current_file;
|
||||
|
||||
MiniModeShade *m_miniModeShade; // mini 模式遮罩
|
||||
QWidget *m_playWidget;
|
||||
MiniModeShade *m_mini_mode_shade; // mini 模式遮罩
|
||||
QWidget *m_play_widget;
|
||||
|
||||
QRect m_normalRect;
|
||||
QRect m_normal_rect;
|
||||
|
||||
Mpv::FileInfo m_fileInfo;
|
||||
Mpv::PlayState m_playStateForS34;
|
||||
Mpv::VideoAspect m_vAspect; // 视频比例
|
||||
Mpv::FileInfo m_file_info;
|
||||
Mpv::VideoAspect m_video_aspect; // 视频比例
|
||||
MpvCore *m_core;
|
||||
|
||||
bool m_isActive;
|
||||
bool m_exitFlag;
|
||||
bool m_isMiniMode;
|
||||
bool m_isMaxWindow;
|
||||
bool m_isFullScreen;
|
||||
bool m_canHideAll;
|
||||
bool m_needPlayWhenMin;
|
||||
bool m_needPlayWhenS34;
|
||||
bool m_isScreenLocked;
|
||||
bool m_is_top;
|
||||
bool m_is_active;
|
||||
bool m_is_mini_mode;
|
||||
bool m_is_maximized;
|
||||
bool m_is_fullscreen;
|
||||
bool m_is_tablet_mode;
|
||||
bool m_is_screen_locked = false;
|
||||
bool m_exit_flag;
|
||||
bool m_can_hide_all;
|
||||
bool m_need_play_when_min;
|
||||
bool m_need_play_when_s34;
|
||||
|
||||
QDBusInterface *m_dbusInterface;
|
||||
quint32 m_inhibitValue; // 阻止锁屏cookie
|
||||
quint64 m_windowId;
|
||||
QDBusInterface *m_dbus_interface;
|
||||
quint32 m_inhibit_value; // 阻止锁屏cookie
|
||||
quint64 m_window_id;
|
||||
|
||||
public slots:
|
||||
void kylin_video_play_request(QStringList filelist);
|
||||
|
@ -79,7 +80,9 @@ public slots:
|
|||
private slots:
|
||||
// s3 s4 处理
|
||||
void onPrepareForSleep(bool isSleep);
|
||||
#if 0
|
||||
void onPrepareForShutdown(bool Shutdown);
|
||||
#endif
|
||||
void onScreenLock();
|
||||
void onScreenUnlock();
|
||||
void onWiredControl(QString data);
|
||||
|
@ -87,6 +90,7 @@ private slots:
|
|||
|
||||
// 耳机插拔
|
||||
void inputDeviceGet(QString device);
|
||||
void uiModeChange(bool isTabletMode);
|
||||
|
||||
void slotQuit();
|
||||
void slotClose();
|
||||
|
@ -105,6 +109,7 @@ private slots:
|
|||
void slotChangePause();
|
||||
void slotOpenFile();
|
||||
void slotOpenDir();
|
||||
void slotOpenUrl();
|
||||
void slotPlayFile(QString file, int pos);
|
||||
void slotPlayWidgetClicked();
|
||||
void slotToTop(bool is_top = true);
|
||||
|
@ -121,7 +126,7 @@ private:
|
|||
void initPlayListWidget();
|
||||
void initMiniModeShade();
|
||||
void initContralBar();
|
||||
void initAboutDialog();
|
||||
void initMediaInfo();
|
||||
|
||||
void updateAspect();
|
||||
void resetLayout();
|
||||
|
@ -129,6 +134,7 @@ private:
|
|||
void appQuit();
|
||||
|
||||
void Single(QStringList filelist);
|
||||
void windowStateChange();
|
||||
|
||||
bool event(QEvent *event) override;
|
||||
void enterEvent(QEvent *event) override;
|
||||
|
@ -136,6 +142,7 @@ private:
|
|||
void resizeEvent(QResizeEvent *event) override;
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
// 以下实现文件拖入播放
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
|
|
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 394 B |
After Width: | Height: | Size: 394 B |
Before Width: | Height: | Size: 386 B After Width: | Height: | Size: 386 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 356 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 223 B |
After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 788 B After Width: | Height: | Size: 788 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 618 B |
Before Width: | Height: | Size: 661 B After Width: | Height: | Size: 661 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 618 B |
After Width: | Height: | Size: 412 B |
After Width: | Height: | Size: 412 B |