├── .gitignore ├── .gitmodules ├── ClickableMenu.cpp ├── ClickableMenu.h ├── DarkStyle.cpp ├── DarkStyle.h ├── EventFilter.cpp ├── EventFilter.h ├── LICENSE ├── README.md ├── Slider.cpp ├── Slider.h ├── Statistics.cpp ├── Statistics.h ├── StatisticsView.cpp ├── StatisticsView.h ├── Xuno-Mpv.ico ├── Xuno-Mpv.png ├── XunoBrowser.cpp ├── XunoBrowser.h ├── XunoPlayer-MPV.pro ├── XunoPlayer-MPV.pro.user ├── XunoPlayer-MPV_128x128.ico ├── XunoPlayerMPV.cpp ├── XunoPlayerMPV.h ├── common ├── Config.cpp ├── Config.h ├── ScreenSaver.cpp ├── ScreenSaver.h ├── common.cpp ├── common.h ├── common_export.h ├── qoptions.cpp ├── qoptions.h └── qthelper.hpp ├── config ├── ConfigDialog.cpp ├── ConfigDialog.h ├── ConfigPageBase.cpp ├── ConfigPageBase.h ├── ImageSequenceConfigPage.cpp ├── ImageSequenceConfigPage.h ├── MiscPage.cpp ├── MiscPage.h ├── VideoEQConfigPage.cpp ├── VideoEQConfigPage.h ├── WebConfigPage.cpp ├── WebConfigPage.h ├── configwebmemu.cpp ├── configwebmemu.h └── configwebmemu.ui ├── darkstyle.qrc ├── darkstyle ├── darkstyle.qss ├── icon_branch_closed.png ├── icon_branch_end.png ├── icon_branch_more.png ├── icon_branch_open.png ├── icon_checkbox_checked.png ├── icon_checkbox_checked_disabled.png ├── icon_checkbox_checked_pressed.png ├── icon_checkbox_indeterminate.png ├── icon_checkbox_indeterminate_disabled.png ├── icon_checkbox_indeterminate_pressed.png ├── icon_checkbox_unchecked.png ├── icon_checkbox_unchecked_disabled.png ├── icon_checkbox_unchecked_pressed.png ├── icon_close.png ├── icon_radiobutton_checked.png ├── icon_radiobutton_checked_disabled.png ├── icon_radiobutton_checked_pressed.png ├── icon_radiobutton_unchecked.png ├── icon_radiobutton_unchecked_disabled.png ├── icon_radiobutton_unchecked_pressed.png ├── icon_restore.png ├── icon_undock.png └── icon_vline.png ├── main.cpp ├── mpvwidget.cpp ├── mpvwidget.h ├── playlist ├── PlayList.cpp ├── PlayList.h ├── PlayListDelegate.cpp ├── PlayListDelegate.h ├── PlayListItem.cpp ├── PlayListItem.h ├── PlayListModel.cpp ├── PlayListModel.h └── common │ ├── common.cpp │ └── common.h ├── ring.h ├── theme.qrc ├── theme ├── dark │ ├── backward.svg │ ├── capture.svg │ ├── close.svg │ ├── forward.svg │ ├── fullscreen.svg │ ├── help.svg │ ├── info.svg │ ├── menu.svg │ ├── open.svg │ ├── pause.svg │ ├── play.svg │ ├── sound.svg │ └── stop.svg ├── default │ ├── backward.svg │ ├── close.svg │ ├── forward.svg │ ├── fullscreen.svg │ ├── help.svg │ ├── info.svg │ ├── mute.svg │ ├── open.svg │ ├── pause.svg │ ├── play.svg │ ├── stop.svg │ └── volume.svg ├── down_arrow-bw.png ├── fullscreen.png ├── media-pause-16.png ├── media-play-16.png └── up_arrow-bw.png ├── tools └── linux │ └── deployqtappQt515.sh └── version.h /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | 4 | # Compiled Object files 5 | *.slo 6 | *.lo 7 | *.o 8 | *.obj 9 | 10 | # Precompiled Headers 11 | *.gch 12 | *.pch 13 | 14 | # Compiled Dynamic libraries 15 | *.so 16 | *.dylib 17 | *.dll 18 | 19 | # Fortran module files 20 | *.mod 21 | *.smod 22 | 23 | # Compiled Static libraries 24 | *.lai 25 | *.la 26 | *.a 27 | *.lib 28 | 29 | # Executables 30 | *.exe 31 | *.out 32 | *.app 33 | *.user 34 | XunoPlayer-MPV.pro.user 35 | XunoPlayer-MPV.pro.user.4.8-pre1 36 | *.9603a89 37 | XunoPlayer-MPV.pro.user 38 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "shaders"] 2 | path = shaders 3 | url = git://github.com/Xuno/mpv-prescalers.git 4 | -------------------------------------------------------------------------------- /ClickableMenu.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #include "ClickableMenu.h" 23 | #include 24 | 25 | ClickableMenu::ClickableMenu(QWidget *parent) : 26 | QMenu(parent) 27 | { 28 | } 29 | 30 | ClickableMenu::ClickableMenu(const QString &title, QWidget *parent) : 31 | QMenu(title, parent) 32 | { 33 | } 34 | 35 | void ClickableMenu::mouseReleaseEvent(QMouseEvent *e) 36 | { 37 | QAction *action = actionAt(e->pos()); 38 | if (action) { 39 | action->activate(QAction::Trigger); 40 | return; 41 | } 42 | QMenu::mouseReleaseEvent(e); 43 | } 44 | 45 | -------------------------------------------------------------------------------- /ClickableMenu.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #ifndef CLICKABLEMENU1_H 23 | #define CLICKABLEMENU1_H 24 | 25 | #include 26 | 27 | class ClickableMenu : public QMenu 28 | { 29 | Q_OBJECT 30 | public: 31 | explicit ClickableMenu(QWidget *parent = 0); 32 | explicit ClickableMenu(const QString& title, QWidget *parent = 0); 33 | 34 | protected: 35 | virtual void mouseReleaseEvent(QMouseEvent *); 36 | 37 | }; 38 | 39 | #endif // CLICKABLEMENU1_H 40 | -------------------------------------------------------------------------------- /DarkStyle.cpp: -------------------------------------------------------------------------------- 1 | #include "DarkStyle.h" 2 | 3 | DarkStyle::DarkStyle(): 4 | DarkStyle(styleBase()) 5 | { } 6 | 7 | DarkStyle::DarkStyle(QStyle *style): 8 | QProxyStyle(style) 9 | { } 10 | 11 | QStyle *DarkStyle::styleBase(QStyle *style) const { 12 | static QStyle *base = !style ? QStyleFactory::create("Fusion") : style; 13 | return base; 14 | } 15 | 16 | QStyle *DarkStyle::baseStyle() const 17 | { 18 | return styleBase(); 19 | } 20 | 21 | void DarkStyle::polish(QPalette &palette) 22 | { 23 | // modify palette to dark 24 | palette.setColor(QPalette::Window,QColor(53,53,53)); 25 | palette.setColor(QPalette::WindowText,Qt::white); 26 | palette.setColor(QPalette::Disabled,QPalette::WindowText,QColor(127,127,127)); 27 | palette.setColor(QPalette::Base,QColor(42,42,42)); 28 | palette.setColor(QPalette::AlternateBase,QColor(66,66,66)); 29 | palette.setColor(QPalette::ToolTipBase,Qt::white); 30 | palette.setColor(QPalette::ToolTipText,Qt::white); 31 | palette.setColor(QPalette::Text,Qt::white); 32 | palette.setColor(QPalette::Disabled,QPalette::Text,QColor(127,127,127)); 33 | palette.setColor(QPalette::Dark,QColor(35,35,35)); 34 | palette.setColor(QPalette::Shadow,QColor(20,20,20)); 35 | palette.setColor(QPalette::Button,QColor(30,30,30)); 36 | palette.setColor(QPalette::ButtonText,Qt::white); 37 | palette.setColor(QPalette::Disabled,QPalette::ButtonText,QColor(127,127,127)); 38 | palette.setColor(QPalette::BrightText,Qt::red); 39 | palette.setColor(QPalette::Link,QColor(42,130,218)); 40 | palette.setColor(QPalette::Highlight,QColor(42,130,218)); 41 | palette.setColor(QPalette::Disabled,QPalette::Highlight,QColor(80,80,80)); 42 | palette.setColor(QPalette::HighlightedText,Qt::white); 43 | palette.setColor(QPalette::Disabled,QPalette::HighlightedText,QColor(127,127,127)); 44 | } 45 | 46 | void DarkStyle::polish(QApplication *app) 47 | { 48 | if (!app) return; 49 | 50 | // increase font size for better reading, 51 | // setPointSize was reduced from +2 because when applied this way in Qt5, the font is larger than intended for some reason 52 | #ifndef unix 53 | QFont defaultFont = QApplication::font(); 54 | defaultFont.setPointSize(defaultFont.pointSize()+1); 55 | app->setFont(defaultFont); 56 | #endif 57 | 58 | // loadstylesheet 59 | QFile qfDarkstyle(QString(":/darkstyle/darkstyle.qss")); 60 | if (qfDarkstyle.open(QIODevice::ReadOnly | QIODevice::Text)) 61 | { 62 | // set stylesheet 63 | QString qsStylesheet = QString(qfDarkstyle.readAll()); 64 | app->setStyleSheet(qsStylesheet); 65 | qfDarkstyle.close(); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /DarkStyle.h: -------------------------------------------------------------------------------- 1 | /* 2 | ############################################################################### 3 | # # 4 | # The MIT License # 5 | # # 6 | # Copyright (C) 2017 by Juergen Skrotzky (JorgenVikingGod@gmail.com) # 7 | # >> https://github.com/Jorgen-VikingGod # 8 | # # 9 | # Sources: https://github.com/Jorgen-VikingGod/Qt-Frameless-Window-DarkStyle # 10 | # # 11 | ############################################################################### 12 | */ 13 | 14 | #ifndef _DarkStyle_HPP 15 | #define _DarkStyle_HPP 16 | 17 | /* INCLUDE FILES **************************************************************/ 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | /* CLASS DECLARATION **********************************************************/ 25 | /** CMainWindow class is a simple singleton to adjust style/palette/stylesheets 26 | *******************************************************************************/ 27 | class DarkStyle : public QProxyStyle 28 | { 29 | Q_OBJECT 30 | // PUBLIC MEMBERS ************************************************************* 31 | // PROTECTED MEMBERS ********************************************************** 32 | // PRIVATE MEMBERS ************************************************************ 33 | // CONSTRUCTOR/DESTRUCTOR ***************************************************** 34 | // PUBLIC METHODS ************************************************************* 35 | public: 36 | DarkStyle(); 37 | explicit DarkStyle(QStyle *style); 38 | 39 | QStyle *baseStyle() const; 40 | 41 | void polish(QPalette &palette) override; 42 | void polish(QApplication *app) override; 43 | 44 | // PROTECTED METHODS ********************************************************** 45 | // PRIVATE METHODS ************************************************************ 46 | private: 47 | QStyle *styleBase(QStyle *style=Q_NULLPTR) const; 48 | }; 49 | 50 | #endif // _DarkStyle_HPP 51 | 52 | //***************************************************************************** 53 | // END OF FILE 54 | //***************************************************************************** 55 | -------------------------------------------------------------------------------- /EventFilter.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #ifndef QTAV_EVENTFILTER_H 23 | #define QTAV_EVENTFILTER_H 24 | 25 | /* 26 | * This class is used interally as QtAV's default event filter. It is suite for single player object 27 | */ 28 | #include 29 | #include 30 | //#include "filters/XunoGlslFilter.h" 31 | 32 | QT_BEGIN_NAMESPACE 33 | class QMenu; 34 | class QPoint; 35 | QT_END_NAMESPACE 36 | namespace QtAV { 37 | //class AVPlayer; 38 | } 39 | //for internal use 40 | class EventFilter : public QObject 41 | { 42 | Q_OBJECT 43 | public: 44 | explicit EventFilter(/*QtAV::AVPlayer *player*/); 45 | virtual ~EventFilter(); 46 | 47 | //void setXunoGLSLFilter(XunoGLSLFilter *value); 48 | 49 | signals: 50 | void helpRequested(); 51 | void showNextOSD(); 52 | 53 | public slots: 54 | void openLocalFile(); 55 | void openUrl(); 56 | void about(); 57 | void aboutFFmpeg(); 58 | void help(); 59 | 60 | protected: 61 | virtual bool eventFilter(QObject *, QEvent *); 62 | void showMenu(const QPoint& p); 63 | 64 | private: 65 | QMenu *menu; 66 | //XunoGLSLFilter *xunoGLSLFilter=Q_NULLPTR; 67 | }; 68 | 69 | 70 | class WindowEventFilter : public QObject 71 | { 72 | Q_OBJECT 73 | public: 74 | WindowEventFilter(QWidget *window); 75 | 76 | signals: 77 | void fullscreenChanged(); 78 | 79 | protected: 80 | virtual bool eventFilter(QObject *watched, QEvent *event); 81 | 82 | private: 83 | QWidget *mpWindow; 84 | QPoint gMousePos, iMousePos; 85 | bool enableMovingWindow; 86 | void setEnableMovingWindow(bool s); 87 | }; 88 | 89 | #endif // QTAV_EVENTFILTER_H 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [XunoPlayer-MPV](http://www.xuno.com) 2 | 3 | XunoPlayer-MPV is fork of [MPV multimedia playback library](https://github.com/mpv-player/mpv) based on MPlayer/mplayer2 and FFmpeg with a Qt GUI and enhanced user functionality optimized for High Quality 12-bit RGB AV1 & HEVC video. 4 | 5 | XunoPlayer has been added to FFmpeg projects page [http://ffmpeg.org/projects.html](http://ffmpeg.org/projects.html) 6 | 7 | **MPV is free software licensed under the terms of GPLv2 "or later" by default, LGPLv2.1 "or later" with --enable-lgpl. If you use MPV or its constituent libraries, you must adhere to the terms of the license in question.** 8 | 9 | 10 | 11 | # XunoPlayer-MPV based on MPV/MPlayer/mplayer2 12 | 13 | ![Alt text](http://www.xuno.com/images/XunoPlayer.jpg "XunoPlayer-MPV") 14 | 15 | ### MPV Features Added 16 | 17 |
  • Add DRM_PRIME Format Handling and Display for RockChip MPP decoders
  • 18 |
  • csputils: Add support for Display P3 primaries
  • 19 |
  • demux: support multiple seekable cached ranges, display cache ranges on OSC
  • 20 |
  • demux_playlist: support .url files
  • 21 |
  • dvb: Add multiple frontends support (up to 8)
  • 22 |
  • dvb: implement parsing of modulation for VDR-style channels config
  • 23 |
  • hwdec: add mediacodec hardware decoder for IMGFMT_MEDIACODEC frames,
  • 24 |
  • rename mediacodec to mediacodec-copy
  • 25 |
  • lua: integrate stats.lua script (bound to i/I by default)
  • 26 |
  • vd_lavc: add support for nvdec hwaccel
  • 27 |
  • vo_gpu: add android opengl backend
  • 28 |
  • vo_gpu: initial d3d11 support
  • 29 |
  • vo_gpu: vulkan support
  • 30 | -------------------------------------------------------------------------------- /Slider.cpp: -------------------------------------------------------------------------------- 1 | /* smplayer, GUI front-end for mplayer. 2 | Copyright (C) 2006-2010 Ricardo Villalba 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) version 3, or any 8 | later version accepted by the membership of KDE e.V. (or its 9 | successor approved by the membership of KDE e.V.), Trolltech ASA 10 | (or its successors, if any) and the KDE Free Qt Foundation, which shall 11 | act as a proxy defined in Section 6 of version 3 of the license. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library. If not, see . 20 | */ 21 | 22 | #define CODE_FOR_CLICK 1 // 0 = old code, 1 = code copied from QSlider, 2 = button swap 23 | 24 | #include "Slider.h" 25 | #include 26 | #include 27 | #include 28 | 29 | #if CODE_FOR_CLICK <= 1 30 | #include 31 | #if CODE_FOR_CLICK == 1 32 | #include 33 | #endif 34 | #endif 35 | 36 | #if QT_VERSION < 0x040300 37 | #define initStyleOption initStyleOption_Qt430 38 | #endif //QT_VERSION 39 | 40 | 41 | Slider::Slider(QWidget *parent): 42 | QSlider(parent) 43 | { 44 | setOrientation(Qt::Horizontal); 45 | setMouseTracking(true); //mouseMoveEvent without press. 46 | } 47 | 48 | Slider::~Slider() 49 | { 50 | } 51 | 52 | #if CODE_FOR_CLICK == 1 53 | // Function copied from qslider.cpp 54 | inline int Slider::pick(const QPoint &pt) const 55 | { 56 | return orientation() == Qt::Horizontal ? pt.x() : pt.y(); 57 | } 58 | 59 | // Function copied from qslider.cpp and modified to make it compile 60 | void Slider::initStyleOption_Qt430(QStyleOptionSlider *option) const 61 | { 62 | if (!option) 63 | return; 64 | 65 | option->initFrom(this); 66 | option->subControls = QStyle::SC_None; 67 | option->activeSubControls = QStyle::SC_None; 68 | option->orientation = orientation(); 69 | option->maximum = maximum(); 70 | option->minimum = minimum(); 71 | option->tickPosition = (QSlider::TickPosition) tickPosition(); 72 | option->tickInterval = tickInterval(); 73 | option->upsideDown = (orientation() == Qt::Horizontal) ? 74 | (invertedAppearance() != (option->direction == Qt::RightToLeft)) 75 | : (!invertedAppearance()); 76 | option->direction = Qt::LeftToRight; // we use the upsideDown option instead 77 | option->sliderPosition = sliderPosition(); 78 | option->sliderValue = value(); 79 | option->singleStep = singleStep(); 80 | option->pageStep = pageStep(); 81 | if (orientation() == Qt::Horizontal) 82 | option->state |= QStyle::State_Horizontal; 83 | } 84 | 85 | // Function copied from qslider.cpp and modified to make it compile 86 | int Slider::pixelPosToRangeValue(int pos) const 87 | { 88 | QStyleOptionSlider opt; 89 | initStyleOption(&opt); 90 | QRect gr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); 91 | QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 92 | int sliderMin, sliderMax, sliderLength; 93 | if (orientation() == Qt::Horizontal) { 94 | sliderLength = sr.width(); 95 | sliderMin = gr.x(); 96 | sliderMax = gr.right() - sliderLength + 1; 97 | } else { 98 | sliderLength = sr.height(); 99 | sliderMin = gr.y(); 100 | sliderMax = gr.bottom() - sliderLength + 1; 101 | } 102 | return QStyle::sliderValueFromPosition(minimum(), maximum(), pos - sliderMin, 103 | sliderMax - sliderMin, opt.upsideDown); 104 | } 105 | 106 | void Slider::addVisualLimits(int min, int max) 107 | { 108 | setVisualMinLimit(min); 109 | setVisualMaxLimit(max); 110 | qDebug()<<"Slider::addVisualLimits"<setObjectName(QStringLiteral("line")); 138 | line->setGeometry(QRect(0, 0, 0, 8)); 139 | line->setFrameShadow(QFrame::Plain); 140 | line->setLineWidth(3); 141 | line->setFrameShape(QFrame::HLine); 142 | line->setContentsMargins(0,0,0,0); 143 | line->setStyleSheet("#line {color: #00FF00}"); //green 144 | //qDebug()<<"Slider::addVisualLimits"<subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderGroove, this); 153 | QRect sr = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 154 | // qDebug()<<"Slider::resizeEvent SC_SliderGroove"<setGeometry(r); 174 | // qDebug()<<"Slider::resizeEvent size,xmin,xmax"<setVisible(s); 183 | } 184 | } 185 | 186 | void Slider::resizeEvent(QResizeEvent *event) 187 | { 188 | if (line) { 189 | //QSize size = event->size(); 190 | updateLimitBar(); 191 | } 192 | QSlider::resizeEvent(event); 193 | } 194 | 195 | 196 | 197 | void Slider::enterEvent(QEvent *event) 198 | { 199 | emit onEnter(); 200 | QSlider::enterEvent(event); 201 | } 202 | 203 | void Slider::leaveEvent(QEvent *e) 204 | { 205 | emit onLeave(); 206 | QSlider::leaveEvent(e); 207 | } 208 | 209 | void Slider::mouseMoveEvent(QMouseEvent *e) 210 | { 211 | const int o = style()->pixelMetric(QStyle::PM_SliderLength ) - 1; 212 | int v = QStyle::sliderValueFromPosition(minimum(), maximum(), e->pos().x()-o/2, width()-o, false); 213 | emit onHover(e->x(), v); 214 | QSlider::mouseMoveEvent(e); 215 | } 216 | 217 | // Based on code from qslider.cpp 218 | void Slider::mousePressEvent(QMouseEvent *e) 219 | { 220 | qDebug("pressed (%d, %d)", e->pos().x(), e->pos().y()); 221 | if (e->button() == Qt::LeftButton) { 222 | QStyleOptionSlider opt; 223 | initStyleOption(&opt); 224 | const QRect sliderRect = style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, this); 225 | const QPoint center = sliderRect.center() - sliderRect.topLeft(); 226 | // to take half of the slider off for the setSliderPosition call we use the center - topLeft 227 | 228 | if (!sliderRect.contains(e->pos())) { 229 | qDebug("accept"); 230 | e->accept(); 231 | 232 | int v = pixelPosToRangeValue(pick(e->pos() - center)); 233 | setSliderPosition(v); 234 | triggerAction(SliderMove); 235 | setRepeatAction(SliderNoAction); 236 | emit sliderMoved(v);//TODO: ok? 237 | emit sliderPressed(); //TODO: ok? 238 | } else { 239 | QSlider::mousePressEvent(e); 240 | } 241 | } else { 242 | QSlider::mousePressEvent(e); 243 | } 244 | } 245 | #endif // CODE_FOR_CLICK == 1 246 | #if CODE_FOR_CLICK == 2 247 | void Slider::mousePressEvent(QMouseEvent *e) 248 | { 249 | // Swaps middle button click with left click 250 | if (e->button() == Qt::LeftButton) { 251 | QMouseEvent ev2(QEvent::MouseButtonRelease, e->pos(), e->globalPos(), Qt::MidButton, Qt::MidButton, e->modifiers()); 252 | QSlider::mousePressEvent(&ev2); 253 | } else if (e->button() == Qt::MidButton) { 254 | QMouseEvent ev2(QEvent::MouseButtonRelease, e->pos(), e->globalPos(), Qt::LeftButton, Qt::LeftButton, e->modifiers()); 255 | QSlider::mousePressEvent(&ev2); 256 | } 257 | else { 258 | QSlider::mousePressEvent(e); 259 | } 260 | } 261 | #endif // CODE_FOR_CLICK == 2 262 | #if CODE_FOR_CLICK == 0 263 | void Slider::mousePressEvent(QMouseEvent *e) 264 | { 265 | // FIXME: 266 | // The code doesn't work well with right to left layout, 267 | // so it's disabled. 268 | if (qApp->isRightToLeft()) { 269 | QSlider::mousePressEvent(e); 270 | return; 271 | } 272 | 273 | int range = maximum()-minimum(); 274 | int pos = (e->x() * range) / width(); 275 | //qDebug( "width: %d x: %d", width(), e->x()); 276 | //qDebug( "range: %d pos: %d value: %d", range, pos, value()); 277 | 278 | // Calculate how many positions takes the slider handle 279 | int metric = qApp->style()->pixelMetric(QStyle::PM_SliderLength); 280 | double one_tick_pixels = (double)width() / range; 281 | int slider_handle_positions = (int)(metric / one_tick_pixels); 282 | 283 | /* 284 | qDebug("metric: %d", metric ); 285 | qDebug("one_tick_pixels :%f", one_tick_pixels); 286 | qDebug("width() :%d", width()); 287 | qDebug("slider_handle_positions: %d", slider_handle_positions); 288 | */ 289 | 290 | if (abs(pos - value()) > slider_handle_positions) { 291 | setValue(pos); 292 | emit sliderMoved(pos); 293 | } else { 294 | QSlider::mousePressEvent(e); 295 | } 296 | } 297 | #endif 298 | -------------------------------------------------------------------------------- /Slider.h: -------------------------------------------------------------------------------- 1 | /* smplayer, GUI front-end for mplayer. 2 | Copyright (C) 2006-2010 Ricardo Villalba 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) version 3, or any 8 | later version accepted by the membership of KDE e.V. (or its 9 | successor approved by the membership of KDE e.V.), Trolltech ASA 10 | (or its successors, if any) and the KDE Free Qt Foundation, which shall 11 | act as a proxy defined in Section 6 of version 3 of the license. 12 | 13 | This library is distributed in the hope that it will be useful, 14 | but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | Lesser General Public License for more details. 17 | 18 | You should have received a copy of the GNU Lesser General Public 19 | License along with this library. If not, see . 20 | */ 21 | 22 | //TODO: hover support(like youtube and ExMplayer timeline preview) 23 | 24 | #ifndef SLIDER_H 25 | #define SLIDER_H 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | class Slider : public QSlider 34 | { 35 | Q_OBJECT 36 | public: 37 | Slider(QWidget *parent = 0); 38 | ~Slider(); 39 | void addVisualLimits(int min=0, int max=0); 40 | void setVisualMinLimit(int min); 41 | void setVisualMaxLimit(int max); 42 | void clearLimits(); 43 | void updateLimitBar(); 44 | void setVisibleVisualLimit(bool s); 45 | 46 | signals: 47 | void onEnter(); 48 | void onLeave(); 49 | void onHover(int pos, int value); 50 | 51 | protected: 52 | void addLimitBar(); 53 | virtual void enterEvent(QEvent* event); 54 | virtual void leaveEvent(QEvent *e); 55 | virtual void mouseMoveEvent(QMouseEvent* event); 56 | virtual void mousePressEvent(QMouseEvent *event); 57 | //virtual void paintEvent(QPaintEvent *e); 58 | virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; 59 | //#if CODE_FOR_CLICK == 1 60 | inline int pick(const QPoint &pt) const; 61 | int pixelPosToRangeValue(int pos) const; 62 | void initStyleOption_Qt430(QStyleOptionSlider *option) const; 63 | //#endif 64 | private: 65 | QFrame *line = 0; 66 | int visualLimitsMin = 0; 67 | int visualLimitsMax = 0; 68 | }; 69 | 70 | #endif //SLIDER_H 71 | 72 | -------------------------------------------------------------------------------- /Statistics.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV: Multimedia framework based on Qt and FFmpeg 3 | Copyright (C) 2012-2017 Wang Bin 4 | 5 | * This file is part of QtAV (from 2013) 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | ******************************************************************************/ 21 | 22 | #include "Statistics.h" 23 | #include "ring.h" 24 | 25 | 26 | 27 | Statistics::Common::Common(): 28 | available(false) 29 | , bit_rate(0) 30 | , frames(0) 31 | , frame_rate(0) 32 | { 33 | } 34 | 35 | Statistics::AudioOnly::AudioOnly(): 36 | sample_rate(0) 37 | , channels(0) 38 | , frame_size(0) 39 | , block_align(0) 40 | { 41 | } 42 | 43 | class Statistics::VideoOnly::Private : public QSharedData { 44 | public: 45 | Private() 46 | : pts(0) 47 | , history(ring(30)) 48 | {} 49 | qreal pts; 50 | ring history; 51 | }; 52 | 53 | Statistics::VideoOnly::VideoOnly(): 54 | width(0) 55 | , height(0) 56 | , coded_width(0) 57 | , coded_height(0) 58 | , gop_size(0) 59 | , rotate(0) 60 | , d(new Private()) 61 | { 62 | } 63 | 64 | Statistics::VideoOnly::VideoOnly(const VideoOnly& v) 65 | : width(v.width) 66 | , height(v.height) 67 | , coded_width(v.coded_width) 68 | , coded_height(v.coded_height) 69 | , gop_size(v.gop_size) 70 | , rotate(v.rotate) 71 | , d(v.d) 72 | { 73 | } 74 | 75 | Statistics::VideoOnly& Statistics::VideoOnly::operator =(const VideoOnly& v) 76 | { 77 | width = v.width; 78 | height = v.height; 79 | coded_width = v.coded_width; 80 | coded_height = v.coded_height; 81 | gop_size = v.gop_size; 82 | rotate = v.rotate; 83 | d = v.d; 84 | return *this; 85 | } 86 | 87 | Statistics::VideoOnly::~VideoOnly() 88 | { 89 | } 90 | 91 | qreal Statistics::VideoOnly::pts() const 92 | { 93 | return d->pts; 94 | } 95 | 96 | qint64 Statistics::VideoOnly::frameDisplayed(qreal pts) 97 | { 98 | d->pts = pts; 99 | const qint64 msecs = QDateTime::currentMSecsSinceEpoch(); 100 | const qreal t = (double)msecs/1000.0; 101 | d->history.push_back(t); 102 | return msecs; 103 | } 104 | // d->history is not thread safe! 105 | qreal Statistics::VideoOnly::currentDisplayFPS() const 106 | { 107 | if (d->history.empty()) 108 | return 0; 109 | // DO NOT use d->history.last-first 110 | const qreal dt = (double)QDateTime::currentMSecsSinceEpoch()/1000.0 - d->history.front(); 111 | // dt should be always > 0 because history stores absolute time 112 | if (qFuzzyIsNull(dt)) 113 | return 0; 114 | return (qreal)d->history.size()/dt; 115 | } 116 | 117 | Statistics::Statistics() 118 | { 119 | } 120 | 121 | Statistics::~Statistics() 122 | { 123 | } 124 | 125 | void Statistics::reset() 126 | { 127 | url = QString(); 128 | audio = Common(); 129 | video = Common(); 130 | audio_only = AudioOnly(); 131 | video_only = VideoOnly(); 132 | metadata.clear(); 133 | } 134 | 135 | void Statistics::setMpvWidget(MpvWidget *m) 136 | { 137 | m_mpv=m; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /Statistics.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV: Multimedia framework based on Qt and FFmpeg 3 | Copyright (C) 2012-2017 Wang Bin 4 | 5 | * This file is part of QtAV (from 2013) 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | ******************************************************************************/ 21 | 22 | #ifndef QTAV_STATISTICS_H 23 | #define QTAV_STATISTICS_H 24 | 25 | //#include 26 | #include 27 | #include 28 | #include 29 | #include "mpvwidget.h" 30 | 31 | /*! 32 | * values from functions are dynamically calculated 33 | */ 34 | 35 | 36 | class Statistics 37 | { 38 | public: 39 | Statistics(); 40 | ~Statistics(); 41 | void reset(); 42 | void setMpvWidget(MpvWidget *m); 43 | 44 | QString url; 45 | int bit_rate; 46 | QString format; 47 | QTime start_time, duration; 48 | QHash metadata; 49 | MpvWidget *m_mpv = 0; 50 | 51 | 52 | class Common { 53 | public: 54 | Common(); 55 | //TODO: dynamic bit rate compute 56 | bool available; 57 | QString codec, codec_long; 58 | QString decoder; 59 | QString decoder_detail; 60 | QTime current_time, total_time, start_time; 61 | int bit_rate; 62 | qint64 frames; 63 | qreal frame_rate; // average fps stored in media stream information 64 | //union member with ctor, dtor, copy ctor only works in c++11 65 | /*union { 66 | audio_only audio; 67 | video_only video; 68 | } only;*/ 69 | QHash metadata; 70 | } audio, video; //init them 71 | 72 | 73 | 74 | //from AVCodecContext 75 | class AudioOnly { 76 | public: 77 | AudioOnly(); 78 | int sample_rate; ///< samples per second 79 | int channels; ///< number of audio channels 80 | QString channel_layout; 81 | QString sample_fmt; ///< sample format 82 | /** 83 | * Number of samples per channel in an audio frame. 84 | * - decoding: may be set by some decoders to indicate constant frame size 85 | */ 86 | int frame_size; 87 | /** 88 | * number of bytes per packet if constant and known or 0 89 | * Used by some WAV based audio codecs. 90 | */ 91 | int block_align; 92 | } audio_only; 93 | 94 | 95 | 96 | //from AVCodecContext 97 | class VideoOnly { 98 | public: 99 | //union member with ctor, dtor, copy ctor only works in c++11 100 | VideoOnly(); 101 | VideoOnly(const VideoOnly&); 102 | VideoOnly& operator =(const VideoOnly&); 103 | ~VideoOnly(); 104 | // compute from pts history 105 | qreal currentDisplayFPS() const; 106 | qreal pts() const; // last pts 107 | 108 | int width, height; 109 | /** 110 | * Bitstream width / height, may be different from width/height if lowres enabled. 111 | * - decoding: Set by user before init if known. Codec should override / dynamically change if needed. 112 | */ 113 | int coded_width, coded_height; 114 | /** 115 | * the number of pictures in a group of pictures, or 0 for intra_only 116 | */ 117 | int gop_size; 118 | QString pix_fmt; 119 | int rotate; 120 | /// return current absolute time (seconds since epcho 121 | qint64 frameDisplayed(qreal pts); // used to compute currentDisplayFPS() 122 | private: 123 | class Private; 124 | QExplicitlySharedDataPointer d; 125 | } video_only; 126 | }; 127 | 128 | 129 | 130 | #endif // QTAV_STATISTICS_H 131 | -------------------------------------------------------------------------------- /StatisticsView.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "StatisticsView.h" 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | QStringList getBaseInfoKeys() { 30 | return QStringList() 31 | << QObject::tr("Url") 32 | << QObject::tr("Format") 33 | << QObject::tr("Bit rate") 34 | << QObject::tr("Start time") 35 | << QObject::tr("Duration") 36 | ; 37 | } 38 | 39 | QStringList getCommonInfoKeys() { 40 | return QStringList() 41 | << QObject::tr("Available") 42 | << QObject::tr("Codec") 43 | << QObject::tr("Decoder") 44 | << QObject::tr("Decoder detail") 45 | << QObject::tr("Total time") 46 | << QObject::tr("Start time") 47 | << QObject::tr("Bit rate") 48 | << QObject::tr("Frames") 49 | << QObject::tr("FPS") // avg_frame_rate. guessed by FFmpeg 50 | ; 51 | } 52 | 53 | QStringList getVideoInfoKeys() { 54 | return getCommonInfoKeys() 55 | << QObject::tr("FPS Now") //current display fps 56 | << QObject::tr("Pixel format") 57 | << QObject::tr("Size") //w x h 58 | << QObject::tr("Coded size") // w x h 59 | << QObject::tr("GOP size") 60 | ; 61 | } 62 | QStringList getAudioInfoKeys() { 63 | return getCommonInfoKeys() 64 | << QObject::tr("Sample format") 65 | << QObject::tr("Sample rate") 66 | << QObject::tr("Channels") 67 | << QObject::tr("Channel layout") 68 | << QObject::tr("Frame size") 69 | ; 70 | } 71 | 72 | QVariantList getBaseInfoValues(const Statistics& s) { 73 | return QVariantList() 74 | << s.url 75 | << s.format 76 | << QString::number(s.bit_rate/1000).append(QString::fromLatin1(" Kb/s")) 77 | << s.start_time.toString(QString::fromLatin1("HH:mm:ss")) 78 | << s.duration.toString(QString::fromLatin1("HH:mm:ss")) 79 | ; 80 | } 81 | 82 | QList getVideoInfoValues(const Statistics& s) { 83 | return QList() 84 | << s.video.available 85 | << QString::fromLatin1("%1 (%2)").arg(s.video.codec).arg(s.video.codec_long) 86 | << s.video.decoder 87 | << s.video.decoder_detail 88 | << s.video.total_time.toString(QString::fromLatin1("HH:mm:ss")) 89 | << s.video.start_time.toString(QString::fromLatin1("HH:mm:ss")) 90 | << QString::number(s.video.bit_rate/1000).append(QString::fromLatin1(" Kb/s")) 91 | << s.video.frames 92 | << s.video.frame_rate 93 | << s.video.frame_rate 94 | << s.video_only.pix_fmt 95 | << QString::fromLatin1("%1x%2").arg(s.video_only.width).arg(s.video_only.height) 96 | << QString::fromLatin1("%1x%2").arg(s.video_only.coded_width).arg(s.video_only.coded_height) 97 | << s.video_only.gop_size 98 | ; 99 | } 100 | QList getAudioInfoValues(const Statistics& s) { 101 | return QList() 102 | << s.audio.available 103 | << QString::fromLatin1("%1 (%2)").arg(s.audio.codec).arg(s.audio.codec_long) 104 | << s.audio.decoder 105 | << s.audio.decoder_detail 106 | << s.audio.total_time.toString(QString::fromLatin1("HH:mm:ss")) 107 | << s.audio.start_time.toString(QString::fromLatin1("HH:mm:ss")) 108 | << QString::number(s.audio.bit_rate/1000).append(QString::fromLatin1(" Kb/s")) 109 | << s.audio.frames 110 | << s.audio.frame_rate 111 | << s.audio_only.sample_fmt 112 | << QString::number(s.audio_only.sample_rate).append(QString::fromLatin1(" Hz")) 113 | << s.audio_only.channels 114 | << s.audio_only.channel_layout 115 | << s.audio_only.frame_size 116 | ; 117 | } 118 | 119 | 120 | StatisticsView::StatisticsView(QWidget *parent) : 121 | QDialog(parent) 122 | , mTimer(0) 123 | , mpFPS(Q_NULLPTR) 124 | , mpAudioBitRate(Q_NULLPTR) 125 | , mpVideoBitRate(Q_NULLPTR) 126 | { 127 | setWindowTitle(tr("Media info")); 128 | setModal(false); 129 | setWindowFlags(windowFlags() | Qt::WindowStaysOnTopHint); 130 | mpView = new QTreeWidget(); 131 | mpView->setAnimated(true); 132 | mpView->setHeaderHidden(false); 133 | mpView->setColumnCount(2); 134 | mpView->headerItem()->setText(0, tr("Key")); 135 | mpView->headerItem()->setText(1, tr("Value")); 136 | initBaseItems(&mBaseItems); 137 | mpView->addTopLevelItems(mBaseItems); 138 | mpMetadata = new QTreeWidgetItem(); 139 | mpMetadata->setText(0, QObject::tr("Metadata")); 140 | mpView->addTopLevelItem(mpMetadata); 141 | QTreeWidgetItem *item = createNodeWithItems(mpView, QObject::tr("Video"), getVideoInfoKeys(), &mVideoItems); 142 | mpFPS = item->child(9); 143 | //mpVideoBitRate = 144 | mpVideoMetadata = new QTreeWidgetItem(item); 145 | mpVideoMetadata->setText(0, QObject::tr("Metadata")); 146 | mpView->addTopLevelItem(item); 147 | item = createNodeWithItems(mpView, QObject::tr("Audio"), getAudioInfoKeys(), &mAudioItems); 148 | //mpAudioBitRate = 149 | mpAudioMetadata = new QTreeWidgetItem(item); 150 | mpAudioMetadata->setText(0, QObject::tr("Metadata")); 151 | mpView->addTopLevelItem(item); 152 | mpView->resizeColumnToContents(0); //call this after content is done 153 | 154 | QPushButton *btn = new QPushButton(QObject::tr("Ok")); 155 | QHBoxLayout *btnLayout = new QHBoxLayout; 156 | btnLayout->addStretch(); 157 | btnLayout->addWidget(btn); 158 | QObject::connect(btn, SIGNAL(clicked()), SLOT(accept())); 159 | 160 | QVBoxLayout *vl = new QVBoxLayout(); 161 | vl->addWidget(mpView); 162 | vl->addLayout(btnLayout); 163 | setLayout(vl); 164 | } 165 | 166 | void StatisticsView::setStatistics(const Statistics& s) 167 | { 168 | mStatistics = s; 169 | QVariantList v = getBaseInfoValues(s); 170 | int i = 0; 171 | foreach(QTreeWidgetItem* item, mBaseItems) { 172 | if (item->data(1, Qt::DisplayRole) != v.at(i)) { 173 | item->setData(1, Qt::DisplayRole, v.at(i)); 174 | } 175 | ++i; 176 | } 177 | v = getVideoInfoValues(s); 178 | i = 0; 179 | foreach(QTreeWidgetItem* item, mVideoItems) { 180 | if (item->data(1, Qt::DisplayRole) != v.at(i)) { 181 | item->setData(1, Qt::DisplayRole, v.at(i)); 182 | } 183 | ++i; 184 | } 185 | v = getAudioInfoValues(s); 186 | i = 0; 187 | foreach(QTreeWidgetItem* item, mAudioItems) { 188 | if (item->data(1, Qt::DisplayRole) != v.at(i)) { 189 | item->setData(1, Qt::DisplayRole, v.at(i)); 190 | } 191 | ++i; 192 | } 193 | setMetadataItem(mpMetadata, s.metadata); 194 | setMetadataItem(mpVideoMetadata, s.video.metadata); 195 | setMetadataItem(mpAudioMetadata, s.audio.metadata); 196 | } 197 | 198 | void StatisticsView::hideEvent(QHideEvent *e) 199 | { 200 | QDialog::hideEvent(e); 201 | killTimer(mTimer); 202 | } 203 | 204 | void StatisticsView::showEvent(QShowEvent *e) 205 | { 206 | QDialog::showEvent(e); 207 | mTimer = startTimer(1000); 208 | } 209 | 210 | void StatisticsView::timerEvent(QTimerEvent *e) 211 | { 212 | if (e->timerId() != mTimer) 213 | return; 214 | if (mpFPS) { 215 | mpFPS->setData(1, Qt::DisplayRole, QString::number(mStatistics.video_only.currentDisplayFPS(), 'f', 2)); 216 | } 217 | } 218 | 219 | void StatisticsView::initBaseItems(QList *items) 220 | { 221 | QTreeWidgetItem *item = Q_NULLPTR; 222 | foreach(const QString& key, getBaseInfoKeys()) { 223 | item = new QTreeWidgetItem(0); 224 | item->setData(0, Qt::DisplayRole, key); 225 | items->append(item); 226 | } 227 | } 228 | 229 | QTreeWidgetItem* StatisticsView::createNodeWithItems(QTreeWidget *view, const QString &name, const QStringList &itemNames, QList *items) 230 | { 231 | QTreeWidgetItem *nodeItem = new QTreeWidgetItem(view); 232 | nodeItem->setData(0, Qt::DisplayRole, name); 233 | QTreeWidgetItem *item = Q_NULLPTR; 234 | foreach(const QString& key, itemNames) { 235 | item = new QTreeWidgetItem(nodeItem); 236 | item->setData(0, Qt::DisplayRole, key); 237 | nodeItem->addChild(item); 238 | if (items) 239 | items->append(item); 240 | } 241 | nodeItem->setExpanded(true); 242 | return nodeItem; 243 | } 244 | 245 | void StatisticsView::setMetadataItem(QTreeWidgetItem *parent, const QHash &metadata) 246 | { 247 | if (parent->childCount() > 0) { 248 | QList children(parent->takeChildren()); 249 | qDeleteAll(children); 250 | } 251 | QHash::const_iterator it = metadata.constBegin(); 252 | for (;it != metadata.constEnd(); ++it) { 253 | QTreeWidgetItem *item = new QTreeWidgetItem(parent); 254 | item->setText(0, it.key()); 255 | item->setText(1, it.value()); 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /StatisticsView.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef STATISTICSVIEW_H 22 | #define STATISTICSVIEW_H 23 | 24 | #include 25 | #include "Statistics.h" 26 | 27 | //using namespace QtAV; 28 | 29 | QT_BEGIN_NAMESPACE 30 | class QTreeWidget; 31 | class QTreeWidgetItem; 32 | QT_END_NAMESPACE 33 | class StatisticsView : public QDialog 34 | { 35 | Q_OBJECT 36 | public: 37 | explicit StatisticsView(QWidget *parent = 0); 38 | void setStatistics(const Statistics &s); 39 | 40 | protected: 41 | virtual void hideEvent(QHideEvent* e); 42 | virtual void showEvent(QShowEvent* e); 43 | virtual void timerEvent(QTimerEvent *e); 44 | 45 | signals: 46 | 47 | public slots: 48 | 49 | private: 50 | void initBaseItems(QList* items); 51 | QTreeWidgetItem* createNodeWithItems(QTreeWidget* view, const QString& name, const QStringList& itemNames, QList* items = 0); 52 | void setMetadataItem(QTreeWidgetItem* parent, const QHash& metadata); 53 | QTreeWidget *mpView; 54 | QList mBaseItems; 55 | QList mVideoItems; 56 | //TODO: multiple streams 57 | QList mAudioItems; 58 | Statistics mStatistics; 59 | int mTimer; 60 | 61 | QTreeWidgetItem *mpFPS, *mpAudioBitRate, *mpVideoBitRate; 62 | QTreeWidgetItem *mpMetadata, *mpAudioMetadata, *mpVideoMetadata; 63 | }; 64 | 65 | #endif // STATISTICSVIEW_H 66 | -------------------------------------------------------------------------------- /Xuno-Mpv.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/Xuno-Mpv.ico -------------------------------------------------------------------------------- /Xuno-Mpv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/Xuno-Mpv.png -------------------------------------------------------------------------------- /XunoBrowser.cpp: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | ** 3 | ** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies). 4 | ** Contact: http://www.qt-project.org/legal 5 | ** 6 | ** This file is part of the examples of the Qt Toolkit. 7 | ** 8 | ** $QT_BEGIN_LICENSE:BSD$ 9 | ** You may use this file under the terms of the BSD license as follows: 10 | ** 11 | ** "Redistribution and use in source and binary forms, with or without 12 | ** modification, are permitted provided that the following conditions are 13 | ** met: 14 | ** * Redistributions of source code must retain the above copyright 15 | ** notice, this list of conditions and the following disclaimer. 16 | ** * Redistributions in binary form must reproduce the above copyright 17 | ** notice, this list of conditions and the following disclaimer in 18 | ** the documentation and/or other materials provided with the 19 | ** distribution. 20 | ** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names 21 | ** of its contributors may be used to endorse or promote products derived 22 | ** from this software without specific prior written permission. 23 | ** 24 | ** 25 | ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 26 | ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 27 | ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 28 | ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 29 | ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 30 | ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 31 | ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 | ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 | ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 | ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 35 | ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." 36 | ** 37 | ** $QT_END_LICENSE$ 38 | ** 39 | ****************************************************************************/ 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include "XunoBrowser.h" 45 | 46 | //--------- myWebEnginePage ----------- 47 | 48 | myWebEnginePage::myWebEnginePage(QWebEngineProfile *profile, QObject *parent) 49 | :QWebEnginePage(profile,parent) 50 | { 51 | qDebug()<<"Consturtor myWebEnginePage"; 52 | } 53 | 54 | 55 | bool myWebEnginePage::checkAllowedMediaTypes(const QUrl &u) 56 | { 57 | QString uext=QFileInfo(u.fileName()).suffix(); 58 | return Allowed_MediaTypes.contains(uext); 59 | } 60 | 61 | bool myWebEnginePage::acceptNavigationRequest(const QUrl &url, QWebEnginePage::NavigationType type, bool isMainFrame) 62 | { 63 | qDebug()<<"myWebEnginePage"<setAutoFillBackground(true); 89 | QPalette pal = palette(); 90 | pal.setColor(QPalette::Window, Qt::white); 91 | this->setPalette(pal); 92 | this->setWindowTitle("XunoBrowser"); 93 | this->setWindowFlags(((this->windowFlags() | Qt::CustomizeWindowHint)& Qt::WindowMaximizeButtonHint & ~Qt::WindowContextHelpButtonHint) ); 94 | 95 | loading = new QLabel("\n Loading....",this); 96 | loading->setAlignment(Qt::AlignCenter); 97 | this->resize(QSize(600,40)); 98 | this->show(); 99 | 100 | //myWebEnginePage *page = new myWebEnginePage(); 101 | 102 | view = new QWebEngineView(this); 103 | profile=new QWebEngineProfile("xunoprofile",view); 104 | QString cagent=profile->httpUserAgent(); 105 | profile->setHttpUserAgent(cagent+" XunoPlayer-MPV/"+XunoVersion); 106 | page = new myWebEnginePage(profile, view); 107 | connect(page, SIGNAL(onClick(QUrl)), SLOT(linkClicked(QUrl))); 108 | view->setPage(static_cast(page)); 109 | 110 | //connect(view->page(), SIGNAL(urlChanged(QUrl)),SLOT(linkClicked(QUrl))); 111 | //view->page()->setLinkDelegationPolicy(QWebEnginePage::DelegateAllLinks); 112 | //TODO There is no way to connect a signal to run C++ code when a link is clicked. However, link clicks can be delegated to the Qt application instead of having the HTML handler engine process them by overloading the QWebEnginePage::acceptNavigationRequest() function. This is necessary when an HTML document is used as part of the user interface, and not to display external data, for example, when displaying a list of results. https://wiki.qt.io/Porting_from_QtWebKit_to_QtWebEngine 113 | 114 | 115 | connect(view, SIGNAL(titleChanged(QString)), SLOT(adjustTitle())); 116 | connect(view, SIGNAL(loadProgress(int)), SLOT(setProgress(int))); 117 | connect(view, SIGNAL(loadFinished(bool)), SLOT(finishLoading(bool))); 118 | //connect(view, SIGNAL(linkClicked(QUrl)), SLOT(linkClicked(QUrl))); 119 | //TODO There is no way to connect a signal .. https://wiki.qt.io/Porting_from_QtWebKit_to_QtWebEngine 120 | 121 | 122 | } 123 | 124 | XunoBrowser::~XunoBrowser() { 125 | //QWebEngineSettings::clearMemoryCaches(); 126 | delete page; 127 | delete profile; 128 | delete view; 129 | } 130 | 131 | void XunoBrowser::setUrl(const QUrl &url) { 132 | if (view->url()!=url) view->load(url); 133 | if (this->isMinimized()) this->showNormal(); 134 | this->setFocus(); 135 | } 136 | 137 | void XunoBrowser::setXUNOContentUrl(const QString &url) { 138 | XUNOContentUrl=url; 139 | } 140 | 141 | 142 | void XunoBrowser::adjustTitle() 143 | { 144 | if (progress <= 0 || progress >= 100) 145 | setWindowTitle((QString("XunoBrowser : %1").arg(view->title()))); 146 | else 147 | setWindowTitle(QString("XunoBrowser : %1 (%2%)").arg(view->title()).arg(progress)); 148 | } 149 | 150 | void XunoBrowser::setProgress(int p) 151 | { 152 | progress = p; 153 | adjustTitle(); 154 | } 155 | 156 | void XunoBrowser::adjustBrowserSize() 157 | { 158 | if (view && view->isHidden()){ 159 | view->resize(QSize(1100,870)); 160 | view->show(); 161 | this->setFocus(); 162 | this->adjustSize(); 163 | int screen=QApplication::desktop()->screenNumber(this); 164 | this->move(QApplication::desktop()->availableGeometry(screen).center() - this->rect().center()); 165 | } 166 | } 167 | 168 | 169 | void XunoBrowser::finishLoading(bool) 170 | { 171 | if (loading) { 172 | delete loading; // delete loading text... 173 | loading=nullptr; 174 | } 175 | progress = 100; 176 | adjustTitle(); 177 | if ((view->url()==QUrl("about:blank"))){ 178 | qDebug()<<"XunoBrowser::finishLoading() about:blank loaded"; 179 | return; 180 | } 181 | adjustBrowserSize(); 182 | } 183 | 184 | void XunoBrowser::hideEvent(QHideEvent *e) 185 | { 186 | qDebug("XunoBrowser::hideEvent"); 187 | QDialog::hideEvent(e); 188 | } 189 | 190 | void XunoBrowser::showEvent(QShowEvent *e) 191 | { 192 | qDebug("XunoBrowser::showEvent"); 193 | QDialog::showEvent(e); 194 | } 195 | 196 | 197 | void XunoBrowser::linkClicked(QUrl url){ 198 | qDebug("XunoBrowser::linkClicked %s",qPrintable(url.toString())); 199 | //if (same_site_domain(url,QUrl(XUNOContentUrl)) && !url.toString().contains("playlist")){ 200 | if (true){ 201 | qDebug("XunoBrowser::linkClicked pass %s",qPrintable(url.toString())); 202 | clickedUrl=url; 203 | this->hide(); 204 | emit clicked(); 205 | } 206 | // else{ 207 | // this->hide(); 208 | // // clickedUrl.clear(); 209 | // // view->load(url); 210 | // } 211 | } 212 | 213 | void XunoBrowser::setXunoVersion(const QString &value) 214 | { 215 | XunoVersion = value; 216 | } 217 | 218 | QUrl XunoBrowser::getClikedUrl(){ 219 | return clickedUrl; 220 | } 221 | 222 | void XunoBrowser::resizeEvent(QResizeEvent* e) { 223 | qDebug("XunoBrowser::resizeEvent"); 224 | if (view && view->isVisible()) { 225 | view->resize(this->size()); 226 | } 227 | QDialog::resizeEvent(e); 228 | } 229 | 230 | QUrl XunoBrowser::remove_fistsubdomain(QUrl url) 231 | { 232 | QString host = url.host(); 233 | QStringList hosts=host.split('.'); 234 | hosts.removeFirst(); 235 | url.setHost(hosts.join('.')); 236 | return url; 237 | } 238 | 239 | bool XunoBrowser::same_site_domain(const QUrl &url1, const QUrl &url2) 240 | { 241 | return (remove_fistsubdomain(url1).host() == remove_fistsubdomain(url2).host()); 242 | } 243 | 244 | -------------------------------------------------------------------------------- /XunoBrowser.h: -------------------------------------------------------------------------------- 1 | #ifndef XUNOBROWSER_H 2 | #define XUNOBROWSER_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | class QWebEngineView; 13 | class QLineEdit; 14 | class QLabel; 15 | 16 | //---------------------------------------------------------- 17 | 18 | class myWebEnginePage : public QWebEnginePage 19 | { 20 | Q_OBJECT 21 | signals: 22 | void onClick(QUrl url); 23 | public: 24 | explicit myWebEnginePage(QWebEngineProfile *profile, QObject *parent = Q_NULLPTR); 25 | bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame); 26 | bool checkAllowedMediaTypes(const QUrl &u); 27 | private: 28 | const QStringList Allowed_MediaTypes={"mp4","mkv","mov","mp4s","m3u8"}; 29 | 30 | 31 | }; 32 | 33 | //----------------------------------------------------------- 34 | 35 | 36 | class XunoBrowser : public QDialog 37 | { 38 | Q_OBJECT 39 | 40 | public: 41 | explicit XunoBrowser(QWidget *parent = nullptr, const QString &version="none"); 42 | ~XunoBrowser(); 43 | void setUrl(const QUrl& url); 44 | void setXUNOContentUrl(const QString &url); 45 | QUrl getClikedUrl(); 46 | void setXunoVersion(const QString &value); 47 | 48 | signals: 49 | void clicked(); 50 | 51 | protected slots: 52 | 53 | void adjustTitle(); 54 | void adjustBrowserSize(); 55 | void setProgress(int p); 56 | void finishLoading(bool); 57 | void linkClicked(QUrl url); 58 | 59 | private: 60 | QWebEngineView *view; 61 | QWebEngineProfile* profile; 62 | myWebEnginePage *page; 63 | QUrl remove_fistsubdomain(QUrl url); 64 | bool same_site_domain(const QUrl &url1, const QUrl &url2); 65 | // QLineEdit *locationEdit; 66 | // QAction *rotateAction; 67 | QLabel *loading; 68 | int progress; 69 | QUrl clickedUrl; 70 | QString XUNOContentUrl,XunoVersion; 71 | 72 | virtual void hideEvent(QHideEvent* e); 73 | virtual void showEvent(QShowEvent* e); 74 | virtual void resizeEvent(QResizeEvent* e); 75 | 76 | 77 | }; 78 | 79 | 80 | 81 | 82 | 83 | 84 | #endif // XUNOBROWSER_H 85 | -------------------------------------------------------------------------------- /XunoPlayer-MPV.pro: -------------------------------------------------------------------------------- 1 | #CONFIG -= app_bundle 2 | #CONFIG += console 3 | #CONFIG += windeployqt 4 | 5 | 6 | TEMPLATE = app 7 | 8 | QT += widgets 9 | QT += webenginewidgets 10 | QT += sql 11 | QT += network 12 | 13 | PROJECTROOT = $$PWD 14 | 15 | win32: { 16 | message("XunoPlayer-MPV WINDOWS") 17 | devtools=D:/develop-tools/ 18 | QT += winextras 19 | QT_CONFIG -= no-pkg-config 20 | CONFIG += link_pkgconfig 21 | QT_CONFIG -= no-pkg-config 22 | } else:unix:!macx:{ 23 | message("XunoPlayer-MPV UNIX") 24 | devtools=/home/lex/develop-tools 25 | } 26 | 27 | 28 | TARGET = XunoPlayer-MPV 29 | VER_MAJ = 0 30 | VER_MIN = 1 31 | VER_PAT = 5 32 | VERSION = $${VER_MAJ}.$${VER_MIN}.$${VER_PAT} 33 | 34 | 35 | GIT_VERSION = $$system(git --git-dir $$PWD/.git --work-tree $$PWD describe --always --tags) 36 | GIT_VERSION += \{$$system(git rev-parse --abbrev-ref HEAD)\} 37 | VERGITSTR = '\\"$${GIT_VERSION}\\"' 38 | 39 | DEFINES += VER_MAJ_STRING=$${VER_MAJ} 40 | DEFINES += VER_MIN_STRING=$${VER_MIN} 41 | DEFINES += VER_PAT_STRING=$${VER_PAT} 42 | DEFINES += VERSION_STRING=\\\"$${VER_MAJ}.$${VER_MIN}.$${VER_PAT}\\\" 43 | DEFINES += VERGIT=\"$${VERGITSTR}\" 44 | 45 | RC_ICONS = $${PROJECTROOT}/XunoPlayer-MPV_128x128.ico 46 | QMAKE_TARGET_COMPANY = "Aaex Corp. www.xuno.com. github.com/Xuno/XunoPlayer-MPV" 47 | QMAKE_TARGET_DESCRIPTION = "XunoPlayer-MPV. Aaex Corp. www.xuno.com." 48 | QMAKE_TARGET_COPYRIGHT = "Copyright (C) 2012-2021 Aaex Corp." 49 | QMAKE_TARGET_PRODUCT = "XunoPlayer-MPV $$1 " 50 | 51 | export(RC_ICONS) 52 | export(QMAKE_TARGET_COMPANY) 53 | export(QMAKE_TARGET_DESCRIPTION) 54 | export(QMAKE_TARGET_COPYRIGHT) 55 | export(QMAKE_TARGET_PRODUCT) 56 | 57 | 58 | 59 | 60 | 61 | HEADERS = \ 62 | XunoPlayerMpv.h \ 63 | XunoBrowser.h \ 64 | common/qthelper.hpp \ 65 | mpvwidget.h \ 66 | Slider.h \ 67 | ClickableMenu.h \ 68 | common/Config.h \ 69 | common/common.h \ 70 | common/common_export.h \ 71 | common/qoptions.h \ 72 | common/ScreenSaver.h \ 73 | EventFilter.h \ 74 | config/ConfigDialog.h \ 75 | config/ConfigPageBase.h \ 76 | config/configwebmemu.h \ 77 | config/WebConfigPage.h \ 78 | config/ImageSequenceConfigPage.h \ 79 | config/VideoEQConfigPage.h \ 80 | config/MiscPage.h \ 81 | playlist/PlayList.h \ 82 | playlist/PlayListDelegate.h \ 83 | playlist/PlayListItem.h \ 84 | playlist/PlayListModel.h \ 85 | StatisticsView.h \ 86 | Statistics.h \ 87 | DarkStyle.h \ 88 | version.h 89 | 90 | # mpv/client.h \ 91 | # mpv/opengl_cb.h \ 92 | # mpv/qthelper.hpp \ 93 | # mpv/stream_cb.h \ 94 | 95 | 96 | 97 | # playlist/PlayList.h \ 98 | # playlist/PlayListDelegate.h \ 99 | # playlist/PlayListItem.h \ 100 | # playlist/PlayListModel.h \ 101 | 102 | 103 | SOURCES = main.cpp \ 104 | XunoPlayerMpv.cpp \ 105 | ClickableMenu.cpp \ 106 | Slider.cpp \ 107 | mpvwidget.cpp \ 108 | XunoBrowser.cpp \ 109 | common/common.cpp \ 110 | common/Config.cpp \ 111 | common/qoptions.cpp \ 112 | common/ScreenSaver.cpp \ 113 | EventFilter.cpp \ 114 | config/ConfigDialog.cpp \ 115 | config/configwebmemu.cpp \ 116 | config/WebConfigPage.cpp \ 117 | config/ConfigPageBase.cpp \ 118 | config/ImageSequenceConfigPage.cpp \ 119 | config/MiscPage.cpp \ 120 | playlist/PlayList.cpp \ 121 | playlist/PlayListDelegate.cpp \ 122 | playlist/PlayListItem.cpp \ 123 | playlist/PlayListModel.cpp \ 124 | config/VideoEQConfigPage.cpp \ 125 | StatisticsView.cpp \ 126 | Statistics.cpp \ 127 | DarkStyle.cpp 128 | 129 | # playlist/PlayList.cpp \ 130 | # playlist/PlayListDelegate.cpp \ 131 | # playlist/PlayListItem.cpp \ 132 | # playlist/PlayListModel.cpp \ 133 | 134 | 135 | RESOURCES += \ 136 | theme.qrc \ 137 | darkstyle.qrc 138 | 139 | FORMS += \ 140 | config/configwebmemu.ui 141 | 142 | message("XunoPlayer-MPV DEFINES: "$$DEFINES) 143 | 144 | DISTFILES += \ 145 | darkstyle/icon_branch_closed.png \ 146 | darkstyle/icon_branch_end.png \ 147 | darkstyle/icon_branch_more.png \ 148 | darkstyle/icon_branch_open.png \ 149 | darkstyle/icon_checkbox_checked.png \ 150 | darkstyle/icon_checkbox_checked_disabled.png \ 151 | darkstyle/icon_checkbox_checked_pressed.png \ 152 | darkstyle/icon_checkbox_indeterminate.png \ 153 | darkstyle/icon_checkbox_indeterminate_disabled.png \ 154 | darkstyle/icon_checkbox_indeterminate_pressed.png \ 155 | darkstyle/icon_checkbox_unchecked.png \ 156 | darkstyle/icon_checkbox_unchecked_disabled.png \ 157 | darkstyle/icon_checkbox_unchecked_pressed.png \ 158 | darkstyle/icon_close.png \ 159 | darkstyle/icon_radiobutton_checked.png \ 160 | darkstyle/icon_radiobutton_checked_disabled.png \ 161 | darkstyle/icon_radiobutton_checked_pressed.png \ 162 | darkstyle/icon_radiobutton_unchecked.png \ 163 | darkstyle/icon_radiobutton_unchecked_disabled.png \ 164 | darkstyle/icon_radiobutton_unchecked_pressed.png \ 165 | darkstyle/icon_undock.png \ 166 | darkstyle/icon_vline.png \ 167 | images/icon_window_close.png \ 168 | images/icon_window_maximize.png \ 169 | images/icon_window_minimize.png \ 170 | images/icon_window_restore.png \ 171 | darkstyle/darkstyle.qss 172 | 173 | #MPV 174 | 175 | win32:{ 176 | #MPVDIR=$${devtools}/mpv/mpvlib/mpv-dev-20181002 177 | #MPVDIR=$${devtools}/mpv/byXunoBuild/build-shared-libmpv-2019-05-01 178 | #MPVDIR=$${devtools}/mpv/byXunoBuild/build-shared-libmpv-2019-10-11 179 | MPVDIR=$${devtools}/mpv/mpv-dev-x86_64-20210711-git-f049acf 180 | #LIBS += -L$${MPVDIR}/libmpv -lmpv.dll 181 | LIBS += -L$${MPVDIR} -llibmpv 182 | #HEADERS += \ 183 | # mpv/client.h \ 184 | # mpv/opengl_cb.h \ 185 | # mpv/qthelper.hpp \ 186 | # mpv/stream_cb.h 187 | 188 | INCLUDEPATH += $${MPVDIR}/include 189 | DEPENDPATH += $${MPVDIR}/include 190 | 191 | } 192 | else:unix:!macx:{ 193 | 194 | MPVDIR=$${devtools}/mpv/mpp-install 195 | FFMPEGDIR=$${devtools}/mpv/mpv-build/build_libs 196 | #MPVDIR=$${devtools}/mpv-player/mpv-build/build-XunoMpv-20190206 197 | #MPVDIR=$${devtools}/mpv-player/mpv-build 198 | #FFMPEGDIR=$${devtools}/ffmpeg/ffmpeg_sources/ffmpeg-build 199 | 200 | #QT_CONFIG -= no-pkg-config 201 | #INCLUDEPATH +=$${devtools}/mpv-player/git/mpv-build/build_libs/include 202 | #INCLUDEPATH +=$${devtools}/mpv-player/git/mpv-build/build_libs/include/libavformat 203 | #INCLUDEPATH +=$${devtools}/mpv-player/git/mpv-build/build_libs/include/libavcodec 204 | #INCLUDEPATH +=$${devtools}/mpv-player/git/mpv-build/build_libs/include/libavutil 205 | #INCLUDEPATH +=$${devtools}/mpv-player/git/mpv-build/build_libs/include/libswresample 206 | 207 | #INCLUDEPATH +=$${devtools}/ffmpeg/ffmpeg_sources/ffmpeg-build/include 208 | #INCLUDEPATH +=$${devtools}/ffmpeg/ffmpeg_sources/ffmpeg-build/include/libavformat 209 | #INCLUDEPATH +=$${devtools}/ffmpeg/ffmpeg_sources/ffmpeg-build/include/libavcodec 210 | #LIBS += -L$${devtools}/mpv-player/mpv-build/build-XunoMpv-20180404/lib 211 | 212 | LIBS += -L$${FFMPEGDIR}/lib 213 | LIBS += -L$${MPVDIR}/lib 214 | 215 | 216 | #PKG_CONFIG_PATH += $${PROJECTROOT}/pkgconfig:$PKG_CONFIG_PATH 217 | 218 | 219 | #PKG_CONFIG_PATH += $${devtools}/mpv-player/git/mpv-build/build_libs/lib/pkgconfig:$PKG_CONFIG_PATH 220 | 221 | CONFIG += link_pkgconfig 222 | 223 | PKG_CONFIG_PATH += $${FFMPEGDIR}/lib/pkgconfig 224 | 225 | PKGCONFIG += libavformat \ 226 | libavutil \ 227 | libswresample \ 228 | libavcodec 229 | 230 | 231 | #PKGCONFIG += $${FFMPEGDIR}/lib/pkgconfig/libavformat.pc 232 | #PKGCONFIG += $${FFMPEGDIR}/lib/pkgconfig/libavutil.pc 233 | #PKGCONFIG += $${FFMPEGDIR}/lib/pkgconfig/libswresample.pc 234 | #PKGCONFIG += $${FFMPEGDIR}/lib/pkgconfig/libavcodec.pc 235 | 236 | #PKGCONFIG += $${devtools}/mpv-player/mpv-build/build-XunoMpv-20190206/lib/pkgconfig/mpv.pc 237 | PKGCONFIG += $${MPVDIR}/lib/pkgconfig/mpv.pc 238 | #PKGCONFIG += $${PROJECTROOT}/pkgconfig/mpv.pc 239 | 240 | LD_LIBRARY_PATH += $${FFMPEGDIR}/lib 241 | LD_LIBRARY_PATH += $${MPVDIR}/lib 242 | 243 | } 244 | 245 | -------------------------------------------------------------------------------- /XunoPlayer-MPV_128x128.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/XunoPlayer-MPV_128x128.ico -------------------------------------------------------------------------------- /XunoPlayerMPV.h: -------------------------------------------------------------------------------- 1 | #ifndef XunoPlayerMpv_H 2 | #define XunoPlayerMpv_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #ifndef unix 25 | #include 26 | #include 27 | #include 28 | #include 29 | #endif 30 | 31 | #include "common/ScreenSaver.h" 32 | #include "StatisticsView.h" 33 | 34 | 35 | 36 | #include "Slider.h" 37 | #include "playlist/PlayList.h" 38 | #include "ClickableMenu.h" 39 | 40 | #include "config/ConfigDialog.h" 41 | #include "config/configwebmemu.h" 42 | #include "config/VideoEQConfigPage.h" 43 | #include "config/ImageSequenceConfigPage.h" 44 | 45 | #include "EventFilter.h" 46 | #include "common/Config.h" 47 | #include "version.h" 48 | 49 | class MpvWidget; 50 | class QSlider; 51 | class QPushButton; 52 | 53 | QT_FORWARD_DECLARE_CLASS(QLabel) 54 | QT_FORWARD_DECLARE_CLASS(QSlider) 55 | QT_FORWARD_DECLARE_CLASS(QAbstractButton) 56 | QT_FORWARD_DECLARE_CLASS(QWinTaskbarButton) 57 | QT_FORWARD_DECLARE_CLASS(QWinTaskbarProgress) 58 | QT_FORWARD_DECLARE_CLASS(QWinThumbnailToolBar) 59 | QT_FORWARD_DECLARE_CLASS(QWinThumbnailToolButton) 60 | 61 | class XunoPlayerMpv : public QWidget 62 | { 63 | Q_OBJECT 64 | public: 65 | explicit XunoPlayerMpv(QWidget *parent = Q_NULLPTR); 66 | ~XunoPlayerMpv() override; 67 | void OpenAndPlay(const QUrl &url); 68 | QString getXunoVersion(int8_t longversion=0) const; 69 | 70 | public Q_SLOTS: 71 | void openMedia(); 72 | void seek(); 73 | void seek(int pos); 74 | void pauseResume(); 75 | 76 | void openFile(); 77 | 78 | 79 | signals: 80 | void ready(); 81 | 82 | private Q_SLOTS: 83 | void setSliderRange(int duration); 84 | void positionChanged(int pos); 85 | void on_START_FILE(); 86 | void on_FILE_LOADED(); 87 | void on_PAUSE(); 88 | void on_END_FILE(); 89 | void stopUnload(); 90 | void setVolume(); 91 | void setMute(); 92 | void onClickXunoBrowser(QUrl url); 93 | void onFullScreen(); 94 | 95 | void onTimeSliderLeave(); 96 | void onTimeSliderHover(int pos, int value); 97 | void handleFullscreenChange(); 98 | void onScaleX1Btn(); 99 | void onScaleX15Btn(); 100 | void onScaleX2Btn(); 101 | void onScaleBtn(qreal _scale); 102 | void updateThumbnailToolBar(); 103 | void setup(); 104 | void tryHideControlBar(); 105 | void tryShowControlBar(); 106 | void openUrl(); 107 | void initPlayer(); 108 | void processPendingActions(); 109 | void play(QString url); 110 | void seek_relative(int pos); 111 | void seekForward(); 112 | void seekBackward(); 113 | void onActionEsc(); 114 | void onVideoEQEngineChanged(); 115 | void onBrightnessChanged(int _brightness); 116 | void onContrastChanged(int _contrast); 117 | void onHueChanged(int _hue); 118 | void onSaturationChanged(int _saturation); 119 | void onGammaRGBChanged(int _gamma); 120 | void onFilterSharpChanged(int _sharp); 121 | bool showInfo(bool hide=false); 122 | void onImageSequenceConfig(); 123 | void customfpsChanged(double n); 124 | void showInfoTimer(bool state=true); 125 | void onRepeatLoopChanged(int i); 126 | void onSetRepeateMax(int i); 127 | void onToggleRepeat(bool s); 128 | void onRepeatAChanged(const QTime &t); 129 | void onRepeatBChanged(const QTime &t); 130 | void on_pSpeedBox_valueChanged(double v); 131 | void setPlayerScale(const double scale); 132 | 133 | private: 134 | QWidget *m_mpvWidget=Q_NULLPTR; 135 | MpvWidget *m_mpv=Q_NULLPTR; 136 | MpvWidget *mpRenderer=Q_NULLPTR; 137 | QSlider *m_slider=Q_NULLPTR; 138 | QPushButton *m_openBtn=Q_NULLPTR; 139 | QPushButton *m_playBtn=Q_NULLPTR; 140 | QWidget *m_preview=Q_NULLPTR; 141 | 142 | private: 143 | bool mIsReady, mHasPendingPlay; 144 | bool mControlOn=false,mShifOn=false; 145 | bool mNaitiveScaleOn=false; 146 | int mCursorTimer; 147 | int mShowControl; //0: can hide, 1: show and playing, 2: always show(not playing) 148 | int mRepeateMax; 149 | double mCustomFPS=0.; 150 | double mPlayerScale=1.0; 151 | QStringList mAudioBackends; 152 | QVBoxLayout *mpPlayerLayout; 153 | 154 | QWidget *m_mpvLayoutWidget=Q_NULLPTR; 155 | QWidget *m_ControlLayoutWidget=Q_NULLPTR; 156 | QWidget *detachedControl=Q_NULLPTR; 157 | QVBoxLayout *detachedControlLayout=Q_NULLPTR; 158 | QWidget *mpControl; 159 | QLabel *mpCurrent, *mpEnd; 160 | QLabel *mpTitle; 161 | QLabel *mpSpeed; 162 | Slider *mpTimeSlider=Q_NULLPTR, *mpVolumeSlider=Q_NULLPTR; 163 | QToolButton *mpWebBtn, *mpFullScreenBtn, *mpScaleX2Btn, *mpScaleX15Btn,*mpScaleX1Btn; 164 | QToolButton *mpVolumeBtn; 165 | QToolButton *mpPlayPauseBtn=Q_NULLPTR; 166 | QToolButton *mpStopBtn, *mpForwardBtn, *mpBackwardBtn; 167 | QToolButton *mpOpenBtn; 168 | QToolButton *mpInfoBtn, *mpMenuBtn, *mpSetupBtn, *mpCaptureBtn; 169 | QMenu *mpMenu; 170 | QDoubleSpinBox *pSpeedBox = Q_NULLPTR; 171 | QAction *mpVOAction, *mpARAction; //remove mpVOAction if vo.id() is supported 172 | QAction *mpRepeatEnableAction; 173 | QCheckBox *mpRepeatLoop; 174 | QWidgetAction *mpRepeatAction; 175 | QSpinBox *mpRepeatBox; 176 | QTimeEdit *mpRepeatA, *mpRepeatB; 177 | QAction *mpAudioTrackAction; 178 | QMenu *mpAudioTrackMenu; 179 | QMenu *mpChannelMenu; 180 | QMenu *mpClockMenu = Q_NULLPTR; 181 | QActionGroup *mpClockMenuAction = Q_NULLPTR; 182 | QAction *mpChannelAction; 183 | QList mVOActions; 184 | 185 | // QtAV::AVClock *mpClock; 186 | // QtAV::AVPlayer *mpPlayer; 187 | // QtAV::VideoRenderer *mpRenderer; 188 | // QtAV::LibAVFilterVideo *mpVideoFilter; 189 | // QtAV::LibAVFilterAudio *mpAudioFilter; 190 | QString mFile; 191 | QString mTitle; 192 | 193 | QLabel *mpPreview; 194 | 195 | // DecoderConfigPage *mpDecoderConfigPage; 196 | VideoEQConfigPage *mpVideoEQ; 197 | 198 | PlayList *mpPlayList, *mpHistory; 199 | 200 | QPointF mGlobalMouse; 201 | StatisticsView *mpStatisticsView = Q_NULLPTR; 202 | 203 | // OSDFilter *mpOSD; 204 | // QtAV::SubtitleFilter *mpSubtitle; 205 | // QtAV::VideoPreviewWidget *m_preview; 206 | 207 | QString XUNOserverUrl; 208 | QString XUNOpresetUrl; 209 | 210 | ImageSequenceConfigPage *mpImageSequence = Q_NULLPTR; 211 | ConfigWebMemu *mpWebMenu = Q_NULLPTR; 212 | 213 | //ImgSeqExtractControl *mpImgSeqExtract=0; 214 | QString aboutXunoQtAV_PlainText(); 215 | QString aboutXunoQtAV_HTML(); 216 | 217 | //ShaderFilterXuno *shaderXuno=Q_NULLPTR; 218 | //SaveGLXuno *mSaveGLXuno=Q_NULLPTR; 219 | 220 | //XunoGLSLFilter *mpGLSLFilter=Q_NULLPTR; 221 | 222 | //QtAV::DynamicShaderObject *m_shader; 223 | //QtAV::GLSLFilter *m_glsl; 224 | 225 | 226 | bool needToUseSuperResolution=false; 227 | bool needToUseSuperResolutionLastLinearFiltering=true; 228 | bool needToUseFXAAFiltering=false; 229 | 230 | #ifndef unix 231 | QWinThumbnailToolBar *thumbnailToolBar=Q_NULLPTR; 232 | QWinThumbnailToolButton *playToolButton=Q_NULLPTR; 233 | #endif 234 | 235 | void setupUi(QWidget *m_mpv_parent, QWidget *_mpv); 236 | 237 | QUrl remove_fistsubdomain(QUrl url); 238 | bool same_site_domain(const QUrl &url1, const QUrl &url2); 239 | 240 | void workaroundRendererSize(); 241 | void reSizeByMovie(); 242 | QSize movieSize(); 243 | void createShortcuts(); 244 | void createThumbnailToolBar(); 245 | void createJumpList(); 246 | void showTextOverMovie(QString txt, int duration=2); 247 | void seekFrameForward(); 248 | void seekFrameBackward(); 249 | void setMovieSpeed(double speed); 250 | void setMovieColors(qreal contrast=1.0, qreal brightness=0.0, qreal saturation=1.0, qreal gamma=1.0); 251 | void contrast(int contrast=0); 252 | void brightness(int brightness=0); 253 | void saturation(int saturation=0); 254 | void hue(int hue=0); 255 | void gamma(int gamma=0); 256 | void sharpen(qreal sharpen=0.0); 257 | void loadRemoteUrlPresset(const QString &url); 258 | void calcToUseSuperResolution(); 259 | 260 | int getGamma(); 261 | qreal getSharpen(); 262 | qreal getContrast(); 263 | qreal getBrightness(); 264 | qreal getSaturation(); 265 | bool isFileImgageSequence(); 266 | QTimer *TimerShowinfo=Q_NULLPTR; 267 | void setRepeat(int repeat); 268 | void setVideoTimePlay(QTime start, QTime end); 269 | protected: 270 | virtual void closeEvent(QCloseEvent *e) override; 271 | virtual void resizeEvent(QResizeEvent *) override; 272 | virtual void timerEvent(QTimerEvent *) override; 273 | virtual void keyPressEvent(QKeyEvent *e) override; 274 | virtual void keyReleaseEvent(QKeyEvent *e) override; 275 | void mousePressEvent(QMouseEvent *e) override; 276 | void mouseReleaseEvent(QMouseEvent *e) override; 277 | void mouseMoveEvent(QMouseEvent *e) override; 278 | void wheelEvent(QWheelEvent *e) override; 279 | bool eventFilter(QObject *obj, QEvent *event) override; 280 | }; 281 | 282 | #endif // XunoPlayerMpv_H 283 | -------------------------------------------------------------------------------- /common/ScreenSaver.h: -------------------------------------------------------------------------------- 1 | #ifndef SCREENSAVER_H 2 | #define SCREENSAVER_H 3 | 4 | #include "common_export.h" 5 | #include 6 | 7 | // TODO: read QtSystemInfo.ScreenSaver 8 | 9 | class COMMON_EXPORT ScreenSaver : QObject 10 | { 11 | Q_OBJECT 12 | public: 13 | static ScreenSaver& instance(); 14 | ScreenSaver(); 15 | ~ScreenSaver(); 16 | // enable: just restore the previous settings. settings changed during the object life will ignored 17 | bool enable(bool yes); 18 | public slots: 19 | void enable(); 20 | void disable(); 21 | protected: 22 | virtual void timerEvent(QTimerEvent *); 23 | private: 24 | //return false if already called 25 | bool retrieveState(); 26 | bool restoreState(); 27 | bool state_saved, modified; 28 | #ifdef Q_OS_LINUX 29 | bool isX11; 30 | int timeout; 31 | int interval; 32 | int preferBlanking; 33 | int allowExposures; 34 | #endif //Q_OS_LINUX 35 | int ssTimerId; //for mac 36 | quint32 osxIOPMAssertionId; // for mac OSX >= 10.8 37 | }; 38 | 39 | #endif // SCREENSAVER_H 40 | -------------------------------------------------------------------------------- /common/common.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2014-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef COMMON_H 22 | #define COMMON_H 23 | #include 24 | #include 25 | #include 26 | #include "qoptions.h" 27 | #include "Config.h" 28 | #include "ScreenSaver.h" 29 | 30 | QOptions COMMON_EXPORT get_common_options(); 31 | void COMMON_EXPORT do_common_options_before_qapp(const QOptions& options); 32 | /// help, log file, ffmpeg log level 33 | void COMMON_EXPORT do_common_options(const QOptions& options, const QString& appName = QString()); 34 | void COMMON_EXPORT load_qm(const QStringList& names, const QString &lang = QLatin1String("system")); 35 | // if appname ends with 'desktop', 'es', 'angle', software', 'sw', set by appname. otherwise set by command line option glopt, or Config file 36 | // TODO: move to do_common_options_before_qapp 37 | void COMMON_EXPORT set_opengl_backend(const QString& glopt = QString::fromLatin1("auto"), const QString& appname = QString()); 38 | 39 | QString COMMON_EXPORT appDataDir(); 40 | 41 | class COMMON_EXPORT AppEventFilter : public QObject 42 | { 43 | public: 44 | AppEventFilter(QObject *player = 0, QObject* parent = 0); 45 | QUrl url() const; 46 | virtual bool eventFilter(QObject *obj, QEvent *ev); 47 | private: 48 | QObject *m_player; 49 | }; 50 | 51 | #endif // COMMON_H 52 | -------------------------------------------------------------------------------- /common/common_export.h: -------------------------------------------------------------------------------- 1 | #ifndef COMMON_EXPORT_H 2 | #define COMMON_EXPORT_H 3 | 4 | #include 5 | 6 | #ifdef BUILD_COMMON_STATIC 7 | #define COMMON_EXPORT 8 | #else 9 | #if defined(BUILD_COMMON_LIB) 10 | # undef COMMON_EXPORT 11 | # define COMMON_EXPORT Q_DECL_EXPORT 12 | #else 13 | # undef COMMON_EXPORT 14 | # define COMMON_EXPORT //Q_DECL_IMPORT //only for vc? link to static lib error 15 | #endif 16 | #endif //BUILD_COMMON_STATIC 17 | #endif // COMMON_EXPORT_H 18 | -------------------------------------------------------------------------------- /common/qoptions.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QOptions: make command line options easy. https://github.com/wang-bin/qoptions 3 | Copyright (C) 2011-2015 Wang Bin 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License along 16 | with this program; if not, write to the Free Software Foundation, Inc., 17 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | ******************************************************************************/ 19 | 20 | #ifndef QOPTIONS_H 21 | #define QOPTIONS_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | #if defined(BUILD_QOPT_LIB) 28 | # define QOPT_EXPORT Q_DECL_EXPORT 29 | #elif defined(BUILD_QOPT_IMPORT) 30 | # define QOPT_EXPORT Q_DECL_IMPORT //only for vc? 31 | #else 32 | # define QOPT_EXPORT 33 | #endif 34 | 35 | /* 36 | command line: some_cmd -short1 value --long1 value --long2=value -short_novalue --long_novalue... 37 | C++: 38 | QOptions get_global_options() { 39 | static QOptions ops = QOptions().addDescription("...") 40 | .add("common option group") 41 | ("long1,short1", default1, "description1") 42 | ("--long2", default2, "description2") 43 | ("short_novalue", "description3") 44 | ("--long_novalue", "description4") 45 | ; 46 | return ops; 47 | } 48 | QOptions options = get_global_options(); 49 | options.add("special option group")(....)...; 50 | options.parse(argc, argv); 51 | int v1 = options.value("short1").toInt(); 52 | */ 53 | 54 | class QOPT_EXPORT QOption { 55 | public: 56 | // TODO: MultiToken -name value1 -name value2 ... 57 | enum Type { 58 | NoToken, SingleToken, MultiToken 59 | }; 60 | QOption(); 61 | explicit QOption(const char* name, const QVariant& defaultValue, Type type, const QString& description); 62 | explicit QOption(const char* name, Type type, const QString& description); 63 | //explicit QOption(const char* name, const QVariant& value, Type type, const QString& description); 64 | 65 | QString shortName() const; 66 | QString longName() const; 67 | QString formatName() const; 68 | QString description() const; 69 | QVariant value() const; 70 | void setValue(const QVariant& value); 71 | bool isSet() const; 72 | bool isValid() const; 73 | 74 | void setType(QOption::Type type); 75 | QOption::Type type() const; 76 | 77 | QString help() const; 78 | void print() const; 79 | bool operator <(const QOption& o) const; 80 | private: 81 | /*! 82 | * \brief setName 83 | * short/long name format: 84 | * "--long", "-short", "short" 85 | * "long,short", "--long,short", "--long,-short", "long,-short" 86 | * "short,--long", "-short,long", "-short,--long" 87 | * \param name 88 | */ 89 | void setName(const QString& name); 90 | 91 | QOption::Type mType; 92 | QString mShortName, mLongName, mDescription; 93 | QVariant mDefaultValue; 94 | QVariant mValue; 95 | }; 96 | 97 | 98 | class QOPT_EXPORT QOptions { 99 | public: 100 | //e.g. application information, copyright etc. 101 | QOptions(); 102 | //QOptions(const QOptions& o); 103 | ~QOptions(); 104 | //QOptions& operator=(const QOptions& o); 105 | 106 | /*! 107 | * \brief parse 108 | * \param argc 109 | * \param argv 110 | * \return false if invalid option found 111 | */ 112 | bool parse(int argc, const char*const* argv); 113 | QOptions& add(const QString& group_description); 114 | QOptions& addDescription(const QString& description); 115 | 116 | QOptions& operator ()(const char* name, const QString& description = QString()); 117 | QOptions& operator ()(const char* name, QOption::Type type, const QString& description = QString()); 118 | QOptions& operator ()(const char* name, const QVariant& defaultValue, const QString& description); 119 | QOptions& operator ()(const char* name, const QVariant& defaultValue, QOption::Type type, const QString& description = QString()); 120 | //QOptions& operator ()(const char* name, QVariant* value, QOption::Type type, const QString& description = QString()); 121 | 122 | QOption option(const QString& name) const; 123 | QVariant value(const QString& name) const; 124 | QVariant operator [](const QString& name) const; 125 | 126 | QString help() const; 127 | void print() const; 128 | private: 129 | QString mDescription, mCurrentDescription; 130 | QList mOptions; 131 | QMap mOptionGroupMap; 132 | }; 133 | 134 | #endif // QOPTIONS_H 135 | -------------------------------------------------------------------------------- /config/ConfigDialog.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2016 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "ConfigDialog.h" 22 | #include 23 | #include 24 | #include 25 | //#include "CaptureConfigPage.h" 26 | //#include "DecoderConfigPage.h" 27 | //#include "AVFormatConfigPage.h" 28 | //#include "AVFilterConfigPage.h" 29 | #include "WebConfigPage.h" 30 | #include "MiscPage.h" 31 | //#include "ShaderPage.h" 32 | #include "common/Config.h" 33 | #include 34 | #include 35 | 36 | void ConfigDialog::display() 37 | { 38 | static ConfigDialog *dialog = new ConfigDialog(); 39 | dialog->show(); 40 | } 41 | 42 | ConfigDialog::ConfigDialog(QWidget *parent) : 43 | QDialog(parent) 44 | { 45 | setWindowTitle(tr("Settings...")); 46 | QVBoxLayout *vbl = new QVBoxLayout(); 47 | setLayout(vbl); 48 | vbl->setSizeConstraint(QLayout::SetFixedSize); 49 | 50 | mpContent = new QTabWidget(); 51 | mpContent->setTabPosition(QTabWidget::West); 52 | mpContent->setMinimumHeight(350); 53 | 54 | mpButtonBox = new QDialogButtonBox(Qt::Horizontal); 55 | mpButtonBox->addButton(tr("Reset"), QDialogButtonBox::ResetRole);// (QDialogButtonBox::Reset); 56 | mpButtonBox->addButton(tr("Ok"), QDialogButtonBox::AcceptRole); //QDialogButtonBox::Ok 57 | mpButtonBox->addButton(tr("Cancel"), QDialogButtonBox::RejectRole); 58 | mpButtonBox->addButton(tr("Apply"), QDialogButtonBox::ApplyRole); 59 | 60 | connect(mpButtonBox, SIGNAL(accepted()), this ,SLOT(accept())); 61 | connect(mpButtonBox, SIGNAL(rejected()), this ,SLOT(reject())); 62 | connect(mpButtonBox, SIGNAL(clicked(QAbstractButton*)), this ,SLOT(onButtonClicked(QAbstractButton*))); 63 | 64 | vbl->addWidget(mpContent); 65 | vbl->addWidget(mpButtonBox); 66 | 67 | mPages 68 | << new MiscPage() 69 | // << new CaptureConfigPage() 70 | // << new DecoderConfigPage() 71 | // << new AVFormatConfigPage() 72 | // << new AVFilterConfigPage() 73 | << new WebConfigPage() 74 | // << new ShaderPage() 75 | ; 76 | foreach (ConfigPageBase* page, mPages) { 77 | page->applyToUi(); 78 | page->applyOnUiChange(false); 79 | mpContent->addTab(page, page->name()); 80 | } 81 | } 82 | 83 | void ConfigDialog::onButtonClicked(QAbstractButton *btn) 84 | { 85 | qDebug("QDialogButtonBox clicked role=%d", mpButtonBox->buttonRole(btn)); 86 | switch (mpButtonBox->buttonRole(btn)) { 87 | case QDialogButtonBox::ResetRole: 88 | qDebug("QDialogButtonBox ResetRole clicked"); 89 | onReset(); 90 | break; 91 | case QDialogButtonBox::AcceptRole: 92 | case QDialogButtonBox::ApplyRole: 93 | qDebug("QDialogButtonBox ApplyRole clicked"); 94 | onApply(); 95 | break; 96 | case QDialogButtonBox::DestructiveRole: 97 | case QDialogButtonBox::RejectRole: 98 | onCancel(); 99 | break; 100 | default: 101 | break; 102 | } 103 | } 104 | 105 | void ConfigDialog::onReset() 106 | { 107 | Config::instance().reset(); 108 | // TODO: check change 109 | int ret=QMessageBox::information(this,tr("Reset all settings"),tr("Reset will delete all data"), 110 | QMessageBox::Ok|QMessageBox::Cancel,QMessageBox::Cancel); 111 | if (ret!=QMessageBox::Ok) return; 112 | 113 | Config::instance().reset(); 114 | 115 | foreach (ConfigPageBase* page, mPages) { 116 | page->reset(); 117 | } 118 | } 119 | 120 | void ConfigDialog::onApply() 121 | { 122 | // TODO: check change 123 | foreach (ConfigPageBase* page, mPages) { 124 | page->apply(); 125 | } 126 | Config::instance().save(); 127 | } 128 | 129 | void ConfigDialog::onCancel() 130 | { 131 | // TODO: check change 132 | foreach (ConfigPageBase* page, mPages) { 133 | page->cancel(); 134 | } 135 | } 136 | 137 | -------------------------------------------------------------------------------- /config/ConfigDialog.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef CONFIGDIALOG_H 22 | #define CONFIGDIALOG_H 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | class ConfigPageBase; 30 | class ConfigDialog : public QDialog 31 | { 32 | Q_OBJECT 33 | public: 34 | static void display(); 35 | 36 | private slots: 37 | void onButtonClicked(QAbstractButton* btn); 38 | void onApply(); 39 | void onCancel(); 40 | void onReset(); 41 | 42 | private: 43 | explicit ConfigDialog(QWidget *parent = 0); 44 | QTabWidget *mpContent; 45 | QDialogButtonBox *mpButtonBox; 46 | QList mPages; 47 | }; 48 | 49 | #endif // CONFIGDIALOG_H 50 | -------------------------------------------------------------------------------- /config/ConfigPageBase.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "ConfigPageBase.h" 22 | 23 | ConfigPageBase::ConfigPageBase(QWidget *parent) : 24 | QWidget(parent) 25 | , mApplyOnUiChange(true) 26 | { 27 | } 28 | 29 | void ConfigPageBase::applyOnUiChange(bool a) 30 | { 31 | mApplyOnUiChange = a; 32 | } 33 | 34 | bool ConfigPageBase::applyOnUiChange() const 35 | { 36 | return mApplyOnUiChange; 37 | } 38 | 39 | void ConfigPageBase::apply() 40 | { 41 | applyFromUi(); 42 | } 43 | 44 | void ConfigPageBase::cancel() 45 | { 46 | applyToUi(); 47 | } 48 | 49 | void ConfigPageBase::reset() 50 | { 51 | // NOTE: make sure Config::instance().reset() is called before it. It is called i ConfigDialog.reset() 52 | applyToUi(); 53 | } 54 | -------------------------------------------------------------------------------- /config/ConfigPageBase.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2016 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef CONFIGPAGEBASE_H 22 | #define CONFIGPAGEBASE_H 23 | 24 | #include 25 | 26 | class ConfigPageBase : public QWidget 27 | { 28 | Q_OBJECT 29 | public: 30 | explicit ConfigPageBase(QWidget *parent = 0); 31 | virtual QString name() const = 0; 32 | void applyOnUiChange(bool a); 33 | // default is true. in dialog is false, must call ConfigDialog::apply() to apply 34 | bool applyOnUiChange() const; 35 | 36 | public slots: 37 | // deprecated. call applyFromUi() 38 | void apply(); 39 | // deprecated. call applyToUi(). 40 | void cancel(); 41 | //call applyToUi() after Config::instance().reset(); 42 | void reset(); 43 | /*! 44 | * \brief applyToUi 45 | * Apply configurations to UI. Call this in your page ctor when ui layout is ready. 46 | */ 47 | virtual void applyToUi() = 0; 48 | protected: 49 | /*! 50 | * \brief applyFromUi 51 | * Save configuration values from UI. Call Config::xxx(value) in your implementation 52 | */ 53 | virtual void applyFromUi() = 0; 54 | private: 55 | bool mApplyOnUiChange; 56 | }; 57 | 58 | #endif // CONFIGPAGEBASE_H 59 | -------------------------------------------------------------------------------- /config/ImageSequenceConfigPage.h: -------------------------------------------------------------------------------- 1 | #ifndef IMAGESEQUENCECONFIGPAGE_H 2 | #define IMAGESEQUENCECONFIGPAGE_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | 22 | class QPushButton; 23 | class QSpinBox; 24 | 25 | class ImageSequenceConfigPage : public QDialog 26 | { 27 | Q_OBJECT 28 | Q_PROPERTY(bool EnableFrameExtractor READ getEnableFrameExtractor WRITE setEnableFrameExtractor) 29 | 30 | public: 31 | explicit ImageSequenceConfigPage(QWidget *parent = 0); 32 | void openFiles(); 33 | void setMovieDuration(qint64 d); 34 | void setStartFrame(quint32 n); 35 | void setEndFrame(quint32 n); 36 | void setImageSequenceFileName(QString fname); 37 | void setRepeatLoop(bool loop); 38 | void setEnableFrameExtractor(bool s); 39 | bool getEnableFrameExtractor() const; 40 | 41 | 42 | signals: 43 | void play(QString); 44 | void stop(); 45 | void repeatAChanged(QTime); 46 | void repeatBChanged(QTime); 47 | void toggleRepeat(bool); 48 | void customfpsChanged(double); 49 | void toogledFrameExtractor(bool state); 50 | void setPlayerScale(double); 51 | void RepeatLoopChanged(int i); 52 | 53 | 54 | public slots: 55 | void onSelectImgages(); 56 | void setFPS(double n); 57 | void setTotalFrames(int n); 58 | 59 | private slots: 60 | void on_checkBoxExtractor_toggled(bool state); 61 | void on_checkLoop_toggled(bool state); 62 | 63 | void on_InputStartFrame_valueChanged(int arg1); 64 | void on_InputEndFrame_valueChanged(int arg1); 65 | void on_InputTotalFrame_valueChanged(int arg1); 66 | void on_cbDecodeGeometryFromFileName_toggled(bool checked); 67 | void on_InputPath_textChanged(const QString &text); 68 | void playImgages(); 69 | 70 | private: 71 | QSpinBox *mpTotalFramesBox; 72 | QDoubleSpinBox *mpFpsBox; 73 | QPushButton *mpSelectImgButton, *mpPlayImgButton; 74 | quint64 startPos,stopPos; 75 | double fps; 76 | quint32 startFrame, frames, totalAllInputFrames; 77 | QFileInfo fileinfo; 78 | QPushButton *buttonPlay; 79 | QLineEdit *InputPath; 80 | QSpinBox *InputStartFrame, *InputEndFrame, *InputTotalFrame; 81 | QLabel *InputAllTotalFrame; 82 | QCheckBox *checkLoop; 83 | QComboBox *cbColorTypeInput; 84 | QPushButton *checkBoxExtractor; 85 | QDoubleSpinBox *InputScale; 86 | QCheckBox *cbDecodeGeometryFromFileName; 87 | QSpinBox *inputImageW; 88 | QSpinBox *inputImageH; 89 | 90 | 91 | void calculatePos(); 92 | void analyzeFilename(); 93 | int getDigetsFilename(); 94 | bool playing_start; 95 | 96 | const QString dataImageSeparator="_"; 97 | 98 | const QStringList ImageTypes = QStringList() 99 | << "420" 100 | << "422" 101 | << "RGB" 102 | << "RGBA" 103 | << "bmp" 104 | << "cr2" 105 | << "dng" 106 | << "dpx" 107 | << "exr" 108 | << "jp2" 109 | << "png" 110 | << "jpg" 111 | << "tga" 112 | << "tif" 113 | << "tiff"; 114 | 115 | int getDigetsFilename(QString filename); 116 | int getNumberFilename(QString filename); 117 | int getTotalNumberFilename(QString filename); 118 | QString getSequenceFilename(QString filename); 119 | void updateInputTotalFrameValue(); 120 | void updateInputEndFrameValue(); 121 | void getGeometryFromFilename(QString filename, QSize &size, int &depth); 122 | 123 | }; 124 | 125 | #endif // IMAGESEQUENCECONFIGPAGE_H 126 | -------------------------------------------------------------------------------- /config/MiscPage.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2016 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "MiscPage.h" 22 | #include 23 | #include 24 | #include "common/Config.h" 25 | #include 26 | 27 | MiscPage::MiscPage() 28 | { 29 | setObjectName("misc"); 30 | QVBoxLayout *vl= new QVBoxLayout; 31 | QGroupBox *video = new QGroupBox; 32 | video->setTitle(tr(" Video")); 33 | QGridLayout *gl = new QGridLayout(video); 34 | gl->setSizeConstraint(QLayout::SetFixedSize); 35 | int r = 0; 36 | m_preview_on = new QCheckBox(tr("Preview"),video); 37 | gl->addWidget(m_preview_on, r++, 0); 38 | m_preview_w = new QSpinBox(video); 39 | m_preview_w->setRange(1, 1920); 40 | m_preview_h = new QSpinBox(video); 41 | m_preview_h->setRange(1, 1080); 42 | gl->addWidget(new QLabel(QString::fromLatin1("%1 %2: ").arg(tr("Preview")).arg(tr("size")),video), r, 0); 43 | QHBoxLayout *hb = new QHBoxLayout; 44 | hb->addWidget(m_preview_w); 45 | hb->addWidget(new QLabel(QString::fromLatin1("x"),video)); 46 | hb->addWidget(m_preview_h); 47 | gl->addLayout(hb, r, 1); 48 | r++; 49 | gl->addWidget(new QLabel(tr("Force fps"),video), r, 0); 50 | m_fps = new QDoubleSpinBox(video); 51 | m_fps->setMinimum(-m_fps->maximum()); 52 | m_fps->setToolTip(QString::fromLatin1("<= 0: ") + tr("Ignore")); 53 | gl->addWidget(m_fps, r++, 1); 54 | 55 | gl->addWidget(new QLabel(tr("Progress update interval") + QString::fromLatin1("(ms)"),video), r, 0); 56 | m_notify_interval = new QSpinBox(video); 57 | m_notify_interval->setEnabled(false); 58 | gl->addWidget(m_notify_interval, r++, 1); 59 | 60 | gl->addWidget(new QLabel(tr("Buffer frames"),video), r, 0); 61 | m_buffer_value = new QSpinBox(video); 62 | m_buffer_value->setRange(-1, 32767); 63 | m_buffer_value->setToolTip(QString::fromLatin1("-1: auto")); 64 | gl->addWidget(m_buffer_value, r++, 1); 65 | 66 | gl->addWidget(new QLabel(QString::fromLatin1("%1(%2)").arg(tr("Timeout")).arg(tr("s")),video), r, 0); 67 | m_timeout = new QDoubleSpinBox(video); 68 | m_timeout->setDecimals(3); 69 | m_timeout->setSingleStep(1.0); 70 | m_timeout->setMinimum(-0.5); 71 | m_timeout->setToolTip(QString::fromLatin1("<=0: never")); 72 | m_timeout_abort = new QCheckBox(tr("Abort")); 73 | hb = new QHBoxLayout; 74 | hb->addWidget(m_timeout); 75 | hb->addWidget(m_timeout_abort); 76 | gl->addLayout(hb, r++, 1); 77 | 78 | gl->addWidget(new QLabel(tr("OpenGL type")), r, 0); 79 | m_opengl = new QComboBox(); 80 | m_opengl->addItem(QString::fromLatin1("Auto"), Config::Auto); 81 | m_opengl->addItem(QString::fromLatin1("Desktop"), Config::Desktop); 82 | m_opengl->addItem(QString::fromLatin1("OpenGLES"), Config::OpenGLES); 83 | m_opengl->addItem(QString::fromLatin1("Software"), Config::Software); 84 | m_opengl->setToolTip(tr("Windows only") + " Qt>=5.4 + dynamicgl" + QString::fromLatin1("\n") + tr("OpenGLES is Used by DXVA Zero Copy")); 85 | gl->addWidget(m_opengl, r, 1); 86 | m_angle_platform = new QComboBox(); 87 | m_angle_platform->setToolTip(tr("D3D9 has performance if ZeroCopy is disabled or for software decoders") + QString::fromLatin1("\n") + tr("RESTART REQUIRED")); 88 | m_angle_platform->addItems(QStringList() << QString::fromLatin1("D3D9") << QString::fromLatin1("D3D11") << QString::fromLatin1("AUTO") << QString::fromLatin1("WARP")); 89 | #ifndef QT_OPENGL_DYNAMIC 90 | m_opengl->setEnabled(false); 91 | m_angle_platform->setEnabled(false); 92 | #endif 93 | gl->addWidget(m_angle_platform, r++, 2); 94 | 95 | gl->addWidget(new QLabel("EGL"), r, 0); 96 | m_egl = new QCheckBox(); 97 | m_egl->setToolTip(tr("Currently only works for Qt>=5.5 XCB build")); 98 | #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) || !defined(Q_OS_LINUX) 99 | m_egl->setEnabled(false); 100 | #endif 101 | gl->addWidget(m_egl, r++, 1); 102 | 103 | gl->addWidget(new QLabel("Log"), r, 0); 104 | m_log = new QComboBox(); 105 | m_log->addItems(QStringList() << QString::fromLatin1("off") << QString::fromLatin1("warning") << QString::fromLatin1("debug") << QString::fromLatin1("all")); 106 | gl->addWidget(m_log, r++, 1); 107 | 108 | //gl->addItem(new QSpacerItem(185, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),r,0); 109 | //gl->addItem(new QSpacerItem(120, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),r,1); 110 | //gl->addItem(new QSpacerItem(120, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),r++,2); 111 | 112 | vl->addWidget(video,1, Qt::AlignTop); 113 | 114 | //------ imgseq 115 | QGroupBox *imgSeq = new QGroupBox(this); 116 | imgSeq->setTitle(tr(" Image Sequences")); 117 | QGridLayout *gli = new QGridLayout(imgSeq); 118 | //setLayout(gl); 119 | gli->setSizeConstraint(QLayout::SetFixedSize); 120 | //gli-> 121 | r = 0; 122 | 123 | gli->addWidget(new QLabel(tr("Buffer frames"),imgSeq), r, 0); 124 | m_buffer_valueI = new QSpinBox(imgSeq); 125 | m_buffer_valueI->setRange(-1, 32767); 126 | m_buffer_valueI->setToolTip("-1: auto"); 127 | gli->addWidget(m_buffer_valueI, r, 1); 128 | 129 | m_forceVideoClockI = new QCheckBox(tr("Force Video Clock"),imgSeq); 130 | gli->addWidget(m_forceVideoClockI, ++r, 0); 131 | gli->addItem(new QSpacerItem(178, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),++r,0); 132 | gli->addItem(new QSpacerItem(140, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),r,1); 133 | vl->addWidget(imgSeq,1, Qt::AlignTop); 134 | 135 | 136 | QGroupBox *playerView = new QGroupBox(this); 137 | playerView->setTitle(tr(" Player View")); 138 | QGridLayout *glpv = new QGridLayout(playerView); 139 | glpv->setSizeConstraint(QLayout::SetFixedSize); 140 | r = 0; 141 | m_floatcontrol = new QCheckBox(tr("Float Control Window")); 142 | m_floatcontrol->setToolTip(tr("Application restart required")); 143 | glpv->addWidget(m_floatcontrol, r, 0); 144 | glpv->addWidget(new QLabel(tr("(application restart required)")), r, 1); 145 | glpv->addItem(new QSpacerItem(178, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),++r,0); 146 | 147 | glpv->addItem(new QSpacerItem(140, 0, QSizePolicy::Minimum, QSizePolicy::Minimum),r,1); 148 | 149 | vl->addWidget(playerView,1, Qt::AlignTop); 150 | 151 | setLayout(vl); 152 | 153 | applyToUi(); 154 | } 155 | 156 | QString MiscPage::name() const 157 | { 158 | return tr("View"); 159 | } 160 | 161 | 162 | void MiscPage::applyFromUi() 163 | { 164 | Config::instance().setPreviewEnabled(m_preview_on->isChecked()) 165 | .setPreviewWidth(m_preview_w->value()) 166 | .setPreviewHeight(m_preview_h->value()) 167 | .setEGL(m_egl->isChecked()) 168 | .setOpenGLType((Config::OpenGLType)m_opengl->itemData(m_opengl->currentIndex()).toInt()) 169 | .setANGLEPlatform(m_angle_platform->currentText().toLower()) 170 | .setForceFrameRate(m_fps->value()) 171 | .setBufferValue(m_buffer_value->value()) 172 | .setTimeout(m_timeout->value()) 173 | .setAbortOnTimeout(m_timeout_abort->isChecked()) 174 | .setBufferValueI(m_buffer_valueI->value()) 175 | .setForceVideoClockI(m_forceVideoClockI->isChecked()) 176 | .setFloatControlEnabled(m_floatcontrol->isChecked()) 177 | .setLogLevel(m_log->currentText().toLower()) 178 | ; 179 | } 180 | 181 | void MiscPage::applyToUi() 182 | { 183 | m_preview_on->setChecked(Config::instance().previewEnabled()); 184 | m_preview_w->setValue(Config::instance().previewWidth()); 185 | m_preview_h->setValue(Config::instance().previewHeight()); 186 | m_opengl->setCurrentIndex(m_opengl->findData(Config::instance().openGLType())); 187 | m_angle_platform->setCurrentIndex(m_angle_platform->findText(Config::instance().getANGLEPlatform().toUpper())); 188 | m_egl->setChecked(Config::instance().isEGL()); 189 | m_fps->setValue(Config::instance().forceFrameRate()); 190 | //m_notify_interval->setValue(Config::instance().avfilterOptions()); 191 | m_buffer_value->setValue(Config::instance().bufferValue()); 192 | m_timeout->setValue(Config::instance().timeout()); 193 | m_timeout_abort->setChecked(Config::instance().abortOnTimeout()); 194 | m_buffer_valueI->setValue(Config::instance().bufferValueI()); 195 | m_forceVideoClockI->setChecked(Config::instance().forceVideoClockI()); 196 | m_floatcontrol->setChecked(Config::instance().floatControlEnabled()); 197 | m_log->setCurrentIndex(m_log->findText(Config::instance().logLevel().toLower())); 198 | } 199 | -------------------------------------------------------------------------------- /config/MiscPage.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef MISCPAGE_H 22 | #define MISCPAGE_H 23 | 24 | #include "ConfigPageBase.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | class MiscPage : public ConfigPageBase 31 | { 32 | Q_OBJECT 33 | public: 34 | MiscPage(); 35 | virtual QString name() const; 36 | protected: 37 | virtual void applyToUi(); 38 | virtual void applyFromUi(); 39 | private: 40 | QCheckBox *m_preview_on,*m_floatcontrol; 41 | QSpinBox *m_preview_w; 42 | QSpinBox *m_preview_h; 43 | QSpinBox *m_notify_interval; 44 | QDoubleSpinBox *m_fps; 45 | QSpinBox *m_buffer_value; 46 | QDoubleSpinBox *m_timeout; 47 | QCheckBox *m_timeout_abort; 48 | //imgseq 49 | QSpinBox *m_buffer_valueI; 50 | QCheckBox *m_forceVideoClockI; 51 | QComboBox *m_opengl; 52 | QComboBox *m_angle_platform; 53 | QCheckBox *m_egl; 54 | QComboBox *m_log; 55 | }; 56 | 57 | #endif // MISCPAGE_H 58 | -------------------------------------------------------------------------------- /config/VideoEQConfigPage.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef VIDEOEQCONFIGPAGE_H 22 | #define VIDEOEQCONFIGPAGE_H 23 | 24 | #include 25 | #include 26 | 27 | QT_BEGIN_NAMESPACE 28 | class QCheckBox; 29 | class QComboBox; 30 | class QPushButton; 31 | class QSlider; 32 | class QDoubleSpinBox; 33 | QT_END_NAMESPACE 34 | class VideoEQConfigPage : public QWidget 35 | { 36 | Q_OBJECT 37 | public: 38 | enum Engine { 39 | SWScale, 40 | GLSL, 41 | XV, 42 | }; 43 | struct ColorSpacePreset { 44 | QString name; 45 | qreal brightness; 46 | qreal contrast; 47 | qreal hue; 48 | qreal saturation; 49 | qreal gammaRGB; 50 | qreal filterSharp; 51 | bool loaded; 52 | ColorSpacePreset() : name(""),brightness(0.0),contrast(0.0),hue(0.0),saturation(0.0),gammaRGB(0.0),filterSharp(0.0),loaded(false) {} 53 | }; 54 | explicit VideoEQConfigPage(QWidget *parent = 0); 55 | 56 | void setEngines(const QVector& engines); 57 | void setListPreset(int id); 58 | void setListPresets(); 59 | void fillCurrentPreset(); 60 | void readCurrentPreset(); 61 | void fillPreset(int id); 62 | void initPresets(); 63 | void loadPresets(); 64 | void savePresets(); 65 | void setSaveFile(const QString &file); 66 | QList presetItems() const; 67 | QString saveFile() const; 68 | void loadLocalPresets(); 69 | void saveLocalPresets(); 70 | void setRemoteUrlPresset(const QString &file); 71 | void getRemotePressets (); 72 | void getLocalPressets (); 73 | 74 | void setEngine(Engine engine); 75 | 76 | Engine engine() const; 77 | 78 | qreal brightness() const; 79 | qreal contrast() const; 80 | qreal hue() const; 81 | qreal saturation() const; 82 | qreal gammaRGB() const; 83 | qreal filterSharp() const; 84 | void brightness(qreal val); 85 | void contrast(qreal val) const; 86 | void hue(qreal val) const; 87 | void saturation(qreal val) const; 88 | void gammaRGB(qreal val) const; 89 | void filterSharp(qreal val) const; 90 | 91 | 92 | 93 | void setXunoVersion(const QString &value); 94 | 95 | signals: 96 | void engineChanged(); 97 | void brightnessChanged(int); 98 | void contrastChanged(int); 99 | void hueChanegd(int); 100 | void saturationChanged(int); 101 | void listPresetChanged(); 102 | void gammaRGBChanged(int); 103 | void filterSharpChanged(int); 104 | 105 | private slots: 106 | void onGlobalSet(bool); 107 | void onReset(); 108 | void onResetByZerro(); 109 | void onEngineChangedByUI(); 110 | void onLoadPreset(); 111 | void onSavePreset(); 112 | void onListPresetChangedByUI(); 113 | void onPresetRequestFinished(QNetworkReply* reply); 114 | void onResetLocalCongig(); 115 | void onSaveLocalCongig(); 116 | 117 | void brightnessTChanged(double); 118 | void contrastTChanged(double); 119 | void hueTChanegd(double); 120 | void saturationTChanged(double); 121 | void gammaRGBTChanged(double); 122 | void filterSharpTChanged(double); 123 | bool resetByRemotePreset(); 124 | 125 | 126 | private: 127 | qreal brightness_p() const; 128 | qreal contrast_p() const; 129 | qreal hue_p() const; 130 | qreal saturation_p() const; 131 | qreal gammaRGB_p() const; 132 | qreal filterSharp_p() const; 133 | QCheckBox *mpGlobal; 134 | QComboBox *mpEngine, *mpListPreset; 135 | QSlider *mpBSlider, *mpCSlider, *mpSSlider, *mpGSlider, *mpFSSlider,*mpHSlider; 136 | QDoubleSpinBox *mpBSliderT, *mpCSliderT, *mpSSliderT, *mpGSliderT, *mpFSSliderT,*mpHSliderT; 137 | QPushButton *mpResetButton, *mpSavePreset, *mpLoadPreset, *mpSaveLocalCongig, *mpResetLocalCongig ; 138 | Engine mEngine; 139 | QVector mEngines; 140 | int mPresetID; 141 | QList mPreset; 142 | ColorSpacePreset mRemotePreset; 143 | QString mFile,mURL,presetUrl; 144 | void parseJsonPressetData(QString &strReply); 145 | void reReadColorsCongig(); 146 | QString XunoVersion; 147 | }; 148 | #endif // VIDEOEQCONFIGPAGE_H 149 | -------------------------------------------------------------------------------- /config/WebConfigPage.cpp: -------------------------------------------------------------------------------- 1 | #include "WebConfigPage.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | //#include 8 | #include 9 | #include 10 | #include "common/Config.h" 11 | #include 12 | #include 13 | #include 14 | 15 | 16 | WebConfigPage::WebConfigPage() 17 | { 18 | setObjectName("web"); 19 | QVBoxLayout *vbox = new QVBoxLayout; 20 | vbox->setAlignment(Qt::AlignTop); 21 | QGroupBox *groupBox = new QGroupBox(tr("Edit list of Web links")); 22 | QVBoxLayout *gl = new QVBoxLayout(); 23 | //gl->setSizeConstraint(QLayout::SetFixedSize); 24 | 25 | initModelData(); 26 | 27 | m_options = new QListView(); 28 | m_options->setModel(model); 29 | m_options->setEditTriggers(QAbstractItemView::NoEditTriggers); 30 | 31 | connect(m_options, SIGNAL(clicked(QModelIndex)),this, SLOT(onSelected(QModelIndex))); 32 | 33 | gl->addWidget(m_options); 34 | 35 | QHBoxLayout *hb1 = new QHBoxLayout(); 36 | QPushButton *bInsert = new QPushButton(tr("&Insert"), this); 37 | QPushButton *bChange = new QPushButton(tr("&Change"), this); 38 | QPushButton *bDelete = new QPushButton(tr("&Delete"), this); 39 | hb1->addWidget(bInsert); 40 | hb1->addWidget(bChange); 41 | hb1->addWidget(bDelete); 42 | 43 | QObject::connect(bInsert, SIGNAL(pressed()), this, SLOT(onInsert())); 44 | QObject::connect(bChange, SIGNAL(pressed()), this, SLOT(onChange())); 45 | QObject::connect(bDelete, SIGNAL(pressed()), this, SLOT(onDelete())); 46 | 47 | gl->addLayout(hb1); 48 | int r=0; 49 | QGridLayout *gbox = new QGridLayout(); 50 | QLabel *lname = new QLabel(tr("&Name:")); 51 | ename = new QLineEdit(); 52 | lname->setBuddy(ename); 53 | gbox->addWidget(lname,r,0); 54 | gbox->addWidget(ename,r,1); 55 | r++; 56 | QLabel *lurl = new QLabel(tr("&Url:")); 57 | eurl = new QLineEdit(); 58 | lurl->setBuddy(eurl); 59 | gbox->addWidget(lurl,r,0); 60 | gbox->addWidget(eurl,r,1); 61 | gl->addLayout(gbox); 62 | groupBox->setLayout(gl); 63 | vbox->addWidget(groupBox); 64 | setLayout(vbox); 65 | applyToUi(); 66 | } 67 | 68 | void WebConfigPage::initModelData() 69 | { 70 | links = QMap(Config::instance().WebLinks()); 71 | QStringList numbers = links.keys(); 72 | 73 | if (!model) model = new StringListModel(); 74 | model->setStringList(numbers); 75 | } 76 | 77 | 78 | QString WebConfigPage::name() const 79 | { 80 | return "Web"; 81 | } 82 | 83 | 84 | bool WebConfigPage::ValidURL(const QString &url) 85 | { 86 | QUrl u(url); 87 | if (!u.isValid()||u.host().isEmpty()){ 88 | QMessageBox::warning(this, tr("Web link"), 89 | tr(" Wrong URL is used. \n" 90 | "May be need start from 'http://' ?\n"), 91 | QMessageBox::Ok); 92 | return false; 93 | } 94 | return true; 95 | } 96 | 97 | void WebConfigPage::onInsert() 98 | { 99 | //qDebug("WebConfigPage onInsert"); 100 | QString name = ename->text(); 101 | QString url = eurl->text(); 102 | if (name.isEmpty()||url.isEmpty()){ 103 | ename->setFocus(); 104 | QMessageBox::warning(this, tr("Insert new Web link"), 105 | tr("\n Both of fields must be filled. \n"), 106 | QMessageBox::Ok); 107 | }else if(ValidURL(url)) { 108 | if (model->match(model->index(0),Qt::DisplayRole,name).isEmpty()){ 109 | model->insertRow(model->rowCount(),QModelIndex()); 110 | QModelIndex index = model->index(model->rowCount()-1, 0, QModelIndex()); 111 | if (model->setData(index, name, Qt::EditRole)){ 112 | m_options->setCurrentIndex(index); 113 | saveLinks(name,url); 114 | ename->clear(); 115 | eurl->clear(); 116 | } 117 | }else{ 118 | QMessageBox::warning(this, tr("Insert new Web link"), 119 | tr("\n This name is used. \n"), 120 | QMessageBox::Ok); 121 | } 122 | 123 | } 124 | } 125 | 126 | void WebConfigPage::onChange() 127 | { 128 | //qDebug("WebConfigPage onChange"); 129 | QModelIndex index = m_options->currentIndex(); 130 | QString name = ename->text(); 131 | QString url = eurl->text(); 132 | if (name.isEmpty()||url.isEmpty()){ 133 | QMessageBox::warning(this, tr("Changing Web link"), 134 | tr("\nBoth of fields must be filled.\n"), 135 | QMessageBox::Ok); 136 | }else if(ValidURL(url)) { 137 | QString oldname =index.data(Qt::DisplayRole).toString(); 138 | if (model->setData(index, name, Qt::EditRole)){ 139 | model->sort(0); 140 | m_options->setCurrentIndex(index); 141 | //qDebug("WebConfigPage Changed"); 142 | deleteLinks(oldname); 143 | saveLinks(name,url); 144 | ename->clear(); 145 | eurl->clear(); 146 | } 147 | } 148 | } 149 | 150 | void WebConfigPage::onDelete() 151 | { 152 | qDebug("WebConfigPage onDelete"); 153 | QModelIndex index = m_options->currentIndex(); 154 | if (index.isValid()){ 155 | QString name = index.data().toString(); 156 | int ret=QMessageBox::question(this, tr("Deleting Web link"), 157 | tr("Record '%1' will be deleted.\n Do you want delete it?").arg(name), 158 | QMessageBox::Yes|QMessageBox::No,QMessageBox::No); 159 | if (ret==QMessageBox::Yes){ 160 | if (links.remove(name)){ 161 | QModelIndex index = m_options->currentIndex(); 162 | qDebug("Index row %d:",index.row()); 163 | if (model->removeRow(index.row(),QModelIndex())){ 164 | //qDebug("WebConfigPage Deleted"); 165 | ename->clear(); 166 | eurl->clear(); 167 | } 168 | } 169 | } 170 | }else{ 171 | QMessageBox::warning(this, tr("Deleting Web link"), 172 | tr("Not selected name in list.\nSelect it before continiue."), 173 | QMessageBox::Ok); 174 | } 175 | } 176 | 177 | void WebConfigPage::onSelected(QModelIndex index) 178 | { 179 | QString name = index.data().toString(); 180 | QString url = links.value(name).toString(); 181 | //qDebug() << "WebConfigPage onSelected :" << name << url ; 182 | ename->setText(name); 183 | eurl->setText(url); 184 | } 185 | 186 | void WebConfigPage::saveLinks(QString name, QString urls) 187 | { 188 | links.insert(name,urls); 189 | } 190 | 191 | void WebConfigPage::deleteLinks(QString name) 192 | { 193 | links.remove(name); 194 | } 195 | 196 | void WebConfigPage::applyFromUi() 197 | { 198 | Config::instance().setWebLinks(links); 199 | } 200 | 201 | void WebConfigPage::applyToUi() 202 | { 203 | initModelData(); 204 | } 205 | -------------------------------------------------------------------------------- /config/WebConfigPage.h: -------------------------------------------------------------------------------- 1 | #ifndef WebConfigPage_H 2 | #define WebConfigPage_H 3 | 4 | #include "ConfigPageBase.h" 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class StringListModel : public QStringListModel 11 | { 12 | }; 13 | 14 | 15 | 16 | class QCheckBox; 17 | class QListView; 18 | class QPushButton; 19 | class QLineEdit; 20 | 21 | class WebConfigPage : public ConfigPageBase 22 | { 23 | Q_OBJECT 24 | public: 25 | WebConfigPage(); 26 | virtual QString name() const; 27 | 28 | private slots: 29 | void onInsert(); 30 | void onChange(); 31 | void onDelete(); 32 | void onSelected(QModelIndex); 33 | 34 | protected: 35 | virtual void applyToUi(); 36 | virtual void applyFromUi(); 37 | 38 | private: 39 | QCheckBox *m_enable; 40 | QListView *m_options; 41 | QDialogButtonBox *mpButtonBox; 42 | QLineEdit *ename; 43 | QLineEdit *eurl; 44 | StringListModel *model = 0; 45 | QMap links; 46 | void initModelData(); 47 | void saveLinks(QString name, QString urls); 48 | void deleteLinks(QString name); 49 | bool ValidURL(const QString &url); 50 | }; 51 | 52 | 53 | #endif // WebConfigPage_H 54 | -------------------------------------------------------------------------------- /config/configwebmemu.cpp: -------------------------------------------------------------------------------- 1 | #include "configwebmemu.h" 2 | #include "common/Config.h" 3 | 4 | 5 | ConfigWebMemu::ConfigWebMemu(QWidget *parent) : 6 | QMenu(parent) 7 | { 8 | initMenuItems(); 9 | init(); 10 | } 11 | 12 | ConfigWebMemu::~ConfigWebMemu() 13 | { 14 | if (mpXunoBrowser) { 15 | delete mpXunoBrowser; 16 | mpXunoBrowser = 0; 17 | } 18 | } 19 | 20 | void ConfigWebMemu::openurl(QAction * a){ 21 | int i=a->data().toInt(); 22 | qDebug() << i << menuitemList.at(i)->name << menuitemList.at(i)->url; 23 | if (!QUrl(menuitemList.at(i)->url).host().isEmpty()) 24 | onXunoBrowser(menuitemList.at(i)->url); 25 | } 26 | 27 | void ConfigWebMemu::initMenuItems(){ 28 | 29 | QMap links = QMap(Config::instance().WebLinks()); 30 | QStringList names = links.keys(); 31 | QList urls = links.values(); 32 | 33 | menuitemList.clear(); 34 | //For Fixed list items 35 | //menuitemList.append(new MenuItems({"Xuno","http://www.xuno.com/playlist_8bit.php",":/www.xuno.net.ico"})); 36 | //menuitemList.append(new MenuItems({"Google","https://www.google.com",":/www.google.com.ico"})); 37 | 38 | if (names.size()){ 39 | for (int i = 0; i < names.size(); ++i){ 40 | QString iconlink=""; 41 | QString urli=urls[i].toString(); 42 | if (QUrl(urli).host().startsWith("www.xuno.com")){ 43 | iconlink= ":/www.xuno.net.ico"; 44 | }else if (QUrl(urli).host().startsWith("www.google.com")){ 45 | iconlink= ":/www.google.com.ico"; 46 | } 47 | menuitemList.append(new MenuItems({names[i],urli ,iconlink})); 48 | } 49 | }else{ 50 | menuitemList.append(new MenuItems({tr("Empty list, please define it in setup"),"" ,""})); 51 | } 52 | XUNOserverUrl="http://www.xuno.com"; 53 | XUNOpresetUrl=XUNOserverUrl+"/getpreset.php?"; 54 | } 55 | 56 | void ConfigWebMemu::init(){ 57 | clear(); 58 | for (int i=0;iiconurl; 60 | if (iconurl.isEmpty()){ 61 | QUrl iurl= QUrl(QString(menuitemList.at(i)->url).append("/favicon.ico")); 62 | } 63 | QIcon* ic = new QIcon(iconurl); 64 | QAction* qa = addAction(*ic,menuitemList.at(i)->name); 65 | qa->setData(i); 66 | } 67 | connect(this, SIGNAL(triggered(QAction *)), this, SLOT(openurl(QAction *))); 68 | } 69 | 70 | 71 | void ConfigWebMemu::onXunoBrowser(QString url){ 72 | 73 | bool emp=url.isEmpty(); 74 | 75 | if (!mpXunoBrowser){ 76 | mpXunoBrowser = new XunoBrowser(Q_NULLPTR,XunoVersion); 77 | mpXunoBrowser->setXUNOContentUrl(QString(XUNOserverUrl).append("/content/")); 78 | connect(mpXunoBrowser, SIGNAL(clicked()), SLOT(onClickXunoBrowser())); 79 | } 80 | if (mpXunoBrowser->isHidden()) mpXunoBrowser->show(); 81 | 82 | if (emp) { 83 | mpXunoBrowser->setUrl(QUrl(QString(XUNOserverUrl).append("/playlist_12bit.php"))); 84 | }else{ 85 | mpXunoBrowser->setUrl(url); 86 | } 87 | } 88 | 89 | void ConfigWebMemu::onClickXunoBrowser(){ 90 | QUrl url=mpXunoBrowser->getClikedUrl(); 91 | emit onPlayXunoBrowser(url); 92 | } 93 | 94 | void ConfigWebMemu::setXunoVersion(const QString &value) 95 | { 96 | XunoVersion = value; 97 | } 98 | 99 | 100 | void ConfigWebMemu::onChanged(){ 101 | initMenuItems(); 102 | init(); 103 | } 104 | 105 | -------------------------------------------------------------------------------- /config/configwebmemu.h: -------------------------------------------------------------------------------- 1 | #ifndef CONFIGWEBMEMU_H 2 | #define CONFIGWEBMEMU_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include "XunoBrowser.h" 8 | 9 | class ConfigWebMemu : public QMenu 10 | { 11 | Q_OBJECT 12 | 13 | public: 14 | explicit ConfigWebMemu(QWidget *parent = nullptr); 15 | ~ConfigWebMemu(); 16 | 17 | void setXunoVersion(const QString &value); 18 | 19 | signals: 20 | void onPlayXunoBrowser(QUrl url); 21 | 22 | public slots: 23 | void onChanged(); 24 | 25 | private slots: 26 | void openurl(QAction *a); 27 | void onClickXunoBrowser(); 28 | 29 | private: 30 | XunoBrowser* mpXunoBrowser = nullptr; 31 | QString XUNOserverUrl, XUNOpresetUrl, XunoVersion; 32 | 33 | struct MenuItems { 34 | QString name; 35 | QString url; 36 | QString iconurl; 37 | }; 38 | QList menuitemList; 39 | 40 | void init(); 41 | void initMenuItems(); 42 | void onXunoBrowser(QString url); 43 | }; 44 | 45 | 46 | #endif // CONFIGWEBMEMU_H 47 | -------------------------------------------------------------------------------- /config/configwebmemu.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ConfigWebMemu 6 | 7 | 8 | 9 | 0 10 | 0 11 | 400 12 | 300 13 | 14 | 15 | 16 | Form 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /darkstyle.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | darkstyle/darkstyle.qss 4 | darkstyle/icon_close.png 5 | darkstyle/icon_undock.png 6 | darkstyle/icon_branch_closed.png 7 | darkstyle/icon_branch_end.png 8 | darkstyle/icon_branch_more.png 9 | darkstyle/icon_branch_open.png 10 | darkstyle/icon_vline.png 11 | darkstyle/icon_checkbox_checked.png 12 | darkstyle/icon_checkbox_indeterminate.png 13 | darkstyle/icon_checkbox_unchecked.png 14 | darkstyle/icon_checkbox_checked_pressed.png 15 | darkstyle/icon_checkbox_indeterminate_pressed.png 16 | darkstyle/icon_checkbox_unchecked_pressed.png 17 | darkstyle/icon_checkbox_checked_disabled.png 18 | darkstyle/icon_checkbox_indeterminate_disabled.png 19 | darkstyle/icon_checkbox_unchecked_disabled.png 20 | darkstyle/icon_radiobutton_checked.png 21 | darkstyle/icon_radiobutton_unchecked.png 22 | darkstyle/icon_radiobutton_checked_pressed.png 23 | darkstyle/icon_radiobutton_unchecked_pressed.png 24 | darkstyle/icon_radiobutton_checked_disabled.png 25 | darkstyle/icon_radiobutton_unchecked_disabled.png 26 | 27 | 28 | -------------------------------------------------------------------------------- /darkstyle/darkstyle.qss: -------------------------------------------------------------------------------- 1 | QToolTip{ 2 | color:#ffffff; 3 | background-color:palette(base); 4 | border:1px solid palette(highlight); 5 | border-radius:4px; 6 | } 7 | QStatusBar{ 8 | background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 9 | color:palette(mid); 10 | } 11 | QMenuBar{ 12 | background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 13 | border-bottom:2px solid rgba(25,25,25,75); 14 | } 15 | QMenuBar::item{ 16 | spacing:2px; 17 | padding:3px 4px; 18 | background:transparent; 19 | } 20 | QMenuBar::item:selected{ 21 | background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(106,106,106,255),stop:1 rgba(106,106,106,75)); 22 | border-left:1px solid rgba(106,106,106,127); 23 | border-right:1px solid rgba(106,106,106,127); 24 | } 25 | QMenuBar::item:pressed{ 26 | background-color:palette(highlight); 27 | border-left:1px solid rgba(25,25,25,127); 28 | border-right:1px solid rgba(25,25,25,127); 29 | } 30 | QMenu{ 31 | background-color:palette(window); 32 | border:1px solid palette(shadow); 33 | } 34 | QMenu::item{ 35 | padding:3px 25px 3px 25px; 36 | border:1px solid transparent; 37 | } 38 | QMenu::item:disabled{ 39 | background-color:rgba(35,35,35,127); 40 | color:palette(disabled); 41 | } 42 | QMenu::item:selected{ 43 | border-color:rgba(147,191,236,127); 44 | background:palette(highlight); 45 | } 46 | QMenu::icon:checked{ 47 | background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 48 | border:1px solid palette(highlight); 49 | border-radius:2px; 50 | } 51 | QMenu::separator{ 52 | height:1px; 53 | background:palette(alternate-base); 54 | margin-left:5px; 55 | margin-right:5px; 56 | } 57 | QMenu::indicator{ 58 | width:18px; 59 | height:18px; 60 | } 61 | QMenu::indicator:non-exclusive:checked{ 62 | image:url(:/darkstyle/icon_checkbox_checked.png); 63 | padding-left:2px; 64 | } 65 | QMenu::indicator:non-exclusive:unchecked{ 66 | image:url(:/darkstyle/icon_checkbox_unchecked.png); 67 | padding-left:2px; 68 | } 69 | QMenu::indicator:exclusive:checked{ 70 | image:url(:/darkstyle/icon_radiobutton_checked.png); 71 | padding-left:2px; 72 | } 73 | QMenu::indicator:exclusive:unchecked{ 74 | image:url(:/darkstyle/icon_radiobutton_unchecked.png); 75 | padding-left:2px; 76 | } 77 | QToolBar::top{ 78 | background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 79 | border-bottom:3px solid qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 80 | } 81 | QToolBar::bottom{ 82 | background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 83 | border-top:3px solid qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 84 | } 85 | QToolBar::left{ 86 | background-color:qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 87 | border-right:3px solid qlineargradient(x1:0,y1:0,x2:1,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 88 | } 89 | QToolBar::right{ 90 | background-color:qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 91 | border-left:3px solid qlineargradient(x1:1,y1:0,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 92 | } 93 | QMainWindow::separator{ 94 | width:6px; 95 | height:5px; 96 | padding:2px; 97 | } 98 | QSplitter::handle:horizontal{ 99 | width:10px; 100 | } 101 | QSplitter::handle:vertical{ 102 | height:10px; 103 | } 104 | QMainWindow::separator:hover,QSplitter::handle:hover{ 105 | background:palette(highlight); 106 | } 107 | QDockWidget::title{ 108 | padding:4px; 109 | background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 110 | border:1px solid rgba(25,25,25,75); 111 | border-bottom:2px solid rgba(25,25,25,75); 112 | } 113 | QDockWidget{ 114 | titlebar-close-icon:url(:/darkstyle/icon_window_close.png); 115 | titlebar-normal-icon:url(:/darkstyle/icon_window_restore.png); 116 | } 117 | QDockWidget::close-button,QDockWidget::float-button{ 118 | subcontrol-position:top right; 119 | subcontrol-origin:margin; 120 | position:absolute; 121 | top:3px; 122 | bottom:0px; 123 | width:20px; 124 | height:20px; 125 | } 126 | QDockWidget::close-button{ 127 | right:3px; 128 | } 129 | QDockWidget::float-button{ 130 | right:25px; 131 | } 132 | QGroupBox{ 133 | background-color:rgba(66,66,66,50%); 134 | margin-top:23px; 135 | border:1px solid rgba(25,25,25,127); 136 | border-top-left-radius:4px; 137 | border-top-right-radius:4px; 138 | } 139 | QGroupBox::title{ 140 | subcontrol-origin:margin; 141 | subcontrol-position:left top; 142 | padding:4px 6px; 143 | margin-left:3px; 144 | background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 145 | border:1px solid rgba(25,25,25,75); 146 | border-top-left-radius:4px; 147 | border-top-right-radius:4px; 148 | } 149 | QTabWidget::pane{ 150 | background-color:rgba(66,66,66,50%); 151 | border-top:1px solid rgba(25,25,25,50%); 152 | } 153 | QTabWidget::tab-bar{ 154 | left:3px; 155 | top:1px; 156 | } 157 | QTabBar{ 158 | background-color:transparent; 159 | qproperty-drawBase:0; 160 | border-bottom:1px solid rgba(25,25,25,50%); 161 | } 162 | QTabBar::tab{ 163 | padding:4px 6px; 164 | background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 165 | border:1px solid rgba(25,25,25,75); 166 | border-top-left-radius:4px; 167 | border-top-right-radius:4px; 168 | } 169 | QTabBar::tab:selected,QTabBar::tab:hover{ 170 | background-color:qlineargradient(x1:0,y1:0,x2:0,y2:1,stop:0 rgba(53,53,53,127),stop:1 rgba(66,66,66,50%)); 171 | border-bottom-color:rgba(66,66,66,75%); 172 | } 173 | QTabBar::tab:selected{ 174 | border-bottom-color:rgba(66,66,66,75%); 175 | } 176 | QTabBar::tab:!selected{ 177 | margin-top:2px; 178 | } 179 | QCheckBox::indicator{ 180 | width:18px; 181 | height:18px; 182 | } 183 | QCheckBox::indicator:checked,QTreeView::indicator:checked,QTableView::indicator:checked,QGroupBox::indicator:checked{ 184 | image:url(:/darkstyle/icon_checkbox_checked.png); 185 | } 186 | QCheckBox::indicator:checked:pressed,QTreeView::indicator:checked:pressed,QTableView::indicator:checked:pressed,QGroupBox::indicator:checked:pressed{ 187 | image:url(:/darkstyle/icon_checkbox_checked_pressed.png); 188 | } 189 | QCheckBox::indicator:checked:disabled,QTreeView::indicator:checked:disabled,QTableView::indicator:checked:disabled,QGroupBox::indicator:checked:disabled{ 190 | image:url(:/darkstyle/icon_checkbox_checked_disabled.png); 191 | } 192 | QCheckBox::indicator:unchecked,QTreeView::indicator:unchecked,QTableView::indicator:unchecked,QGroupBox::indicator:unchecked{ 193 | image:url(:/darkstyle/icon_checkbox_unchecked.png); 194 | } 195 | QCheckBox::indicator:unchecked:pressed,QTreeView::indicator:unchecked:pressed,QTableView::indicator:unchecked:pressed,QGroupBox::indicator:unchecked:pressed{ 196 | image:url(:/darkstyle/icon_checkbox_unchecked_pressed.png); 197 | } 198 | QCheckBox::indicator:unchecked:disabled,QTreeView::indicator:unchecked:disabled,QTableView::indicator:unchecked:disabled,QGroupBox::indicator:unchecked:disabled{ 199 | image:url(:/darkstyle/icon_checkbox_unchecked_disabled.png); 200 | } 201 | QCheckBox::indicator:indeterminate,QTreeView::indicator:indeterminate,QTableView::indicator:indeterminate,QGroupBox::indicator:indeterminate{ 202 | image:url(:/darkstyle/icon_checkbox_indeterminate.png); 203 | } 204 | QCheckBox::indicator:indeterminate:pressed,QTreeView::indicator:indeterminate:pressed,QTableView::indicator:indeterminate:pressed,QGroupBox::indicator:indeterminate:pressed{ 205 | image:url(:/darkstyle/icon_checkbox_indeterminate_pressed.png); 206 | } 207 | QCheckBox::indicator:indeterminate:disabled,QTreeView::indicator:indeterminate:disabled,QTableView::indicator:indeterminate:disabled,QGroupBox::indicator:indeterminate:disabled{ 208 | image:url(:/darkstyle/icon_checkbox_indeterminate_disabled.png); 209 | } 210 | QRadioButton::indicator{ 211 | width:18px; 212 | height:18px; 213 | } 214 | QRadioButton::indicator:checked{ 215 | image:url(:/darkstyle/icon_radiobutton_checked.png); 216 | } 217 | QRadioButton::indicator:checked:pressed{ 218 | image:url(:/darkstyle/icon_radiobutton_checked_pressed.png); 219 | } 220 | QRadioButton::indicator:checked:disabled{ 221 | image:url(:/darkstyle/icon_radiobutton_checked_disabled.png); 222 | } 223 | QRadioButton::indicator:unchecked{ 224 | image:url(:/darkstyle/icon_radiobutton_unchecked.png); 225 | } 226 | QRadioButton::indicator:unchecked:pressed{ 227 | image:url(:/darkstyle/icon_radiobutton_unchecked_pressed.png); 228 | } 229 | QRadioButton::indicator:unchecked:disabled{ 230 | image:url(:/darkstyle/icon_radiobutton_unchecked_disabled.png); 231 | } 232 | QTreeView, QTableView{ 233 | alternate-background-color:palette(window); 234 | background:palette(base); 235 | } 236 | QTreeView QHeaderView::section, QTableView QHeaderView::section{ 237 | /*height:24px;*/ 238 | background-color:qlineargradient(x1:0,y1:1,x2:0,y2:0,stop:0 rgba(25,25,25,127),stop:1 rgba(53,53,53,75)); 239 | border-style:none; 240 | border-bottom:1px solid palette(dark); 241 | padding-left:5px; 242 | padding-right:5px; 243 | } 244 | QTreeView::item:selected:disabled, QTableView::item:selected:disabled{ 245 | background:rgb(80,80,80); 246 | } 247 | QTreeView::branch{ 248 | background-color:palette(base); 249 | } 250 | QTreeView::branch:has-siblings:!adjoins-item{ 251 | border-image:url(:/darkstyle/icon_vline.png) 0; 252 | } 253 | QTreeView::branch:has-siblings:adjoins-item{ 254 | border-image:url(:/darkstyle/icon_branch_more.png) 0; 255 | } 256 | QTreeView::branch:!has-children:!has-siblings:adjoins-item{ 257 | border-image:url(:/darkstyle/icon_branch_end.png) 0; 258 | } 259 | QTreeView::branch:has-children:!has-siblings:closed, 260 | QTreeView::branch:closed:has-children:has-siblings{ 261 | border-image:none; 262 | image:url(:/darkstyle/icon_branch_closed.png); 263 | } 264 | QTreeView::branch:open:has-children:!has-siblings, 265 | QTreeView::branch:open:has-children:has-siblings{ 266 | border-image:none; 267 | image:url(:/darkstyle/icon_branch_open.png); 268 | } 269 | QScrollBar:vertical{ 270 | background:palette(base); 271 | border-top-right-radius:2px; 272 | border-bottom-right-radius:2px; 273 | width:16px; 274 | margin:0px; 275 | } 276 | QScrollBar::handle:vertical{ 277 | background-color:palette(alternate-base); 278 | border-radius:2px; 279 | min-height:20px; 280 | margin:2px 4px 2px 4px; 281 | } 282 | QScrollBar::handle:vertical:hover{ 283 | background-color:palette(highlight); 284 | } 285 | QScrollBar::add-line:vertical{ 286 | background:none; 287 | height:0px; 288 | subcontrol-position:right; 289 | subcontrol-origin:margin; 290 | } 291 | QScrollBar::sub-line:vertical{ 292 | background:none; 293 | height:0px; 294 | subcontrol-position:left; 295 | subcontrol-origin:margin; 296 | } 297 | QScrollBar:horizontal{ 298 | background:palette(base); 299 | height:16px; 300 | margin:0px; 301 | } 302 | QScrollBar::handle:horizontal{ 303 | background-color:palette(alternate-base); 304 | border-radius:2px; 305 | min-width:20px; 306 | margin:4px 2px 4px 2px; 307 | } 308 | QScrollBar::handle:horizontal:hover{ 309 | background-color:palette(highlight); 310 | } 311 | QScrollBar::add-line:horizontal{ 312 | background:none; 313 | width:0px; 314 | subcontrol-position:bottom; 315 | subcontrol-origin:margin; 316 | } 317 | QScrollBar::sub-line:horizontal{ 318 | background:none; 319 | width:0px; 320 | subcontrol-position:top; 321 | subcontrol-origin:margin; 322 | } 323 | QSlider::handle:horizontal{ 324 | border-radius:4px; 325 | border:1px solid rgba(25,25,25,255); 326 | background-color:palette(alternate-base); 327 | min-height:20px; 328 | margin:0 -4px; 329 | } 330 | QSlider::handle:horizontal:hover{ 331 | background:palette(highlight); 332 | } 333 | QSlider::add-page:horizontal{ 334 | background:palette(base); 335 | } 336 | QSlider::sub-page:horizontal{ 337 | background:palette(highlight); 338 | } 339 | QSlider::sub-page:horizontal:disabled{ 340 | background:rgb(80,80,80); 341 | } 342 | -------------------------------------------------------------------------------- /darkstyle/icon_branch_closed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_branch_closed.png -------------------------------------------------------------------------------- /darkstyle/icon_branch_end.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_branch_end.png -------------------------------------------------------------------------------- /darkstyle/icon_branch_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_branch_more.png -------------------------------------------------------------------------------- /darkstyle/icon_branch_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_branch_open.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_checked.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_checked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_checked_disabled.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_checked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_checked_pressed.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_indeterminate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_indeterminate.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_indeterminate_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_indeterminate_disabled.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_indeterminate_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_indeterminate_pressed.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_unchecked.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_unchecked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_unchecked_disabled.png -------------------------------------------------------------------------------- /darkstyle/icon_checkbox_unchecked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_checkbox_unchecked_pressed.png -------------------------------------------------------------------------------- /darkstyle/icon_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_close.png -------------------------------------------------------------------------------- /darkstyle/icon_radiobutton_checked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_radiobutton_checked.png -------------------------------------------------------------------------------- /darkstyle/icon_radiobutton_checked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_radiobutton_checked_disabled.png -------------------------------------------------------------------------------- /darkstyle/icon_radiobutton_checked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_radiobutton_checked_pressed.png -------------------------------------------------------------------------------- /darkstyle/icon_radiobutton_unchecked.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_radiobutton_unchecked.png -------------------------------------------------------------------------------- /darkstyle/icon_radiobutton_unchecked_disabled.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_radiobutton_unchecked_disabled.png -------------------------------------------------------------------------------- /darkstyle/icon_radiobutton_unchecked_pressed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_radiobutton_unchecked_pressed.png -------------------------------------------------------------------------------- /darkstyle/icon_restore.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_restore.png -------------------------------------------------------------------------------- /darkstyle/icon_undock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_undock.png -------------------------------------------------------------------------------- /darkstyle/icon_vline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/darkstyle/icon_vline.png -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "XunoPlayerMPV.h" 3 | #include "DarkStyle.h" 4 | 5 | 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | QApplication a(argc, argv); 10 | // Qt sets the locale in the QApplication constructor, but libmpv requires 11 | // the LC_NUMERIC category to be set to "C", so change it back. 12 | 13 | 14 | QCoreApplication::setApplicationName("XunoPlayer-MPV"); 15 | QCoreApplication::setOrganizationName("Aaex Corp. www.xuno.com."); 16 | QCoreApplication::setApplicationVersion(VERGIT); 17 | QCommandLineParser parser; 18 | 19 | parser.setApplicationDescription("XunoPlayer-MPV. Aaex Corp. www.xuno.com."); 20 | parser.addHelpOption(); 21 | parser.addVersionOption(); 22 | parser.addPositionalArgument("url", "The URL to open."); 23 | parser.process(a); 24 | 25 | // style our application with custom dark style 26 | a.setStyle(new DarkStyle); 27 | #ifdef unix 28 | setlocale(LC_NUMERIC, "C"); 29 | #endif 30 | XunoPlayerMpv w; 31 | w.show(); 32 | 33 | if (!parser.positionalArguments().isEmpty()) { 34 | QList urls; 35 | foreach (const QString &a, parser.positionalArguments()) 36 | urls.append(QUrl::fromUserInput(a, QDir::currentPath(), QUrl::DefaultResolution)); 37 | w.OpenAndPlay(urls.at(0)); 38 | } 39 | 40 | return a.exec(); 41 | } 42 | -------------------------------------------------------------------------------- /mpvwidget.cpp: -------------------------------------------------------------------------------- 1 | #include "mpvwidget.h" 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | static void wakeup(void *ctx) 11 | { 12 | QMetaObject::invokeMethod(static_cast(ctx), "on_mpv_events", Qt::QueuedConnection); 13 | } 14 | 15 | static void *get_proc_address(void *ctx, const char *name) { 16 | Q_UNUSED(ctx); 17 | QOpenGLContext *glctx = QOpenGLContext::currentContext(); 18 | if (!glctx) 19 | return nullptr; 20 | return reinterpret_cast(glctx->getProcAddress(QByteArray(name))); 21 | } 22 | 23 | 24 | MpvWidget::MpvWidget(QWidget *parent, Qt::WindowFlags f) 25 | : QOpenGLWidget(parent, f) 26 | { 27 | //mpv = mpv::qt::Handle::FromRawHandle(mpv_create()); 28 | mpv = mpv_create(); 29 | if (!mpv) 30 | throw std::runtime_error("could not create mpv context"); 31 | 32 | // QDir dir("."); 33 | // QString curdir=dir.absolutePath() ; 34 | 35 | 36 | 37 | 38 | mpv_set_option_string(mpv, "terminal", "yes"); 39 | //mpv_set_option_string(mpv,"msg-time", ""); 40 | //mpv_set_option_string(mpv, "msg-level", "all=v"); 41 | 42 | //XUNO 43 | // mpv_set_option_string(mpv, "opengl-pbo", "yes"); 44 | //QString curdir=QDir::currentPath(); 45 | //QString shaderdir=QDir::toNativeSeparators(QDir::currentPath().append("\\shaders\\gather\\ravu-r4-yuv.hook")); 46 | 47 | //qDebug()<<"shaderdir"<(mpv_get_sub_api(mpv, MPV_SUB_API_OPENGL_CB)); 110 | // if (!mpv_gl) 111 | // throw std::runtime_error("OpenGL not compiled in"); 112 | // mpv_opengl_cb_set_update_callback(mpv_gl, MpvWidget::on_update, static_cast(this)); 113 | // connect(this, SIGNAL(frameSwapped()), SLOT(swapped())); 114 | 115 | mpv_observe_property(mpv, 0, "duration", MPV_FORMAT_DOUBLE); 116 | mpv_observe_property(mpv, 0, "time-pos", MPV_FORMAT_DOUBLE); 117 | mpv_set_wakeup_callback(mpv, wakeup, this); 118 | 119 | if (mpv_initialize(mpv) < 0) 120 | throw std::runtime_error("could not initialize mpv context"); 121 | 122 | //mpv::qt::command_variant(mpv, QVariantList()<<"load-script"<<"ytdl_hook.lua"); 123 | 124 | } 125 | 126 | MpvWidget::~MpvWidget() 127 | { 128 | // makeCurrent(); 129 | // if (mpv_gl) 130 | // mpv_opengl_cb_set_update_callback(mpv_gl, Q_NULLPTR, Q_NULLPTR); 131 | // // Until this call is done, we need to make sure the player remains 132 | // // alive. This is done implicitly with the mpv::qt::Handle instance 133 | // // in this class. 134 | // mpv_opengl_cb_uninit_gl(mpv_gl); 135 | makeCurrent(); 136 | if (mpv_gl) 137 | mpv_render_context_free(mpv_gl); 138 | mpv_terminate_destroy(mpv); 139 | 140 | } 141 | 142 | void MpvWidget::command(const QVariant& params) 143 | { 144 | mpv::qt::command(mpv, params); 145 | } 146 | 147 | QVariant MpvWidget::command_result(const QVariant& params) 148 | { 149 | return mpv::qt::command(mpv, params); 150 | } 151 | 152 | void MpvWidget::setOption(const QString &name, const QString parameter) 153 | { 154 | mpv_set_option_string(mpv, name.toLatin1().data(), parameter.toLatin1().data()); 155 | } 156 | 157 | qreal MpvWidget::current_fps() 158 | { 159 | return fps; 160 | } 161 | 162 | void MpvWidget::setProperty(const QString& name, const QVariant& value) 163 | { 164 | mpv::qt::set_property_variant(mpv, name, value); 165 | } 166 | 167 | QVariant MpvWidget::getProperty(const QString &name) const 168 | { 169 | return mpv::qt::get_property_variant(mpv, name); 170 | } 171 | 172 | void MpvWidget::initializeGL() 173 | { 174 | 175 | mpv_opengl_init_params gl_init_params{get_proc_address, nullptr, nullptr}; 176 | mpv_render_param params[]{ 177 | {MPV_RENDER_PARAM_API_TYPE, const_cast(MPV_RENDER_API_TYPE_OPENGL)}, 178 | {MPV_RENDER_PARAM_OPENGL_INIT_PARAMS, &gl_init_params}, 179 | {MPV_RENDER_PARAM_INVALID, nullptr} 180 | }; 181 | 182 | if (mpv_render_context_create(&mpv_gl, mpv, params) < 0) 183 | throw std::runtime_error("failed to initialize mpv GL context"); 184 | mpv_render_context_set_update_callback(mpv_gl, MpvWidget::on_update, reinterpret_cast(this)); 185 | 186 | 187 | // int r = mpv::qt::mpv_opengl_cb_init_gl(mpv_gl, Q_NULLPTR, get_proc_address, Q_NULLPTR); 188 | // if (r < 0) 189 | // throw std::runtime_error("could not initialize OpenGL"); 190 | frameTime.start(); 191 | } 192 | 193 | void MpvWidget::paintGL() 194 | { 195 | // mpv_opengl_cb_draw(mpv_gl, static_cast(defaultFramebufferObject()), width(), -height()); 196 | 197 | mpv_opengl_fbo mpfbo{static_cast(defaultFramebufferObject()), width(), height(), 0}; 198 | int flip_y{1}; 199 | 200 | mpv_render_param params[] = { 201 | {MPV_RENDER_PARAM_OPENGL_FBO, &mpfbo}, 202 | {MPV_RENDER_PARAM_FLIP_Y, &flip_y}, 203 | {MPV_RENDER_PARAM_INVALID, nullptr} 204 | }; 205 | // See render_gl.h on what OpenGL environment mpv expects, and 206 | // other API details. 207 | mpv_render_context_render(mpv_gl, params); 208 | 209 | 210 | ++frameCount; 211 | if (frameTime.elapsed() >= 1000) 212 | { 213 | fps = frameCount / (static_cast(frameTime.elapsed()/1000.0)); 214 | frameCount=0; 215 | frameTime.restart(); 216 | } 217 | } 218 | 219 | void MpvWidget::swapped() 220 | { 221 | // mpv_opengl_cb_report_flip(mpv_gl, 0); 222 | } 223 | 224 | 225 | void MpvWidget::on_mpv_events() 226 | { 227 | // Process all events, until the event queue is empty. 228 | while (mpv) { 229 | mpv_event *event = mpv_wait_event(mpv, 0); 230 | if (event->event_id == MPV_EVENT_NONE) { 231 | break; 232 | } 233 | handle_mpv_event(event); 234 | } 235 | } 236 | 237 | void MpvWidget::handle_mpv_event(mpv_event *event) 238 | { 239 | switch (event->event_id) { 240 | case MPV_EVENT_PROPERTY_CHANGE: { 241 | mpv_event_property *prop = static_cast(event->data); 242 | if (strcmp(prop->name, "time-pos") == 0) { 243 | if (prop->format == MPV_FORMAT_DOUBLE) { 244 | double time = *static_cast(prop->data); 245 | Q_EMIT positionChanged(static_cast(time)); 246 | } 247 | } else if (strcmp(prop->name, "duration") == 0) { 248 | if (prop->format == MPV_FORMAT_DOUBLE) { 249 | double time = *static_cast(prop->data); 250 | Q_EMIT durationChanged(static_cast(time)); 251 | } 252 | } 253 | break; 254 | } 255 | case MPV_EVENT_START_FILE:{ 256 | Q_EMIT mpv_on_START_FILE(); 257 | break; 258 | } 259 | case MPV_EVENT_FILE_LOADED:{ 260 | Q_EMIT mpv_on_FILE_LOADED(); 261 | break; 262 | } 263 | case MPV_EVENT_PAUSE:{ 264 | Q_EMIT mpv_on_PAUSE(); 265 | break; 266 | } 267 | case MPV_EVENT_END_FILE:{ 268 | Q_EMIT mpv_on_END_FILE(); 269 | break; 270 | } 271 | 272 | 273 | default: ; 274 | // Ignore uninteresting or unknown events. 275 | } 276 | } 277 | 278 | 279 | // Make Qt invoke mpv_opengl_cb_draw() to draw a new/updated video frame. 280 | void MpvWidget::maybeUpdate() 281 | { 282 | // If the Qt window is not visible, Qt's update() will just skip rendering. 283 | // This confuses mpv's opengl-cb API, and may lead to small occasional 284 | // freezes due to video rendering timing out. 285 | // Handle this by manually redrawing. 286 | // Note: Qt doesn't seem to provide a way to query whether update() will 287 | // be skipped, and the following code still fails when e.g. switching 288 | // to a different workspace with a reparenting window manager. 289 | if (window()->isMinimized()) { 290 | makeCurrent(); 291 | paintGL(); 292 | context()->swapBuffers(context()->surface()); 293 | //swapped(); 294 | doneCurrent(); 295 | } else { 296 | update(); 297 | } 298 | } 299 | 300 | void MpvWidget::on_update(void *ctx) 301 | { 302 | QMetaObject::invokeMethod(static_cast(ctx), "maybeUpdate"); 303 | } 304 | 305 | bool MpvWidget::getOsdmsg_used() const 306 | { 307 | return osdmsg_used; 308 | } 309 | 310 | void MpvWidget::setOsdmsg_used(bool value) 311 | { 312 | osdmsg_used = value; 313 | } 314 | 315 | -------------------------------------------------------------------------------- /mpvwidget.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef PLAYERWINDOW_H 3 | #define PLAYERWINDOW_H 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include "common/qthelper.hpp" 11 | 12 | class MpvWidget Q_DECL_FINAL: public QOpenGLWidget 13 | { 14 | Q_OBJECT 15 | public: 16 | MpvWidget(QWidget *parent = 0, Qt::WindowFlags f = 0); 17 | ~MpvWidget(); 18 | void command(const QVariant& params); 19 | void setProperty(const QString& name, const QVariant& value); 20 | QVariant getProperty(const QString& name) const; 21 | QSize sizeHint() const { return QSize(960, 540);} 22 | QVariant command_result(const QVariant ¶ms); 23 | void setOption(const QString &name, const QString parameter); 24 | qreal current_fps(); 25 | bool getOsdmsg_used() const; 26 | void setOsdmsg_used(bool value); 27 | 28 | Q_SIGNALS: 29 | void durationChanged(int value); 30 | void positionChanged(int value); 31 | void mpv_on_START_FILE(); 32 | void mpv_on_FILE_LOADED(); 33 | void mpv_on_PAUSE(); 34 | void mpv_on_END_FILE(); 35 | protected: 36 | void initializeGL() Q_DECL_OVERRIDE; 37 | void paintGL() Q_DECL_OVERRIDE; 38 | private Q_SLOTS: 39 | void swapped(); 40 | void on_mpv_events(); 41 | void maybeUpdate(); 42 | private: 43 | void handle_mpv_event(mpv_event *event); 44 | static void on_update(void *ctx); 45 | QTime frameTime; 46 | qreal fps; 47 | long frameCount; 48 | bool osdmsg_used=false; 49 | 50 | //mpv::qt::Handle mpv; 51 | mpv_handle *mpv; 52 | //mpv_opengl_cb_context *mpv_gl; 53 | mpv_render_context *mpv_gl; 54 | QWidget *mpv_container; 55 | }; 56 | 57 | 58 | 59 | #endif // PLAYERWINDOW_H 60 | -------------------------------------------------------------------------------- /playlist/PlayList.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "PlayList.h" 22 | #include "PlayListModel.h" 23 | #include "PlayListDelegate.h" 24 | #include "common/common.h" 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | PlayList::PlayList(QWidget *parent) : 33 | QWidget(parent) 34 | { 35 | mFirstShow = true; 36 | mMaxRows = -1; 37 | mpModel = new PlayListModel(this); 38 | mpDelegate = new PlayListDelegate(this); 39 | mpListView = new QListView; 40 | //mpListView->setResizeMode(QListView::Adjust); 41 | mpListView->setModel(mpModel); 42 | mpListView->setItemDelegate(mpDelegate); 43 | mpListView->setSelectionMode(QAbstractItemView::ExtendedSelection); //ctrl,shift 44 | mpListView->setEditTriggers(QAbstractItemView::NoEditTriggers); 45 | mpListView->setToolTip(QString::fromLatin1("Ctrl/Shift + ") + tr("Click to select multiple")); 46 | QVBoxLayout *vbl = new QVBoxLayout; 47 | setLayout(vbl); 48 | vbl->addWidget(mpListView); 49 | QHBoxLayout *hbl = new QHBoxLayout; 50 | 51 | mpClear = new QToolButton(0); 52 | mpClear->setText(tr("Clear")); 53 | mpRemove = new QToolButton(0); 54 | mpRemove->setText(QString::fromLatin1("-")); 55 | mpRemove->setToolTip(tr("Remove selected items")); 56 | mpAdd = new QToolButton(0); 57 | mpAdd->setText(QString::fromLatin1("+")); 58 | 59 | hbl->addWidget(mpClear); 60 | hbl->addSpacing(width()); 61 | hbl->addWidget(mpRemove); 62 | hbl->addWidget(mpAdd); 63 | vbl->addLayout(hbl); 64 | connect(mpClear, SIGNAL(clicked()), SLOT(clearItems())); 65 | connect(mpRemove, SIGNAL(clicked()), SLOT(removeSelectedItems())); 66 | connect(mpAdd, SIGNAL(clicked()), SLOT(addItems())); 67 | connect(mpListView, SIGNAL(doubleClicked(QModelIndex)), SLOT(onAboutToPlay(QModelIndex))); 68 | // enter to highight 69 | //connect(mpListView, SIGNAL(entered(QModelIndex)), SLOT(highlight(QModelIndex))); 70 | } 71 | 72 | PlayList::~PlayList() 73 | { 74 | qDebug("+++++++++++++~PlayList()"); 75 | save(); 76 | } 77 | 78 | void PlayList::setSaveFile(const QString &file) 79 | { 80 | mFile = file; 81 | } 82 | 83 | QString PlayList::saveFile() const 84 | { 85 | return mFile; 86 | } 87 | 88 | void PlayList::load() 89 | { 90 | QFile f(mFile); 91 | if (!f.exists()) 92 | return; 93 | if (!f.open(QIODevice::ReadOnly)) 94 | return; 95 | QDataStream ds(&f); 96 | QList list; 97 | ds >> list; 98 | for (int i = 0; i < list.size(); ++i) { 99 | insertItemAt(list.at(i), i); 100 | } 101 | } 102 | 103 | void PlayList::save() 104 | { 105 | QFile f(mFile); 106 | if (!f.open(QIODevice::WriteOnly)) { 107 | qWarning("File open error: %s", qPrintable(f.errorString())); 108 | return; 109 | } 110 | QDataStream ds(&f); 111 | ds << mpModel->items(); 112 | } 113 | 114 | PlayListItem PlayList::itemAt(int row) 115 | { 116 | if (mpModel->rowCount() < 0) { 117 | qWarning("Invalid rowCount"); 118 | return PlayListItem(); 119 | } 120 | return mpModel->data(mpModel->index(row), Qt::DisplayRole).value(); 121 | } 122 | 123 | void PlayList::insertItemAt(const PlayListItem &item, int row) 124 | { 125 | if (mMaxRows > 0 && mpModel->rowCount() >= mMaxRows) { 126 | // +1 because new row is to be inserted 127 | mpModel->removeRows(mMaxRows, mpModel->rowCount() - mMaxRows + 1); 128 | } 129 | int i = mpModel->items().indexOf(item, row+1); 130 | if (i > 0) { 131 | mpModel->removeRow(i); 132 | } 133 | if (!mpModel->insertRow(row)) 134 | return; 135 | if (row > 0) { 136 | i = mpModel->items().lastIndexOf(item, row - 1); 137 | if (i >= 0) 138 | mpModel->removeRow(i); 139 | } 140 | setItemAt(item, row); 141 | changedWidhtRows(); 142 | } 143 | 144 | void PlayList::setItemAt(const PlayListItem &item, int row) 145 | { 146 | mpModel->setData(mpModel->index(row), QVariant::fromValue(item), Qt::DisplayRole); 147 | } 148 | 149 | void PlayList::insert(const QString &url, int row) 150 | { 151 | PlayListItem item; 152 | item.setUrl(url); 153 | item.setDuration(0); 154 | item.setLastTime(0); 155 | QString title = url; 156 | if (!url.contains(QLatin1String("://")) || url.startsWith(QLatin1String("file://"))) { 157 | title = QFileInfo(url).fileName(); 158 | } 159 | if (url.startsWith("http://")){ 160 | title = QString("http://%1/.../%2").arg(QUrl(url).host(),QUrl(url).fileName()); 161 | } 162 | if (url.startsWith("https://")){ 163 | title = QString("https://%1/.../%2").arg(QUrl(url).host(),QUrl(url).fileName()); 164 | } 165 | item.setTitle(title); 166 | insertItemAt(item, row); 167 | changedWidhtRows(); 168 | } 169 | 170 | void PlayList::remove(const QString &url) 171 | { 172 | for (int i = mpModel->rowCount() - 1; i >= 0; --i) { 173 | PlayListItem item = mpModel->data(mpModel->index(i), Qt::DisplayRole).value(); 174 | if (item.url() == url) { 175 | mpModel->removeRow(i); 176 | } 177 | } 178 | } 179 | 180 | void PlayList::setMaxRows(int r) 181 | { 182 | mMaxRows = r; 183 | } 184 | 185 | int PlayList::maxRows() const 186 | { 187 | return mMaxRows; 188 | } 189 | 190 | void PlayList::removeSelectedItems() 191 | { 192 | QItemSelectionModel *selection = mpListView->selectionModel(); 193 | if (!selection->hasSelection()) 194 | return; 195 | QModelIndexList s = selection->selectedIndexes(); 196 | for (int i = s.size()-1; i >= 0; --i) { 197 | mpModel->removeRow(s.at(i).row()); 198 | } 199 | changedWidhtRows(); 200 | } 201 | 202 | void PlayList::clearItems() 203 | { 204 | mpModel->removeRows(0, mpModel->rowCount()); 205 | } 206 | 207 | void PlayList::addItems() 208 | { 209 | // TODO: add url; 210 | QStringList files = QFileDialog::getOpenFileNames(0, tr("Select files")); 211 | if (files.isEmpty()) 212 | return; 213 | // TODO: check playlist file: m3u, pls... In another thread 214 | for (int i = 0; i < files.size(); ++i) { 215 | QString file = files.at(i); 216 | if (!QFileInfo(file).isFile()) 217 | continue; 218 | insert(file, i); 219 | } 220 | changedWidhtRows(); 221 | } 222 | 223 | void PlayList::onAboutToPlay(const QModelIndex &index) 224 | { 225 | emit aboutToPlay(index.data(Qt::DisplayRole).value().url()); 226 | save(); 227 | } 228 | 229 | void PlayList::changedWidhtRows(){ 230 | mpListView->setMinimumWidth(mpListView->sizeHintForColumn(0)+2); 231 | mpListView->updateGeometry(); 232 | } 233 | 234 | 235 | -------------------------------------------------------------------------------- /playlist/PlayList.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #ifndef PLAYLIST_H 23 | #define PLAYLIST_H 24 | 25 | #include 26 | #include 27 | #include "PlayListItem.h" 28 | 29 | QT_BEGIN_NAMESPACE 30 | class QListView; 31 | class QToolButton; 32 | QT_END_NAMESPACE 33 | class PlayListDelegate; 34 | 35 | class PlayListModel; 36 | class PlayList : public QWidget 37 | { 38 | Q_OBJECT 39 | public: 40 | explicit PlayList(QWidget *parent = 0); 41 | ~PlayList(); 42 | 43 | void setSaveFile(const QString& file); 44 | QString saveFile() const; 45 | void load(); 46 | void save(); 47 | 48 | PlayListItem itemAt(int row); 49 | void insertItemAt(const PlayListItem& item, int row = 0); 50 | void setItemAt(const PlayListItem& item, int row = 0); 51 | void remove(const QString& url); 52 | void insert(const QString& url, int row = 0); 53 | void setMaxRows(int r); 54 | int maxRows() const; 55 | void changedWidhtRows(); 56 | 57 | signals: 58 | void aboutToPlay(const QString& url); 59 | 60 | private slots: 61 | void removeSelectedItems(); 62 | void clearItems(); 63 | // 64 | void addItems(); 65 | 66 | void onAboutToPlay(const QModelIndex& index); 67 | //void highlight(const QModelIndex& index); 68 | private: 69 | QListView *mpListView; 70 | QToolButton *mpClear, *mpRemove, *mpAdd; 71 | PlayListDelegate *mpDelegate; 72 | PlayListModel *mpModel; 73 | int mMaxRows; 74 | QString mFile; 75 | bool mFirstShow; 76 | }; 77 | 78 | #endif // PLAYLIST_H 79 | -------------------------------------------------------------------------------- /playlist/PlayListDelegate.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "PlayListDelegate.h" 22 | #include "PlayListItem.h" 23 | 24 | #include 25 | #include 26 | #include "PlayListModel.h" 27 | 28 | static const int kMarginLeft = 4; 29 | static const int kMarginTop = 2; 30 | static const int kWidth = 380; 31 | static const int kHeightMax = 30; 32 | static const int kHeightMin = 20; 33 | 34 | PlayListDelegate::PlayListDelegate(QObject *parent) : 35 | QStyledItemDelegate(parent) 36 | { 37 | mHighlightRow = -1; 38 | } 39 | 40 | // dynamic height:http://www.qtcentre.org/threads/18879-solved-QListView-dynamic-item-height 41 | void PlayListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const 42 | { 43 | if (!index.data().canConvert()) { 44 | QStyledItemDelegate::paint(painter, option, index); 45 | return; 46 | } 47 | 48 | painter->save(); 49 | painter->translate(option.rect.topLeft()); //!!! 50 | painter->setRenderHint(QPainter::Antialiasing, true); 51 | PlayListItem pli = qvariant_cast(index.data(Qt::DisplayRole)); 52 | //selected state has different background 53 | bool detail = false; 54 | //TODO: draw border. wrong rect. http://stackoverflow.com/questions/18568594/correct-highlighting-with-qt-custom-delegates 55 | //const QWidget *widget = option.widget; 56 | //QStyle *style = widget ? widget->style() : QApplication::style(); 57 | if (option.state & QStyle::State_Selected) { 58 | detail = true; 59 | mSelectedRows.append(index.row()); 60 | painter->fillRect(QRect(0, 0, kWidth, kHeightMax), QColor(0, 100, 200, 100)); 61 | //style->drawControl(QStyle::CE_ItemViewItem, &option, painter, widget); 62 | } else { 63 | mSelectedRows.removeAll(index.row()); 64 | } 65 | // if check QStyle::State_HasFocus, updateLayout() will be called infinitly, why? 66 | if (option.state & (QStyle::State_MouseOver)) { 67 | detail = true; 68 | PlayListModel *m = (PlayListModel*)index.model(); 69 | if (m && mHighlightRow != index.row()) { 70 | mHighlightRow = index.row(); 71 | m->updateLayout(); 72 | } 73 | painter->fillRect(QRect(0, 0, kWidth, kHeightMax), QColor(0, 100, 200, 30)); 74 | } 75 | QFont ft; 76 | ft.setBold(detail); 77 | ft.setPixelSize(12);//kHeightMin - 2*kMarginTop); 78 | painter->setFont(ft); 79 | painter->translate(kMarginLeft, kMarginTop); 80 | painter->drawText(QRect(0, 0, kWidth - 2*kMarginLeft, kHeightMin - 2*kMarginTop), pli.title()); 81 | painter->translate(0, kHeightMin + kMarginTop); 82 | if (detail) { 83 | painter->save(); 84 | ft.setBold(false); 85 | ft.setPixelSize(8);//(kHeightMax - kHeightMin - 2*kMarginTop)); 86 | painter->setFont(ft); 87 | painter->drawText(0, 0, pli.lastTimeString() + QString::fromLatin1("/") + pli.durationString()); 88 | painter->restore(); 89 | } 90 | painter->restore(); 91 | } 92 | 93 | // http://qt-project.org/forums/viewthread/5741 94 | QSize PlayListDelegate::sizeHint(const QStyleOptionViewItem &option, 95 | const QModelIndex &index) const 96 | { 97 | if (!index.data().canConvert()) { 98 | return QStyledItemDelegate::sizeHint(option, index); 99 | } 100 | bool detail = option.state & (QStyle::State_Selected|QStyle::State_MouseOver); 101 | // TODO: why detail always false? 102 | if (detail || mHighlightRow == index.row() || mSelectedRows.contains(index.row())) { 103 | return QSize(kWidth, kHeightMax); 104 | } 105 | return QSize(kWidth, kHeightMin); 106 | } 107 | -------------------------------------------------------------------------------- /playlist/PlayListDelegate.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #ifndef PLAYLISTDELEGATE_H 23 | #define PLAYLISTDELEGATE_H 24 | 25 | #include 26 | 27 | class PlayListDelegate : public QStyledItemDelegate 28 | { 29 | Q_OBJECT 30 | public: 31 | explicit PlayListDelegate(QObject *parent = 0); 32 | 33 | virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex & index) const; 34 | virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; 35 | 36 | private: 37 | mutable int mHighlightRow; 38 | mutable QList mSelectedRows; 39 | }; 40 | 41 | #endif // PLAYLISTDELEGATE_H 42 | -------------------------------------------------------------------------------- /playlist/PlayListItem.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #include "PlayListItem.h" 23 | #include 24 | #include 25 | 26 | QDataStream& operator>> (QDataStream& s, PlayListItem& p) 27 | { 28 | int stars; 29 | qint64 duration, last_time; 30 | QString url, title; 31 | s >> url >> title >> duration >> last_time >> stars; 32 | p.setTitle(title); 33 | p.setUrl(url); 34 | p.setStars(stars); 35 | p.setDuration(duration); 36 | p.setLastTime(last_time); 37 | return s; 38 | } 39 | 40 | QDataStream& operator<< (QDataStream& s, const PlayListItem& p) 41 | { 42 | s << p.url() << p.title() << p.duration() << p.lastTime() << p.stars(); 43 | return s; 44 | } 45 | 46 | PlayListItem::PlayListItem() 47 | : mStars(0) 48 | , mLastTime(0) 49 | , mDuration(0) 50 | { 51 | } 52 | 53 | void PlayListItem::setTitle(const QString &title) 54 | { 55 | mTitle = title; 56 | } 57 | 58 | QString PlayListItem::title() const 59 | { 60 | return mTitle; 61 | } 62 | 63 | void PlayListItem::setUrl(const QString &url) 64 | { 65 | mUrl = url; 66 | } 67 | 68 | QString PlayListItem::url() const 69 | { 70 | return mUrl; 71 | } 72 | 73 | void PlayListItem::setStars(int s) 74 | { 75 | mStars = s; 76 | } 77 | 78 | int PlayListItem::stars() const 79 | { 80 | return mStars; 81 | } 82 | 83 | void PlayListItem::setLastTime(qint64 ms) 84 | { 85 | mLastTime = ms; 86 | mLastTimeS = QTime(0, 0, 0, 0).addMSecs(ms).toString(QString::fromLatin1("HH:mm:ss")); 87 | } 88 | 89 | qint64 PlayListItem::lastTime() const 90 | { 91 | return mLastTime; 92 | } 93 | 94 | QString PlayListItem::lastTimeString() const 95 | { 96 | return mLastTimeS; 97 | } 98 | 99 | void PlayListItem::setDuration(qint64 ms) 100 | { 101 | mDuration = ms; 102 | mDurationS = QTime(0, 0, 0, 0).addMSecs(ms).toString(QString::fromLatin1("HH:mm:ss")); 103 | } 104 | 105 | qint64 PlayListItem::duration() const 106 | { 107 | return mDuration; 108 | } 109 | 110 | QString PlayListItem::durationString() const 111 | { 112 | return mDurationS; 113 | } 114 | 115 | bool PlayListItem::operator ==(const PlayListItem& other) const 116 | { 117 | return url() == other.url(); 118 | } 119 | -------------------------------------------------------------------------------- /playlist/PlayListItem.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #ifndef PLAYLISTITEM_H 23 | #define PLAYLISTITEM_H 24 | 25 | #include 26 | #include 27 | 28 | class PlayListItem 29 | { 30 | public: 31 | PlayListItem(); 32 | void setTitle(const QString& title); 33 | QString title() const; 34 | void setUrl(const QString& url); 35 | QString url() const; 36 | void setStars(int s); 37 | int stars() const; 38 | void setLastTime(qint64 ms); 39 | qint64 lastTime() const; 40 | QString lastTimeString() const; 41 | void setDuration(qint64 ms); 42 | qint64 duration() const; 43 | QString durationString() const; 44 | //icon 45 | bool operator ==(const PlayListItem& other) const; 46 | private: 47 | QString mTitle; 48 | QString mUrl; 49 | int mStars; 50 | qint64 mLastTime, mDuration; 51 | QString mLastTimeS, mDurationS; 52 | }; 53 | 54 | Q_DECLARE_METATYPE(PlayListItem); 55 | 56 | QDataStream& operator>> (QDataStream& s, PlayListItem& p); 57 | QDataStream& operator<< (QDataStream& s, const PlayListItem& p); 58 | 59 | #endif // PLAYLISTITEM_H 60 | -------------------------------------------------------------------------------- /playlist/PlayListModel.cpp: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #include "PlayListModel.h" 22 | #include "PlayListItem.h" 23 | #include 24 | 25 | PlayListModel::PlayListModel(QObject *parent) : 26 | QAbstractListModel(parent) 27 | { 28 | } 29 | 30 | QList PlayListModel::items() const 31 | { 32 | return mItems; 33 | } 34 | 35 | Qt::ItemFlags PlayListModel::flags(const QModelIndex &index) const 36 | { 37 | if (!index.isValid()) 38 | return QAbstractListModel::flags(index) | Qt::ItemIsDropEnabled;; 39 | return QAbstractListModel::flags(index) | Qt::ItemIsSelectable; 40 | } 41 | 42 | int PlayListModel::rowCount(const QModelIndex &parent) const 43 | { 44 | if (parent.isValid()) 45 | return 0; 46 | 47 | return mItems.size(); 48 | } 49 | 50 | QVariant PlayListModel::data(const QModelIndex &index, int role) const 51 | { 52 | QVariant v; 53 | if (index.row() < 0 || index.row() >= mItems.size()) 54 | return v; 55 | 56 | if (role == Qt::DisplayRole || role == Qt::EditRole) 57 | v.setValue(mItems.at(index.row())); 58 | 59 | return v; 60 | } 61 | 62 | bool PlayListModel::setData(const QModelIndex &index, const QVariant &value, int role) 63 | { 64 | if (index.row() >= 0 && index.row() < mItems.size() 65 | && (role == Qt::EditRole || role == Qt::DisplayRole)) { 66 | // TODO: compare value? 67 | mItems.replace(index.row(), value.value()); 68 | #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) 69 | emit dataChanged(index, index, QVector() << role); 70 | #else 71 | emit dataChanged(index, index); 72 | #endif 73 | return true; 74 | } 75 | return false; 76 | } 77 | 78 | 79 | bool PlayListModel::insertRows(int row, int count, const QModelIndex &parent) 80 | { 81 | if (count < 1 || row < 0 || row > rowCount(parent)) 82 | return false; 83 | beginInsertRows(QModelIndex(), row, row + count - 1); 84 | for (int r = 0; r < count; ++r) 85 | mItems.insert(row, PlayListItem()); 86 | endInsertRows(); 87 | return true; 88 | } 89 | 90 | 91 | bool PlayListModel::removeRows(int row, int count, const QModelIndex &parent) 92 | { 93 | if (count <= 0 || row < 0 || (row + count) > rowCount(parent)) 94 | return false; 95 | beginRemoveRows(QModelIndex(), row, row + count - 1); 96 | for (int r = 0; r < count; ++r) 97 | mItems.removeAt(row); 98 | endRemoveRows(); 99 | return true; 100 | } 101 | 102 | void PlayListModel::updateLayout() 103 | { 104 | emit layoutChanged(); 105 | } 106 | -------------------------------------------------------------------------------- /playlist/PlayListModel.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2012-2014 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | 22 | #ifndef PLAYLISTMODEL_H 23 | #define PLAYLISTMODEL_H 24 | 25 | #include 26 | #include "PlayListItem.h" 27 | 28 | class PlayListModel : public QAbstractListModel 29 | { 30 | Q_OBJECT 31 | Q_DISABLE_COPY(PlayListModel) 32 | public: 33 | explicit PlayListModel(QObject *parent = 0); 34 | 35 | QList items() const; 36 | 37 | virtual Qt::ItemFlags flags(const QModelIndex &index) const; 38 | int rowCount(const QModelIndex &parent = QModelIndex()) const; 39 | QVariant data(const QModelIndex &index, int role) const; 40 | virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); 41 | 42 | bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex()); 43 | bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex()); 44 | 45 | void updateLayout(); 46 | private: 47 | QList mItems; 48 | }; 49 | 50 | #endif // PLAYLISTMODEL_H 51 | -------------------------------------------------------------------------------- /playlist/common/common.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV Player Demo: this file is part of QtAV examples 3 | Copyright (C) 2014-2015 Wang Bin 4 | 5 | * This file is part of QtAV 6 | 7 | This program is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | ******************************************************************************/ 20 | 21 | #ifndef COMMON_H 22 | #define COMMON_H 23 | #include 24 | #include 25 | #include 26 | #include "common/qoptions.h" 27 | #include "common/Config.h" 28 | #include "common/ScreenSaver.h" 29 | 30 | QOptions COMMON_EXPORT get_common_options(); 31 | void COMMON_EXPORT do_common_options_before_qapp(const QOptions& options); 32 | /// help, log file, ffmpeg log level 33 | void COMMON_EXPORT do_common_options(const QOptions& options, const QString& appName = QString()); 34 | void COMMON_EXPORT load_qm(const QStringList& names, const QString &lang = QLatin1String("system")); 35 | // if appname ends with 'desktop', 'es', 'angle', software', 'sw', set by appname. otherwise set by command line option glopt, or Config file 36 | // TODO: move to do_common_options_before_qapp 37 | void COMMON_EXPORT set_opengl_backend(const QString& glopt = QString::fromLatin1("auto"), const QString& appname = QString()); 38 | 39 | QString COMMON_EXPORT appDataDir(); 40 | 41 | class COMMON_EXPORT AppEventFilter : public QObject 42 | { 43 | public: 44 | AppEventFilter(QObject *player = 0, QObject* parent = 0); 45 | QUrl url() const; 46 | virtual bool eventFilter(QObject *obj, QEvent *ev); 47 | private: 48 | QObject *m_player; 49 | }; 50 | 51 | #endif // COMMON_H 52 | -------------------------------------------------------------------------------- /ring.h: -------------------------------------------------------------------------------- 1 | /****************************************************************************** 2 | QtAV: Multimedia framework based on Qt and FFmpeg 3 | Copyright (C) 2012-2016 Wang Bin 4 | 5 | * This file is part of QtAV (from 2015) 6 | 7 | This library is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU Lesser General Public 9 | License as published by the Free Software Foundation; either 10 | version 2.1 of the License, or (at your option) any later version. 11 | 12 | This library is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | Lesser General Public License for more details. 16 | 17 | You should have received a copy of the GNU Lesser General Public 18 | License along with this library; if not, write to the Free Software 19 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 | ******************************************************************************/ 21 | 22 | #ifndef QTAV_RING_H 23 | #define QTAV_RING_H 24 | 25 | #include 26 | #include 27 | 28 | template 29 | class ring_api { 30 | public: 31 | ring_api() : m_0(0), m_1(0), m_s(0) {} 32 | void push_back(const T &t); 33 | void pop_front(); 34 | T &front() { return m_data[m_0]; } 35 | const T &front() const { return m_data[m_0]; } 36 | T &back() { return m_data[m_1]; } 37 | const T &back() const { return m_data[m_1]; } 38 | virtual size_t capacity() const = 0; 39 | size_t size() const { return m_s;} 40 | bool empty() const { return size() == 0;} 41 | // need at() []? 42 | const T &at(size_t i) const { assert(i < m_s); return m_data[index(m_0+i)];} 43 | const T &operator[](size_t i) const { return at(i);} 44 | T &operator[](size_t i) {assert(i < m_s); return m_data[index(m_0+i)];} 45 | protected: 46 | size_t index(size_t i) const { return i < capacity() ? i : i - capacity();} // i always [0,capacity()) 47 | size_t m_0, m_1; 48 | size_t m_s; 49 | C m_data; 50 | }; 51 | 52 | template 53 | class ring : public ring_api > { 54 | using ring_api >::m_data; // why need this? 55 | public: 56 | ring(size_t capacity) : ring_api >() { 57 | m_data.reserve(capacity); 58 | m_data.resize(capacity); 59 | } 60 | size_t capacity() const {return m_data.size();} 61 | }; 62 | template 63 | class static_ring : public ring_api { 64 | using ring_api::m_data; // why need this? 65 | public: 66 | static_ring() : ring_api() {} 67 | size_t capacity() const {return N;} 68 | }; 69 | 70 | template 71 | void ring_api::push_back(const T &t) { 72 | if (m_s == capacity()) { 73 | m_data[m_0] = t; 74 | m_0 = index(++m_0); 75 | m_1 = index(++m_1); 76 | } else if (empty()) { 77 | m_s = 1; 78 | m_0 = m_1 = 0; 79 | m_data[m_0] = t; 80 | } else { 81 | m_data[index(m_0 + m_s)] = t; 82 | ++m_1; 83 | ++m_s; 84 | } 85 | } 86 | 87 | template 88 | void ring_api::pop_front() { 89 | assert(!empty()); 90 | if (empty()) 91 | return; 92 | m_data[m_0] = T(); //erase the old data 93 | m_0 = index(++m_0); 94 | --m_s; 95 | } 96 | #endif // QTAV_RING_H 97 | -------------------------------------------------------------------------------- /theme.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | theme/dark/backward.svg 4 | theme/dark/capture.svg 5 | theme/dark/close.svg 6 | theme/dark/forward.svg 7 | theme/dark/fullscreen.svg 8 | theme/dark/help.svg 9 | theme/dark/info.svg 10 | theme/dark/menu.svg 11 | theme/dark/open.svg 12 | theme/dark/pause.svg 13 | theme/dark/play.svg 14 | theme/dark/sound.svg 15 | theme/dark/stop.svg 16 | theme/default/backward.svg 17 | theme/default/close.svg 18 | theme/default/forward.svg 19 | theme/default/fullscreen.svg 20 | theme/default/help.svg 21 | theme/default/info.svg 22 | theme/default/mute.svg 23 | theme/default/open.svg 24 | theme/default/pause.svg 25 | theme/default/play.svg 26 | theme/default/stop.svg 27 | theme/default/volume.svg 28 | theme/down_arrow-bw.png 29 | theme/fullscreen.png 30 | theme/media-pause-16.png 31 | theme/media-play-16.png 32 | theme/up_arrow-bw.png 33 | Xuno-Mpv.ico 34 | XunoPlayer-MPV_128x128.ico 35 | 36 | 37 | -------------------------------------------------------------------------------- /theme/dark/backward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /theme/dark/capture.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /theme/dark/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /theme/dark/forward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /theme/dark/fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /theme/dark/help.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | ? 12 | 13 | -------------------------------------------------------------------------------- /theme/dark/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | i 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/dark/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/dark/open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /theme/dark/pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /theme/dark/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /theme/dark/sound.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /theme/dark/stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /theme/default/backward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/default/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /theme/default/forward.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/default/fullscreen.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /theme/default/help.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 13 | ? 14 | 15 | -------------------------------------------------------------------------------- /theme/default/info.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 13 | i 14 | 15 | 16 | -------------------------------------------------------------------------------- /theme/default/mute.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /theme/default/open.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/default/pause.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /theme/default/play.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /theme/default/stop.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 8 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /theme/default/volume.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /theme/down_arrow-bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/theme/down_arrow-bw.png -------------------------------------------------------------------------------- /theme/fullscreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/theme/fullscreen.png -------------------------------------------------------------------------------- /theme/media-pause-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/theme/media-pause-16.png -------------------------------------------------------------------------------- /theme/media-play-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/theme/media-play-16.png -------------------------------------------------------------------------------- /theme/up_arrow-bw.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Xuno/XunoPlayer-MPV/f8e5ed1a90a08adead0d9dd65fd0a2fa672731bd/theme/up_arrow-bw.png -------------------------------------------------------------------------------- /version.h: -------------------------------------------------------------------------------- 1 | #ifndef XUNO_VERSION_H 2 | #define XUNO_VERSION_H 3 | 4 | #define XUNO_MPV_MAJOR VER_MAJ_STRING 5 | #define XUNO_MPV_MINOR VER_MIN_STRING 6 | #define XUNO_MPV_PATCH VER_PAT_STRING 7 | 8 | #ifdef WIN64 9 | #define MPV_PLATFORM "x64" 10 | #endif 11 | 12 | #ifdef ARCH 13 | #define MPV_PLATFORM "ARCH" 14 | #endif 15 | 16 | #ifdef __linux__ 17 | #define MPV_PLATFORM "Linux" 18 | #endif 19 | 20 | 21 | 22 | 23 | 24 | #ifdef MPV_PLATFORM 25 | //#define XUNO_MPV_VERSION_STR "v" 26 | #define XUNO_MPV_VERSION_STR "v" TOSTR(XUNO_MPV_MAJOR) "." TOSTR(XUNO_MPV_MINOR) "." TOSTR(XUNO_MPV_PATCH) " (" TOSTR(MPV_PLATFORM) ")" 27 | #else 28 | #define XUNO_MPV_VERSION_STR "v." TOSTR(XUNO_MPV_MAJOR) "." TOSTR(XUNO_MPV_MINOR) "." TOSTR(XUNO_MPV_PATCH) 29 | #endif 30 | 31 | #define XUNO_MPV_VERSION_STR_LONG XUNO_MPV_VERSION_STR " (" __DATE__ ", " __TIME__ ")" 32 | 33 | #endif // XUNO_VERSION_H 34 | --------------------------------------------------------------------------------