├── src ├── icon_windows.rc ├── images │ ├── icon.icns │ ├── icon.png │ ├── oscs │ │ ├── box.png │ │ ├── topbar.png │ │ ├── slimbox.png │ │ ├── bottombar.png │ │ ├── seekbarstylebar.png │ │ └── seekbarstylediamond.png │ ├── colorpicker.png │ └── icon_windows.ico ├── main.cpp ├── tabconfig.hpp ├── valueboxsetting.hpp ├── tabconfig.cpp ├── valueboxsetting.cpp ├── tabosc.hpp ├── unknownsettingstab.hpp ├── slidersetting.h ├── tabextensions.hpp ├── resources.qrc ├── tabwindow.hpp ├── comboboxsetting.hpp ├── tabmisc.hpp ├── setting.hpp ├── tabscreenshot.hpp ├── tabaudio.hpp ├── tabvideo.hpp ├── tabosd.hpp ├── comboboxsetting.cpp ├── slidersetting.cpp ├── mainwindow.hpp ├── tabsubtitle.hpp ├── mpvconfigurator.pro ├── unknownsettingstab.cpp ├── tabextensions.cpp ├── unknownsettingstab.ui ├── tabwindow.cpp ├── tabmisc.cpp ├── tabosc.cpp ├── setting.cpp ├── mainwindow.ui ├── tabextensions.ui ├── tabosd.cpp ├── tabosc.ui ├── tabscreenshot.cpp ├── man │ ├── osc.rst │ └── ao.rst ├── tabsubtitle.cpp ├── mainwindow.cpp ├── tabvideo.cpp ├── tabaudio.cpp ├── tabconfig.ui ├── tabwindow.ui └── tabmisc.ui ├── .gitignore ├── README.md └── LICENSE /src/icon_windows.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "./images/icon_windows.ico" -------------------------------------------------------------------------------- /src/images/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/icon.icns -------------------------------------------------------------------------------- /src/images/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/icon.png -------------------------------------------------------------------------------- /src/images/oscs/box.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/oscs/box.png -------------------------------------------------------------------------------- /src/images/colorpicker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/colorpicker.png -------------------------------------------------------------------------------- /src/images/oscs/topbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/oscs/topbar.png -------------------------------------------------------------------------------- /src/images/icon_windows.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/icon_windows.ico -------------------------------------------------------------------------------- /src/images/oscs/slimbox.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/oscs/slimbox.png -------------------------------------------------------------------------------- /src/images/oscs/bottombar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/oscs/bottombar.png -------------------------------------------------------------------------------- /src/images/oscs/seekbarstylebar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/oscs/seekbarstylebar.png -------------------------------------------------------------------------------- /src/images/oscs/seekbarstylediamond.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/HEAD/src/images/oscs/seekbarstylediamond.png -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.hpp" 2 | #include 3 | #include 4 | 5 | int main(int argc, char *argv[]) 6 | { 7 | QApplication a(argc, argv); 8 | MainWindow w; 9 | QCoreApplication::setOrganizationName("HaasnSoft"); 10 | QCoreApplication::setOrganizationDomain("mpvconfigurator"); 11 | QCoreApplication::setApplicationName("mpv Configurator"); 12 | w.show(); 13 | 14 | return a.exec(); 15 | } 16 | -------------------------------------------------------------------------------- /src/tabconfig.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABCONFIG_HPP 2 | #define TABCONFIG_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace Ui { 8 | class tabconfig; 9 | } 10 | 11 | class tabconfig : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit tabconfig(QWidget *parent = 0); 17 | QGraphicsScene* logoScene; 18 | ~tabconfig(); 19 | 20 | private: 21 | Ui::tabconfig *ui; 22 | }; 23 | 24 | #endif // TABCONFIG_HPP 25 | -------------------------------------------------------------------------------- /src/valueboxsetting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef VALUEBOXSETTING_HPP 2 | #define VALUEBOXSETTING_HPP 3 | #include 4 | #include "setting.hpp" 5 | 6 | class valueboxSetting : public setting { 7 | 8 | Q_OBJECT 9 | 10 | public: 11 | QLineEdit* valueBox; 12 | valueboxSetting(QLineEdit* aValueBox, QCheckBox* checkBox, QStringList* manuals); 13 | 14 | void setValueBox(QLineEdit* aValueBox); 15 | QLineEdit* getValueBox(); 16 | QString getValue(); 17 | ~valueboxSetting(); 18 | }; 19 | 20 | #endif // VALUEBOXSETTING_HPP 21 | -------------------------------------------------------------------------------- /src/tabconfig.cpp: -------------------------------------------------------------------------------- 1 | #include "tabconfig.hpp" 2 | #include "ui_tabconfig.h" 3 | 4 | tabconfig::tabconfig(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabconfig) 7 | { 8 | ui->setupUi(this); 9 | 10 | logoScene = new QGraphicsScene(); 11 | ui->graphicsView->setScene(logoScene); 12 | ui->graphicsView->setStyleSheet("background: transparent; border: 0px;"); 13 | logoScene->addPixmap(QPixmap(":/images/icon.png")); 14 | } 15 | 16 | tabconfig::~tabconfig() 17 | { 18 | delete logoScene; 19 | delete ui; 20 | } 21 | -------------------------------------------------------------------------------- /src/valueboxsetting.cpp: -------------------------------------------------------------------------------- 1 | #include "valueboxsetting.hpp" 2 | 3 | valueboxSetting::valueboxSetting(QLineEdit* aValueBox, QCheckBox* checkBox, QStringList* manuals) : setting(checkBox, manuals), valueBox{aValueBox} { 4 | type = "valuebox"; 5 | connect(settingCheckBox, SIGNAL(toggled(bool)), valueBox, SLOT(setEnabled(bool))); 6 | } 7 | 8 | void valueboxSetting::setValueBox(QLineEdit* aValueBox){ 9 | valueBox = aValueBox; 10 | } 11 | 12 | QLineEdit* valueboxSetting::getValueBox(){ 13 | return valueBox; 14 | } 15 | 16 | QString valueboxSetting::getValue(){ 17 | return valueBox->text(); 18 | } 19 | 20 | valueboxSetting::~valueboxSetting(){} 21 | -------------------------------------------------------------------------------- /src/tabosc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABOSC_HPP 2 | #define TABOSC_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace Ui { 8 | class tabosc; 9 | } 10 | 11 | class tabosc : public QWidget 12 | { 13 | Q_OBJECT 14 | 15 | public: 16 | explicit tabosc(QWidget *parent = 0); 17 | QGraphicsScene *box_osc_scene, *bottombar_osc_scene, *topbar_osc_scene, *slimbox_osc_scene, 18 | *seekbar_osc_bar_scene, *seekbar_osc_diamond_scene; 19 | void readFromConf(QString conf); 20 | ~tabosc(); 21 | 22 | public slots: 23 | void parseToConf(QStringList*); 24 | 25 | private: 26 | Ui::tabosc *ui; 27 | }; 28 | 29 | #endif // TABOSC_HPP 30 | -------------------------------------------------------------------------------- /src/unknownsettingstab.hpp: -------------------------------------------------------------------------------- 1 | #ifndef UNKNOWNSETTINGSTAB_HPP 2 | #define UNKNOWNSETTINGSTAB_HPP 3 | 4 | #include 5 | 6 | namespace Ui { 7 | class unknownsettingstab; 8 | } 9 | 10 | class unknownsettingstab : public QWidget 11 | { 12 | Q_OBJECT 13 | 14 | public: 15 | explicit unknownsettingstab(QWidget *parent = 0); 16 | void addSetting(QString withSetting); 17 | void parseToConf(QStringList* conf); 18 | void applyFromReadConf(QMap* conf); 19 | ~unknownsettingstab(); 20 | 21 | private slots: 22 | void addSetting(); 23 | void removeSetting(); 24 | 25 | private: 26 | Ui::unknownsettingstab *ui; 27 | }; 28 | 29 | #endif // UNKNOWNSETTINGSTAB_HPP 30 | -------------------------------------------------------------------------------- /src/slidersetting.h: -------------------------------------------------------------------------------- 1 | #ifndef SLIDERSETTING_H 2 | #define SLIDERSETTING_H 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | class sliderSetting : public setting{ 9 | 10 | Q_OBJECT 11 | 12 | public: 13 | QSlider* slider; 14 | int divideBy; 15 | QLabel* shownValue; 16 | sliderSetting(QSlider* aSlider, QLabel* valuer, int divideItBy, QCheckBox* checkBox, QStringList* manuals); 17 | 18 | void setSlider(QSlider* aSlider); 19 | int getDivideBy(); 20 | QSlider* getSlider(); 21 | QString getValue(); 22 | ~sliderSetting(); 23 | 24 | public slots: 25 | void updateShownValue(int); 26 | }; 27 | 28 | #endif // SLIDERSETTING_H 29 | -------------------------------------------------------------------------------- /src/tabextensions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABEXTENSIONS_HPP 2 | #define TABEXTENSIONS_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | namespace Ui { 9 | class tabExtensions; 10 | } 11 | 12 | class tabExtensions : public QWidget 13 | { 14 | Q_OBJECT 15 | 16 | public: 17 | explicit tabExtensions(QWidget *parent = 0); 18 | QMap* settingMap; 19 | 20 | void parseToConf(QStringList* conf); 21 | void readExtensions(QString name, QStringList settings); 22 | ~tabExtensions(); 23 | 24 | private slots: 25 | void addNewExtensionTab(); 26 | void removeExtensionTab(); 27 | 28 | private: 29 | Ui::tabExtensions *ui; 30 | }; 31 | 32 | #endif // TABEXTENSIONS_HPP 33 | -------------------------------------------------------------------------------- /src/resources.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | images/icon.icns 4 | images/icon.png 5 | images/colorpicker.png 6 | images/oscs/bottombar.png 7 | images/oscs/box.png 8 | images/oscs/seekbarstylebar.png 9 | images/oscs/seekbarstylediamond.png 10 | images/oscs/slimbox.png 11 | images/oscs/topbar.png 12 | man/af.rst 13 | man/ao.rst 14 | man/mpv.rst 15 | man/options.rst 16 | man/osc.rst 17 | man/vf.rst 18 | man/vo.rst 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/tabwindow.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABWINDOW_HPP 2 | #define TABWINDOW_HPP 3 | 4 | #include 5 | #include "setting.hpp" 6 | #include "comboboxsetting.hpp" 7 | #include "valueboxsetting.hpp" 8 | 9 | namespace Ui { 10 | class tabWindow; 11 | } 12 | 13 | class tabWindow : public QWidget 14 | { 15 | Q_OBJECT 16 | 17 | public: 18 | explicit tabWindow(QWidget *parent = 0); 19 | std::vector* windowSettings; 20 | QStringList* manualPages; 21 | 22 | void addWindowSetting(QCheckBox* box); 23 | void addWindowSetting(QComboBox* comboBox, QCheckBox* box); 24 | void addWindowSetting(QLineEdit* valueBox, QCheckBox* box); 25 | void applyFromReadConf(QMap* conf); 26 | ~tabWindow(); 27 | 28 | public slots: 29 | void parseToConf(QStringList* conf); 30 | 31 | private: 32 | Ui::tabWindow *ui; 33 | }; 34 | 35 | #endif // TABWINDOW_HPP 36 | -------------------------------------------------------------------------------- /src/comboboxsetting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef COMBOBOXSETTING_HPP 2 | #define COMBOBOXSETTING_HPP 3 | #include 4 | #include 5 | #include 6 | 7 | class comboboxSetting : public setting { 8 | 9 | Q_OBJECT 10 | 11 | public: 12 | QComboBox* combobox; 13 | 14 | comboboxSetting(QComboBox* box, QCheckBox* checkBox, QStringList* manuals); 15 | void setComboBox(QComboBox* box); 16 | QComboBox* getComboBox(); 17 | QString getValue(); 18 | ~comboboxSetting(); 19 | }; 20 | 21 | class fontBoxSetting : public setting { 22 | 23 | Q_OBJECT 24 | 25 | public: 26 | QFontComboBox* combobox; 27 | 28 | fontBoxSetting(QFontComboBox* box, QCheckBox* checkBox, QStringList* manuals); 29 | void setComboBox(QFontComboBox* box); 30 | QFontComboBox* getComboBox(); 31 | QString getValue(); 32 | ~fontBoxSetting(); 33 | }; 34 | 35 | #endif // COMBOBOXSETTING_HPP 36 | -------------------------------------------------------------------------------- /src/tabmisc.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABMISC_HPP 2 | #define TABMISC_HPP 3 | 4 | #include 5 | #include 6 | #include "setting.hpp" 7 | #include "comboboxsetting.hpp" 8 | #include "valueboxsetting.hpp" 9 | 10 | namespace Ui { 11 | class tabMisc; 12 | } 13 | 14 | class tabMisc : public QWidget 15 | { 16 | Q_OBJECT 17 | 18 | public: 19 | explicit tabMisc(QWidget *parent = 0); 20 | 21 | std::vector* miscSettings; 22 | QStringList* manualPages; 23 | 24 | void addMiscSetting(QCheckBox* box); 25 | void addMiscSetting(QComboBox* comboBox, QCheckBox* box); 26 | void addMiscSetting(QLineEdit* valueBox, QCheckBox* box); 27 | void parseToConf(QStringList* conf); 28 | void applyFromReadConf(QMap* conf); 29 | ~tabMisc(); 30 | 31 | private slots: 32 | void openCDROMFolder(); 33 | 34 | private: 35 | Ui::tabMisc *ui; 36 | }; 37 | 38 | #endif // TABMISC_HPP 39 | -------------------------------------------------------------------------------- /src/setting.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SETTING_HPP 2 | #define SETTING_HPP 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class setting : public QObject { 11 | 12 | Q_OBJECT 13 | 14 | public: 15 | QString name, description, type, value; 16 | bool settingStatus; 17 | QCheckBox* settingCheckBox; 18 | QStringList* manual; 19 | 20 | setting(QCheckBox* checkbox, QStringList* manuals); 21 | void setName(QString name); 22 | void setDescription(QString descriptor); 23 | void setCheckBox(QCheckBox* box); 24 | QString getName(); 25 | QString getDescription(); 26 | bool getSettingStatus(); 27 | QCheckBox* getCheckBox(); 28 | QString parseSetting(); 29 | QString getType(); 30 | virtual QString getValue(); 31 | ~setting(); 32 | 33 | public slots: 34 | void toggleSetting(bool); 35 | }; 36 | 37 | #endif // SETTING_HPP 38 | -------------------------------------------------------------------------------- /src/tabscreenshot.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABSCREENSHOT_HPP 2 | #define TABSCREENSHOT_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include "setting.hpp" 8 | #include "comboboxsetting.hpp" 9 | #include "valueboxsetting.hpp" 10 | 11 | namespace Ui { 12 | class tabScreenshot; 13 | } 14 | 15 | class tabScreenshot : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit tabScreenshot(QWidget *parent = 0); 21 | 22 | std::vector* screenshotSettings; 23 | QStringList* manualPages; 24 | 25 | void addScreenshotSetting(QCheckBox* box); 26 | void addScreenshotSetting(QComboBox* comboBox, QCheckBox* box); 27 | void addScreenshotSetting(QLineEdit* valueBox, QCheckBox* box); 28 | QString convertTemplateToFormat(); 29 | void applyFromReadConf(QMap* conf); 30 | ~tabScreenshot(); 31 | 32 | private slots: 33 | void enablePNGandJPEGWidgets(QString); 34 | void enableDisableCustomTemplate(QString); 35 | void browseForScreenshotFolder(); 36 | 37 | public slots: 38 | void parseToConf(QStringList*); 39 | 40 | private: 41 | Ui::tabScreenshot *ui; 42 | }; 43 | 44 | #endif // TABSCREENSHOT_HPP 45 | -------------------------------------------------------------------------------- /src/tabaudio.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABAUDIO_HPP 2 | #define TABAUDIO_HPP 3 | 4 | #include 5 | #include 6 | #include "setting.hpp" 7 | #include "comboboxsetting.hpp" 8 | #include "valueboxsetting.hpp" 9 | 10 | 11 | namespace Ui { 12 | class tabaudio; 13 | } 14 | 15 | class tabaudio : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit tabaudio(QWidget *parent = 0); 21 | std::vector* aoSettings; 22 | std::vector* audioSettings; 23 | QStringList* manualPages; 24 | QString ao = "ao="; 25 | void addAOSetting(QCheckBox* box); 26 | void addAOSetting(QComboBox* comboBox, QCheckBox* box); 27 | void addAOSetting(QLineEdit* valueBox, QCheckBox* box); 28 | void addAudioSetting(QCheckBox* box); 29 | void addAudioSetting(QComboBox* comboBox, QCheckBox* box); 30 | void addAudioSetting(QLineEdit* valueBox, QCheckBox* box); 31 | void applyFromReadConf(QMap* settingMap); 32 | void readAOLine(QString readAO); 33 | ~tabaudio(); 34 | 35 | public slots: 36 | void parseAOSettings(); 37 | void parseAOSettings(QString); 38 | void parseToConf(QStringList*); 39 | void changeDriver(bool); 40 | 41 | private: 42 | Ui::tabaudio *ui; 43 | }; 44 | 45 | #endif // TABAUDIO_HPP 46 | -------------------------------------------------------------------------------- /src/tabvideo.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABVIDEO_HPP 2 | #define TABVIDEO_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include "setting.hpp" 8 | #include "comboboxsetting.hpp" 9 | #include "valueboxsetting.hpp" 10 | 11 | namespace Ui { 12 | class tabVideo; 13 | } 14 | 15 | class tabVideo : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit tabVideo(QWidget *parent = 0); 21 | std::vector* voSettings; 22 | std::vector* videoSettings; 23 | QStringList* manualPages; 24 | QString vo = "vo="; 25 | void addVOSetting(QCheckBox* box); 26 | void addVOSetting(QComboBox* comboBox, QCheckBox* box); 27 | void addVOSetting(QLineEdit* valueBox, QCheckBox* box); 28 | void addVideoSetting(QCheckBox* box); 29 | void addVideoSetting(QComboBox* comboBox, QCheckBox* box); 30 | void addVideoSetting(QLineEdit* valueBox, QCheckBox* box); 31 | void parseToConf(QStringList* conf); 32 | void applyFromReadConf(QMap* conf); 33 | void readVOLine(QString readVO); 34 | ~tabVideo(); 35 | 36 | public slots: 37 | void parseVOSettings(); 38 | void parseVOSettings(QString); 39 | void changeDriver(bool); 40 | void browseForShader(); 41 | void browseForICC(); 42 | 43 | private: 44 | Ui::tabVideo *ui; 45 | }; 46 | 47 | #endif // TABVIDEO_HPP 48 | -------------------------------------------------------------------------------- /src/tabosd.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABOSD_HPP 2 | #define TABOSD_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | namespace Ui { 12 | class tabosd; 13 | } 14 | 15 | class tabosd : public QWidget 16 | { 17 | Q_OBJECT 18 | 19 | public: 20 | explicit tabosd(QWidget *parent = 0); 21 | 22 | std::vector* osdSettings; 23 | QColor fontColor, borderColor, shadowColor, backColor; 24 | QColorDialog* colorPickerFontColor, *colorPickerBorderColor, 25 | *colorPickerShadowColor, *colorPickerBackColor; 26 | QStringList* manualPages; 27 | 28 | void addOSDSetting(QCheckBox* box); 29 | void addOSDSetting(QComboBox* comboBox, QCheckBox* box); 30 | void addOSDSetting(QLineEdit* valueBox, QCheckBox* box); 31 | void addOSDSetting(QSlider* slider, QLabel* valueCounter, int divideBy, QCheckBox* box); 32 | void applyFromReadConf(QMap* conf); 33 | ~tabosd(); 34 | 35 | public slots: 36 | void parseToConf(QStringList*); 37 | 38 | private slots: 39 | void setOSDFontColor(QColor); 40 | void setOSDBorderColor(QColor); 41 | void setOSDShadowColor(QColor); 42 | void setOSDBackColor(QColor); 43 | 44 | private: 45 | Ui::tabosd *ui; 46 | }; 47 | 48 | #endif // TABOSD_HPP 49 | -------------------------------------------------------------------------------- /src/comboboxsetting.cpp: -------------------------------------------------------------------------------- 1 | #include "comboboxsetting.hpp" 2 | 3 | comboboxSetting::comboboxSetting(QComboBox* box, QCheckBox* checkBox, QStringList* manuals) : combobox{box}, setting(checkBox, manuals) { 4 | type = "combobox"; 5 | connect(settingCheckBox, SIGNAL(toggled(bool)), combobox, SLOT(setEnabled(bool))); 6 | } 7 | 8 | void comboboxSetting::setComboBox(QComboBox *box){ 9 | combobox = box; 10 | } 11 | 12 | QComboBox* comboboxSetting::getComboBox(){ 13 | return combobox; 14 | } 15 | 16 | QString comboboxSetting::getValue(){ 17 | return combobox->currentText(); 18 | } 19 | 20 | comboboxSetting::~comboboxSetting() {} 21 | 22 | // ---------------------------------- 23 | 24 | fontBoxSetting::fontBoxSetting(QFontComboBox* box, QCheckBox* checkBox, QStringList* manuals) : combobox{box}, setting(checkBox, manuals) { 25 | type = "combobox"; 26 | connect(settingCheckBox, SIGNAL(toggled(bool)), combobox, SLOT(setEnabled(bool))); 27 | } 28 | 29 | void fontBoxSetting::setComboBox(QFontComboBox *box){ 30 | combobox = box; 31 | } 32 | 33 | QFontComboBox* fontBoxSetting::getComboBox(){ 34 | return combobox; 35 | } 36 | 37 | QString fontBoxSetting::getValue(){ 38 | return QString('"').append(combobox->currentText()).append('"'); // For writing config. Needs to be encased since many include whitespace. 39 | } 40 | 41 | fontBoxSetting::~fontBoxSetting() {} 42 | 43 | -------------------------------------------------------------------------------- /src/slidersetting.cpp: -------------------------------------------------------------------------------- 1 | #include "slidersetting.h" 2 | 3 | sliderSetting::sliderSetting(QSlider* aSlider, QLabel* valuer, int divideItBy, QCheckBox* checkBox, QStringList* manuals) : slider{aSlider}, shownValue{valuer}, divideBy{divideItBy}, setting(checkBox, manuals) { 4 | connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(updateShownValue(int))); 5 | connect(settingCheckBox, SIGNAL(toggled(bool)), slider, SLOT(setEnabled(bool))); 6 | type = "slider"; 7 | } 8 | 9 | void sliderSetting::setSlider(QSlider *box){ 10 | slider = box; 11 | } 12 | 13 | QSlider* sliderSetting::getSlider(){ 14 | return slider; 15 | } 16 | 17 | int sliderSetting::getDivideBy(){ 18 | return divideBy; 19 | } 20 | 21 | 22 | // This way in case the slider does decimal increments, which slider->value() does not understand. 23 | // Some of the settings have -0.7 for example, which means a custom slider is necessary, or just divide it to achieve the same thing. 24 | void sliderSetting::updateShownValue(int i){ 25 | if(i != 0){ 26 | float converted = (float(i))/float(divideBy); 27 | shownValue->setText(QString::number(converted)); // Humans can unfortunately not divide by zero yet. 28 | } 29 | else 30 | shownValue->setText(QString::number(i)); 31 | } 32 | 33 | // Since a slider can be in decimals, the label next to the slider is a more accurate value than the QSlider object's value. 34 | QString sliderSetting::getValue(){ 35 | return shownValue->text(); 36 | } 37 | 38 | sliderSetting::~sliderSetting(){} 39 | -------------------------------------------------------------------------------- /src/mainwindow.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MAINWINDOW_HPP 2 | #define MAINWINDOW_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include "tabconfig.hpp" 8 | #include "tabvideo.hpp" 9 | #include "tabaudio.hpp" 10 | #include "tabsubtitle.hpp" 11 | #include "tabosc.hpp" 12 | #include "tabosd.hpp" 13 | #include "tabscreenshot.hpp" 14 | #include "tabwindow.hpp" 15 | #include "tabmisc.hpp" 16 | #include "tabextensions.hpp" 17 | #include "unknownsettingstab.hpp" 18 | #include 19 | 20 | namespace Ui { 21 | class MainWindow; 22 | } 23 | 24 | class MainWindow : public QMainWindow 25 | { 26 | Q_OBJECT 27 | 28 | public: 29 | explicit MainWindow(QWidget *parent = 0); 30 | 31 | // Needs to be initialized with variables to be able to call them later for config parsing. 32 | tabconfig* tabConfig; 33 | tabVideo* tabvideo; 34 | tabaudio* tabAudio; 35 | tabsubtitle* tabSubtitle; 36 | tabosc* tabOSC; 37 | tabosd* tabOSD; 38 | tabScreenshot* tabscreenshot; 39 | tabWindow* tabwindow; 40 | tabMisc* tabmisc; 41 | tabExtensions* tabextensions; 42 | unknownsettingstab* tabunknown; 43 | QFile* savedConf; 44 | QSettings* windowSettings; 45 | 46 | QString parseSetting(); 47 | QString parseComboboxSetting(QString* settingName, QObject* objectToChange); 48 | ~MainWindow(); 49 | 50 | public slots: 51 | void parseFullConf(); 52 | void readFullConf(); 53 | void deleteAllSettings(bool); 54 | void saveAs(); 55 | void messageClose(); 56 | 57 | private: 58 | Ui::MainWindow *ui; 59 | }; 60 | 61 | #endif // MAINWINDOW_HPP 62 | -------------------------------------------------------------------------------- /src/tabsubtitle.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TABSUBTITLE_HPP 2 | #define TABSUBTITLE_HPP 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "setting.hpp" 10 | #include "comboboxsetting.hpp" 11 | #include "valueboxsetting.hpp" 12 | #include "slidersetting.h" 13 | 14 | namespace Ui { 15 | class tabsubtitle; 16 | } 17 | 18 | class tabsubtitle : public QWidget 19 | { 20 | Q_OBJECT 21 | 22 | public: 23 | explicit tabsubtitle(QWidget *parent = 0); 24 | QGraphicsSimpleTextItem* testSubtitle; 25 | QColor fontColor, borderColor, shadowColor; 26 | QGraphicsDropShadowEffect* testShadow; 27 | QColorDialog* colorPickerFontColor, *colorPickerBorderColor, *colorPickerShadowColor; 28 | QGraphicsScene* subtitleScene; 29 | std::vector* subtitleSettings; 30 | QStringList* manualPages; 31 | 32 | void addSubtitleSetting(QCheckBox* box); 33 | void addSubtitleSetting(QComboBox* comboBox, QCheckBox* box); 34 | void addSubtitleSetting(QLineEdit* valueBox, QCheckBox* box); 35 | void addSubtitleSetting(QSlider* slider, QLabel* valueCounter, int divideBy, QCheckBox* box); 36 | void applyFromReadConf(QMap* conf); 37 | ~tabsubtitle(); 38 | 39 | private slots: 40 | void setSubFontColor(QColor); 41 | void setSubBorderColor(QColor); 42 | void setSubShadowColor(QColor); 43 | void updateTestText(int); 44 | 45 | public slots: 46 | void parseToConf(QStringList*); 47 | 48 | private: 49 | Ui::tabsubtitle *ui; 50 | }; 51 | 52 | #endif // TABSUBTITLE_HPP 53 | -------------------------------------------------------------------------------- /src/mpvconfigurator.pro: -------------------------------------------------------------------------------- 1 | QT += core gui 2 | 3 | greaterThan(QT_MAJOR_VERSION, 4): QT += widgets 4 | 5 | TARGET = mpvconfigurator 6 | TEMPLATE = app 7 | 8 | 9 | SOURCES += main.cpp\ 10 | mainwindow.cpp \ 11 | tabvideo.cpp \ 12 | tabaudio.cpp \ 13 | tabsubtitle.cpp \ 14 | tabscreenshot.cpp \ 15 | tabosc.cpp \ 16 | setting.cpp \ 17 | valueboxsetting.cpp \ 18 | comboboxsetting.cpp \ 19 | slidersetting.cpp \ 20 | tabosd.cpp \ 21 | tabwindow.cpp \ 22 | tabmisc.cpp \ 23 | tabextensions.cpp \ 24 | unknownsettingstab.cpp \ 25 | tabconfig.cpp 26 | 27 | HEADERS += mainwindow.hpp \ 28 | tabvideo.hpp \ 29 | tabaudio.hpp \ 30 | tabsubtitle.hpp \ 31 | tabscreenshot.hpp \ 32 | tabosc.hpp \ 33 | setting.hpp \ 34 | valueboxsetting.hpp \ 35 | comboboxsetting.hpp \ 36 | slidersetting.h \ 37 | tabosd.hpp \ 38 | tabwindow.hpp \ 39 | tabmisc.hpp \ 40 | tabextensions.hpp \ 41 | unknownsettingstab.hpp \ 42 | tabconfig.hpp 43 | 44 | FORMS += mainwindow.ui \ 45 | tabvideo.ui \ 46 | tabaudio.ui \ 47 | tabsubtitle.ui \ 48 | tabscreenshot.ui \ 49 | tabosc.ui \ 50 | tabosd.ui \ 51 | tabwindow.ui \ 52 | tabmisc.ui \ 53 | tabextensions.ui \ 54 | unknownsettingstab.ui \ 55 | tabconfig.ui \ 56 | tempfix.ui 57 | 58 | QMAKE_CXXFLAGS += -std=c++11 59 | 60 | # OS X specific compilation requirements since Apple hates C++. 61 | macx{ 62 | QMAKE_CXXFLAGS += -std=c++0x -stdlib=libc++ 63 | QMAKE_LFLAGS += -lc++ 64 | } 65 | 66 | RESOURCES = resources.qrc 67 | 68 | RC_FILE = icon_windows.rc # Windows Icon 69 | ICON = images/icon.icns # OS X Icon 70 | -------------------------------------------------------------------------------- /src/unknownsettingstab.cpp: -------------------------------------------------------------------------------- 1 | #include "unknownsettingstab.hpp" 2 | #include "ui_unknownsettingstab.h" 3 | 4 | unknownsettingstab::unknownsettingstab(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::unknownsettingstab) 7 | { 8 | ui->setupUi(this); 9 | connect(ui->button_add_setting, SIGNAL(clicked()), this, SLOT(addSetting())); 10 | connect(ui->button_remove_setting, SIGNAL(clicked()), this, SLOT(removeSetting())); 11 | connect(ui->listWidget, SIGNAL(doubleClicked(QModelIndex)), ui->listWidget, SLOT(edit(QModelIndex))); 12 | 13 | } 14 | 15 | // adds a setting to the list. 16 | void unknownsettingstab::addSetting(){ 17 | QListWidgetItem* item = new QListWidgetItem("Custom Setting"); 18 | item->setFlags(item->flags() | Qt::ItemIsEditable); // Makes it possible to doubleclick to edit. 19 | ui->listWidget->addItem(item); 20 | } 21 | 22 | // Adds an already read setting. 23 | void unknownsettingstab::addSetting(QString withSetting){ 24 | QListWidgetItem* item = new QListWidgetItem(withSetting); 25 | item->setFlags(item->flags() | Qt::ItemIsEditable); 26 | ui->listWidget->addItem(item); 27 | } 28 | 29 | // Removes it. 30 | void unknownsettingstab::removeSetting(){ 31 | delete ui->listWidget->currentItem(); 32 | } 33 | 34 | void unknownsettingstab::parseToConf(QStringList* conf){ 35 | conf->append("\n# Unknown and custom settings"); 36 | for(int i = 0; i < ui->listWidget->count(); i++){ 37 | conf->append(ui->listWidget->item(i)->text()); 38 | } 39 | } 40 | 41 | void unknownsettingstab::applyFromReadConf(QMap* conf){ 42 | for(auto & readSetting : conf->keys()) { 43 | addSetting(readSetting.append(conf->value(readSetting))); 44 | conf->remove(readSetting); 45 | } 46 | } 47 | 48 | unknownsettingstab::~unknownsettingstab() 49 | { 50 | delete ui; 51 | } 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![http://mpv.io/](https://raw.githubusercontent.com/haasnhoff/mpvconfigurator/master/src/images/icon.png) 2 | 3 | ## mpv Configurator 4 | 5 | -------------- 6 | 7 | 8 | * [Overview](#overview) 9 | * [Downloads](#downloads) 10 | * [FAQ:](#faq) 11 | * [Bug reports](#bug-reports) 12 | * [License](#license) 13 | 14 | ## Overview 15 | 16 | **mpv Configurator** is a simple GUI that creates mpv.conf files that the media player mpv can use. 17 | 18 | Currently, mpv Configurator is in beta. This means it's not very optimized and might screw up on different operating systems. 19 | 20 | ## Downloads 21 | 22 | Pre-compiled binaries for mpv Configurator can be found in the [releases section](https://github.com/haasnhoff/mpvconfigurator/releases) 23 | 24 | Currently only betas are available. The configurator will be slated for 1.0 release when it has been properly tested, updating manuals feature and tooltips are fixed. 25 | 26 | **Note for GNU/Linux users:** 27 | 28 | While the GNU/Linux version of mpv Configurator worked out of the box on a Ubuntu 14.04 live CD without modifications or required downloads, GNU/Linux has very special deployment methods thus it might not work OOB in all distributions. If it gives off a segfault or require dependencies, you'll need to download the required libraries, whatever they might be. Try ldd and see what is missing. 29 | 30 | I might statically build the GNU/Linux binary later on for easier deployment, but if you keep having problems with it, please download Qt5 and compile it yourself. I am painfully aware of how stupid this is, but deploying shared library Qt applications on GNU/Linux are a pain in the ass, sorry. 31 | 32 | ## FAQ: 33 | 34 | **Are you affiliated with the mpv guys?** 35 | 36 | No. 37 | 38 | **Some tooltips aren't working as inteded. Comboboxes should have tooltips.** 39 | 40 | This is known. 41 | 42 | **Your code is absolutely horrible, please commit suicide.** 43 | 44 | This is my second "major" C++ project, please bear with me. 45 | 46 | **Where is the documentation?** 47 | 48 | Under construction. 49 | 50 | ## Bug reports 51 | 52 | Please use the issue-tracker provided by GitHub to send me bug 53 | reports or feature requests. 54 | 55 | ## License 56 | 57 | [GPLv2](https://github.com/haasnhoff/mpvconfigurator/blob/master/LICENSE) -------------------------------------------------------------------------------- /src/tabextensions.cpp: -------------------------------------------------------------------------------- 1 | #include "tabextensions.hpp" 2 | #include "ui_tabextensions.h" 3 | 4 | tabExtensions::tabExtensions(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabExtensions) 7 | { 8 | ui->setupUi(this); 9 | 10 | settingMap = new QMap; 11 | 12 | connect(ui->button_add_extension, SIGNAL(clicked()), this, SLOT(addNewExtensionTab())); 13 | connect(ui->button_remove_current, SIGNAL(clicked()), this, SLOT(removeExtensionTab())); 14 | } 15 | 16 | // Adds a new extension and creates a new tab for it. 17 | void tabExtensions::addNewExtensionTab(){ 18 | if(ui->valuebox_add_new_extension->text().startsWith(".")){ 19 | QWidget* newTab = new QWidget(); 20 | QGridLayout* grid = new QGridLayout(); 21 | newTab->setLayout(grid); 22 | QLabel* nameLabel = new QLabel("Name:", newTab); 23 | grid->addWidget(nameLabel, 0, 0); 24 | QLabel* actualName = new QLabel(ui->valuebox_add_new_extension->text(), newTab); 25 | grid->addWidget(actualName, 0, 1); 26 | QPlainTextEdit* textEditor = new QPlainTextEdit(newTab); 27 | grid->addWidget(textEditor, 1, 0, 1, 0); 28 | ui->tabWidget->addTab(newTab, ui->valuebox_add_new_extension->text()); 29 | settingMap->insert(actualName->text(), textEditor); 30 | ui->valuebox_add_new_extension->clear(); 31 | } 32 | else{ 33 | QMessageBox error; 34 | error.setText("ERROR: The extension needs to start with a dot."); 35 | error.exec(); 36 | } 37 | } 38 | 39 | // Reads the extensions and inserts tab and text. 40 | void tabExtensions::readExtensions(QString name, QStringList settings){ 41 | QWidget* newTab = new QWidget(); 42 | QPlainTextEdit* textEditor = new QPlainTextEdit(newTab); 43 | textEditor->setGeometry(80,90,500,260); 44 | textEditor->appendPlainText(settings.join("\n")); 45 | QLabel* nameLabel = new QLabel("Name:", newTab); 46 | nameLabel->setGeometry(80,30,51,16); 47 | QLabel* actualName = new QLabel(name, newTab); 48 | actualName->setGeometry(140,30,80,16); 49 | ui->tabWidget->addTab(newTab, name); 50 | settingMap->insert(actualName->text(), textEditor); 51 | ui->valuebox_add_new_extension->clear(); 52 | 53 | } 54 | 55 | // Removes current visible tab from existence. 56 | void tabExtensions::removeExtensionTab(){ 57 | if(ui->tabWidget->currentIndex() > 0){ 58 | QWidget* tabInQuestion = ui->tabWidget->currentWidget(); 59 | settingMap->remove(ui->tabWidget->tabText(ui->tabWidget->currentIndex())); 60 | ui->tabWidget->removeTab(ui->tabWidget->currentIndex()); 61 | delete tabInQuestion; 62 | } 63 | else{ 64 | ui->tabWidget->removeTab(ui->tabWidget->currentIndex()); 65 | } 66 | } 67 | 68 | void tabExtensions::parseToConf(QStringList* conf){ 69 | conf->append("\n# Extensions - Do not add custom settings that are not extension related below this line."); 70 | if(!settingMap->isEmpty()){ 71 | for(auto & it : settingMap->keys()) { 72 | conf->append(QString("[extension").append(it).append("]\n").append(settingMap->value(it)->toPlainText()).append("\n")); 73 | } 74 | } 75 | } 76 | 77 | tabExtensions::~tabExtensions() 78 | { 79 | delete settingMap; 80 | delete ui; 81 | } 82 | -------------------------------------------------------------------------------- /src/unknownsettingstab.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | unknownsettingstab 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 1000 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 160 19 | 20 | 21 | 160 22 | 23 | 24 | 25 | 26 | Qt::Horizontal 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 50 37 | 16777215 38 | 39 | 40 | 41 | + 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 50 | 16777215 51 | 52 | 53 | 54 | - 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | Qt::Vertical 64 | 65 | 66 | 67 | 20 68 | 40 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | Unknown or custom settings: 77 | 78 | 79 | 80 | 81 | 82 | 83 | Qt::Horizontal 84 | 85 | 86 | 87 | 40 88 | 20 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | Qt::Horizontal 97 | 98 | 99 | 100 | 40 101 | 20 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /src/tabwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "tabwindow.hpp" 2 | #include "ui_tabwindow.h" 3 | 4 | tabWindow::tabWindow(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabWindow) 7 | { 8 | ui->setupUi(this); 9 | 10 | windowSettings = new std::vector(); 11 | manualPages = new QStringList(); 12 | manualPages->append(":/man/options.rst"); 13 | 14 | addWindowSetting(ui->comboBox_screen_default, ui->box_screen_default); 15 | addWindowSetting(ui->box_fullscreen); 16 | addWindowSetting(ui->comboBox_keep_open, ui->box_keep_open); 17 | addWindowSetting(ui->comboBox_force_window, ui->box_force_window); 18 | addWindowSetting(ui->box_ontop); 19 | addWindowSetting(ui->box_no_border); 20 | addWindowSetting(ui->box_on_all_workspaces); 21 | addWindowSetting(ui->valuebox_autofit, ui->box_autofit); 22 | addWindowSetting(ui->valuebox_autofit_larger, ui->box_autofit_larger); 23 | addWindowSetting(ui->valuebox_autofit_smaller, ui->box_autofit_smaller); 24 | addWindowSetting(ui->comboBox_cursor_autohide, ui->box_cursor_autohide); 25 | addWindowSetting(ui->box_cursor_autohide_fs_only); 26 | addWindowSetting(ui->box_no_fixed_vo); 27 | addWindowSetting(ui->box_no_keepaspect); 28 | addWindowSetting(ui->box_no_keepaspect_window); 29 | addWindowSetting(ui->valuebox_monitoraspect, ui->box_monitoraspect); 30 | addWindowSetting(ui->box_no_stop_screensaver); 31 | addWindowSetting(ui->box_no_window_dragging); 32 | addWindowSetting(ui->valuebox_x11_name, ui->box_x11_name); 33 | addWindowSetting(ui->comboBox_x11_netwm, ui->box_x11_netwm); 34 | 35 | } 36 | 37 | void tabWindow::addWindowSetting(QCheckBox* box) { 38 | windowSettings->push_back(new setting(box, manualPages)); 39 | } 40 | 41 | void tabWindow::addWindowSetting(QComboBox* comboBox, QCheckBox* box) { 42 | windowSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 43 | } 44 | 45 | void tabWindow::addWindowSetting(QLineEdit* valueBox, QCheckBox* box) { 46 | windowSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 47 | } 48 | 49 | void tabWindow::parseToConf(QStringList* conf){ 50 | conf->append("\n# Window settings"); 51 | for(auto & it : *windowSettings) { 52 | if(it->getSettingStatus()){ 53 | if(it->getType().compare("checkbox") == 0) 54 | conf->append(it->getName()); 55 | else 56 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 57 | } 58 | } 59 | } 60 | 61 | void tabWindow::applyFromReadConf(QMap* conf){ 62 | for(auto & readSetting : conf->keys()) { 63 | for(auto & it : *windowSettings){ 64 | if(readSetting.compare(it->getName()) == 0){ 65 | it->getCheckBox()->setChecked(true); 66 | if(it->getType().compare("combobox") == 0){ 67 | comboboxSetting* tempBox = (comboboxSetting*)it; 68 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 69 | } 70 | else if(it->getType().compare("valuebox") == 0){ 71 | valueboxSetting* tempBox = (valueboxSetting*)it; 72 | tempBox->getValueBox()->setText(conf->value(readSetting)); 73 | } 74 | conf->remove(readSetting); // To find unknown settings added by user 75 | } 76 | 77 | } 78 | } 79 | } 80 | 81 | tabWindow::~tabWindow() 82 | { 83 | delete windowSettings; 84 | delete manualPages; 85 | delete ui; 86 | } 87 | -------------------------------------------------------------------------------- /src/tabmisc.cpp: -------------------------------------------------------------------------------- 1 | #include "tabmisc.hpp" 2 | #include "ui_tabmisc.h" 3 | 4 | tabMisc::tabMisc(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabMisc) 7 | { 8 | ui->setupUi(this); 9 | miscSettings = new std::vector(); 10 | manualPages = new QStringList(); 11 | manualPages->append(":/man/options.rst"); 12 | 13 | addMiscSetting(ui->comboBox_ytdl_format, ui->box_ytdl_format); 14 | addMiscSetting(ui->box_save_position_on_quit); 15 | addMiscSetting(ui->comboBox_priority, ui->box_priority); 16 | addMiscSetting(ui->comboBox_force_seekable, ui->box_force_seekable); 17 | addMiscSetting(ui->valuebox_cdrom_device, ui->box_cdrom_device); 18 | addMiscSetting(ui->valuebox_heartbeat_cmd, ui->box_heartbeat_cmd); 19 | addMiscSetting(ui->valuebox_heartbeat_interval, ui->box_heartbeat_interval); 20 | addMiscSetting(ui->box_no_cache); 21 | addMiscSetting(ui->comboBox_cache, ui->box_cache); 22 | addMiscSetting(ui->comboBox_cache_default, ui->box_cache_default); 23 | addMiscSetting(ui->valuebox_cache_initial, ui->box_cache_initial); 24 | addMiscSetting(ui->valuebox_cache_secs, ui->box_cache_secs); 25 | addMiscSetting(ui->valuebox_cache_seek_min, ui->box_cache_seek_min); 26 | addMiscSetting(ui->box_no_cache_pause); 27 | addMiscSetting(ui->valuebox_network_timeout, ui->box_network_timeout); 28 | addMiscSetting(ui->comboBox_hls_bitrate, ui->box_hls_bitrate); 29 | 30 | connect(ui->button_browse_cdrom, SIGNAL(clicked()), this, SLOT(openCDROMFolder())); 31 | 32 | } 33 | 34 | void tabMisc::addMiscSetting(QCheckBox* box) { 35 | miscSettings->push_back(new setting(box, manualPages)); 36 | } 37 | 38 | void tabMisc::addMiscSetting(QComboBox* comboBox, QCheckBox* box) { 39 | miscSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 40 | } 41 | 42 | void tabMisc::addMiscSetting(QLineEdit* valueBox, QCheckBox* box) { 43 | miscSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 44 | } 45 | 46 | void tabMisc::parseToConf(QStringList* conf){ 47 | conf->append("\n# Miscellaneous settings"); 48 | for(auto & it : *miscSettings) { 49 | if(it->getSettingStatus()){ 50 | if(it->getType().compare("checkbox") == 0) 51 | conf->append(it->getName()); 52 | else 53 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 54 | } 55 | }; 56 | } 57 | 58 | // Opens a file dialog for the user to choose a CD-ROM drive. 59 | void tabMisc::openCDROMFolder(){ 60 | QString folderName = QFileDialog::getExistingDirectory(this, 61 | tr("Open CD-ROM folder..."), QDir::homePath()); 62 | ui->valuebox_cdrom_device->setText(QString('"').append(folderName).append('"')); 63 | } 64 | 65 | void tabMisc::applyFromReadConf(QMap* conf){ 66 | for(auto & readSetting : conf->keys()) { 67 | for(auto & it : *miscSettings){ 68 | if(readSetting.compare(it->getName()) == 0){ 69 | it->getCheckBox()->setChecked(true); 70 | if(it->getType().compare("combobox") == 0){ 71 | comboboxSetting* tempBox = (comboboxSetting*)it; 72 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 73 | } 74 | else if(it->getType().compare("valuebox") == 0){ 75 | valueboxSetting* tempBox = (valueboxSetting*)it; 76 | tempBox->getValueBox()->setText(conf->value(readSetting)); 77 | } 78 | conf->remove(readSetting); // To find unknown settings added by user 79 | } 80 | } 81 | } 82 | } 83 | 84 | tabMisc::~tabMisc() 85 | { 86 | delete miscSettings; 87 | delete manualPages; 88 | delete ui; 89 | } 90 | -------------------------------------------------------------------------------- /src/tabosc.cpp: -------------------------------------------------------------------------------- 1 | #include "tabosc.hpp" 2 | #include "ui_tabosc.h" 3 | 4 | tabosc::tabosc(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabosc) 7 | { 8 | ui->setupUi(this); 9 | 10 | // Remove ugly border from the images. 11 | ui->graphicsview_box_osc->setStyleSheet("background: transparent; border: 0px;"); 12 | ui->graphicsView_bottombar_osc->setStyleSheet("background: transparent; border: 0px;"); 13 | ui->graphicsView_top_bar_osc->setStyleSheet("background: transparent; border: 0px;"); 14 | ui->graphicsView_slim_box_osc->setStyleSheet("background: transparent; border: 0px;"); 15 | ui->graphicsView_seekbar_bar->setStyleSheet("background: transparent; border: 0px;"); 16 | ui->graphicsView_seekbar_diamond->setStyleSheet("background: transparent; border: 0px;"); 17 | 18 | box_osc_scene = new QGraphicsScene(); 19 | bottombar_osc_scene = new QGraphicsScene(); 20 | topbar_osc_scene = new QGraphicsScene(); 21 | slimbox_osc_scene = new QGraphicsScene(); 22 | seekbar_osc_bar_scene = new QGraphicsScene(); 23 | seekbar_osc_diamond_scene= new QGraphicsScene(); 24 | 25 | box_osc_scene->addPixmap(QPixmap(":/images/oscs/box.png")); 26 | bottombar_osc_scene->addPixmap(QPixmap(":/images/oscs/bottombar.png")); 27 | topbar_osc_scene->addPixmap(QPixmap(":/images/oscs/topbar.png")); 28 | slimbox_osc_scene->addPixmap(QPixmap(":/images/oscs/slimbox.png")); 29 | seekbar_osc_bar_scene->addPixmap(QPixmap(":/images/oscs/seekbarstylebar.png")); 30 | seekbar_osc_diamond_scene->addPixmap(QPixmap(":/images/oscs/seekbarstylediamond.png")); 31 | 32 | // Add the OSC radio buttons. 33 | ui->graphicsview_box_osc->setScene(box_osc_scene); 34 | ui->graphicsView_bottombar_osc->setScene(bottombar_osc_scene); 35 | ui->graphicsView_top_bar_osc->setScene(topbar_osc_scene); 36 | ui->graphicsView_slim_box_osc->setScene(slimbox_osc_scene); 37 | ui->graphicsView_seekbar_bar->setScene(seekbar_osc_bar_scene); 38 | ui->graphicsView_seekbar_diamond->setScene(seekbar_osc_diamond_scene); 39 | } 40 | 41 | // Ugly parsed, should rewrite. 42 | void tabosc::parseToConf(QStringList* conf){ 43 | conf->append("\n# OSC settings"); 44 | QString toBeAdded; 45 | if(ui->radio_no_osc->isChecked()) 46 | toBeAdded.append("no-osc"); 47 | else if(ui->radio_preset_2->isChecked()) 48 | toBeAdded.append("script-opts=osc-layout=bottombar,"); 49 | else if(ui->radio_preset_3->isChecked()) 50 | toBeAdded.append("script-opts=osc-layout=topbar,"); 51 | else if(ui->radio_preset_4->isChecked()) 52 | toBeAdded.append("script-opts=osc-layout=slimbox,"); 53 | else 54 | toBeAdded.append("script-opts=osc-layout=box,"); 55 | 56 | if(!ui->radio_no_osc->isChecked() && ui->radio_seekbar_diamond->isChecked()) 57 | toBeAdded.append("osc-seekbarstyle=slider"); 58 | else if(!ui->radio_no_osc->isChecked()) 59 | toBeAdded.append("osc-seekbarstyle=bar"); 60 | 61 | conf->append(toBeAdded); 62 | } 63 | 64 | void tabosc::readFromConf(QString conf){ 65 | if(conf.contains("no-osc")){ 66 | ui->radio_no_osc->setChecked(true); 67 | return; 68 | } 69 | else if(conf.contains("bottombar")) 70 | ui->radio_preset_2->setChecked(true); 71 | else if(conf.contains("topbar")) 72 | ui->radio_preset_3->setChecked(true); 73 | else if(conf.contains("slimbox")) 74 | ui->radio_preset_4->setChecked(true); 75 | else 76 | ui->radio_preset_1->setChecked(true); 77 | 78 | if(conf.contains("seekbarstyle=slider")) 79 | ui->radio_seekbar_diamond->setChecked(true); 80 | else 81 | ui->radio_seekbar_bar->setChecked(true); 82 | } 83 | 84 | tabosc::~tabosc() 85 | { 86 | delete box_osc_scene; 87 | delete bottombar_osc_scene; 88 | delete topbar_osc_scene; 89 | delete slimbox_osc_scene; 90 | delete seekbar_osc_bar_scene; 91 | delete seekbar_osc_diamond_scene; 92 | delete ui; 93 | 94 | } 95 | -------------------------------------------------------------------------------- /src/setting.cpp: -------------------------------------------------------------------------------- 1 | #include "setting.hpp" 2 | 3 | setting::setting(QCheckBox* checkbox, QStringList* manuals) : 4 | name{checkbox->text()}, manual{manuals}, description{""}, settingStatus{false}, settingCheckBox{checkbox}, type{"checkbox"}, value{""} { 5 | connect(settingCheckBox, SIGNAL(toggled(bool)), this, SLOT(toggleSetting(bool))); 6 | description = parseSetting(); 7 | settingCheckBox->setToolTip(description); 8 | } 9 | 10 | void setting::setName(QString name_) { 11 | name = name_; 12 | } 13 | 14 | void setting::setDescription(QString description_) { 15 | description = description_; 16 | } 17 | 18 | void setting::toggleSetting(bool toggledTo) { 19 | settingStatus=toggledTo; 20 | } 21 | 22 | void setting::setCheckBox(QCheckBox *box){ 23 | settingCheckBox = box; 24 | } 25 | 26 | QString setting::getName() { 27 | return name; 28 | } 29 | 30 | QString setting::getDescription() { 31 | return description; 32 | } 33 | 34 | bool setting::getSettingStatus() { 35 | return settingStatus; 36 | } 37 | 38 | QCheckBox* setting::getCheckBox(){ 39 | return settingCheckBox; 40 | } 41 | 42 | QString setting::getType(){ 43 | return type; 44 | } 45 | 46 | QString setting::getValue(){ 47 | return value; 48 | } 49 | 50 | // This method parses tooltips from .rst files located in ./man. 51 | // accessibleName and accessibleDescription is used as a name/description override for hard-to-parse options. 52 | // This is obviously not how accessible stuff should be used, but you know what? Fuck it. 53 | QString setting::parseSetting(){ 54 | QString regularExpress; 55 | if(!settingCheckBox->accessibleName().isEmpty()) 56 | regularExpress.append("(``|``--)").append(settingCheckBox->accessibleName()).append(".*``\n"); // This is a override. 57 | else 58 | regularExpress.append("(``|``--)").append(name).append(".*``\n"); 59 | QStringList listAuto; 60 | for(auto &i : *manual){ 61 | QFile manualFile(i); 62 | if(manualFile.open(QFile::ReadOnly |QFile::Text)) 63 | { 64 | while(!manualFile.atEnd()) 65 | { 66 | QString testString = manualFile.readLine(); 67 | if(testString.contains(QRegularExpression(regularExpress))){ 68 | break; 69 | } 70 | } 71 | } 72 | QString currentLine = ""; 73 | while(true){ 74 | currentLine = manualFile.readLine(); 75 | if(currentLine.contains(QRegularExpression(".*---.*"))){ 76 | listAuto.removeLast(); 77 | break; 78 | } 79 | else if(currentLine.contains("admonition::")){ 80 | int indentedBy{0}; 81 | QChar whitespace = currentLine.at(indentedBy); 82 | while(whitespace.isSpace()){ 83 | indentedBy++; 84 | whitespace = currentLine.at(indentedBy); 85 | } 86 | QString neededIndentationToAdd = QString("^ {").append(QString::number(indentedBy)).append("}.*"); 87 | while(currentLine.startsWith("\n") || currentLine.contains(QRegularExpression(neededIndentationToAdd))){ 88 | listAuto += currentLine; 89 | currentLine = manualFile.readLine(); 90 | } 91 | break; 92 | } 93 | else if(currentLine.contains(QRegularExpression("``.*``\n"))) 94 | break; 95 | else if(manualFile.atEnd()){ 96 | break; 97 | } 98 | listAuto += currentLine; 99 | } 100 | QString output; 101 | for(int i = 0; i < listAuto.length(); i++){ 102 | output.append(listAuto[i]); 103 | } 104 | if(!output.isEmpty()){ 105 | output = output.replace(QRegularExpression(" "), ""); 106 | output = output.replace(QRegularExpression("``"), "'"); 107 | output = output.replace(QRegularExpression(".. admonition:: "), ""); 108 | output = output.replace(QRegularExpression(".. note::"), "Note:"); 109 | output = output.replace(QRegularExpression(".. warning::"), "Warning:"); 110 | return output.trimmed(); 111 | } 112 | } 113 | if(!settingCheckBox->accessibleDescription().isEmpty()){ 114 | return settingCheckBox->accessibleDescription(); 115 | } 116 | qDebug() << "Failed to read manual description from - " << name; 117 | return "No tooltip available for this option. Please look it up in the manual."; 118 | } 119 | 120 | setting::~setting() {} 121 | 122 | -------------------------------------------------------------------------------- /src/mainwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 900 11 | 12 | 13 | 14 | MainWindow 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 0 23 | 0 24 | 25 | 26 | 27 | 28 | 860 29 | 450 30 | 31 | 32 | 33 | QTabWidget::North 34 | 35 | 36 | QTabWidget::Rounded 37 | 38 | 39 | -1 40 | 41 | 42 | Qt::ElideMiddle 43 | 44 | 45 | false 46 | 47 | 48 | false 49 | 50 | 51 | false 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 0 61 | 0 62 | 1000 63 | 22 64 | 65 | 66 | 67 | 68 | File 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | Help 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Open 91 | 92 | 93 | 94 | 95 | Save 96 | 97 | 98 | 99 | 100 | Save as... 101 | 102 | 103 | 104 | 105 | New... 106 | 107 | 108 | Ctrl+N 109 | 110 | 111 | 112 | 113 | Open... 114 | 115 | 116 | Ctrl+O 117 | 118 | 119 | Qt::ApplicationShortcut 120 | 121 | 122 | 123 | 124 | Save... 125 | 126 | 127 | Ctrl+S 128 | 129 | 130 | 131 | 132 | Save as... 133 | 134 | 135 | Ctrl+Shift+S 136 | 137 | 138 | Qt::ApplicationShortcut 139 | 140 | 141 | 142 | 143 | Manual 144 | 145 | 146 | 147 | 148 | Exit 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /src/tabextensions.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | tabExtensions 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 900 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | 1 21 | 22 | 23 | 150 24 | 25 | 26 | 27 | 28 | Extensions settings: 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 75 37 | true 38 | true 39 | 40 | 41 | 42 | <html><head/><body><p>Extensions allows you to customize settings for a certain filetype. For example all .webm files can automatically loop, while any other filetype does not.</p><p>Since there's a plethora of settings you can add here, it has been sat as a text editor instead of a bunch of checkboxes. Check the settings around in the configurator for settings tips. You can also check the manual for further settings.</p></body></html> 43 | 44 | 45 | (?) 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Qt::Horizontal 55 | 56 | 57 | 58 | 40 59 | 20 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Qt::Horizontal 68 | 69 | 70 | 71 | 40 72 | 20 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 0 83 | 84 | 85 | 86 | true 87 | 88 | 89 | 90 | 0 91 | 0 92 | 93 | 94 | 95 | EXAMPLE 96 | 97 | 98 | 99 | 100 | 101 | Name: 102 | 103 | 104 | 105 | 106 | 107 | 108 | .exmpl 109 | 110 | 111 | 112 | 113 | 114 | 115 | true 116 | 117 | 118 | ontop 119 | loop-file=yes 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 75 128 | true 129 | 130 | 131 | 132 | Note: This example extension will not be added to the config. 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 30 146 | 147 | 148 | 15 149 | 150 | 151 | 10 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Add Extension 160 | 161 | 162 | 163 | 164 | 165 | 166 | Remove Current 167 | 168 | 169 | 170 | 171 | 172 | 173 | horizontalSpacer 174 | horizontalSpacer_2 175 | 176 | 177 | 178 | 179 | -------------------------------------------------------------------------------- /src/tabosd.cpp: -------------------------------------------------------------------------------- 1 | #include "tabosd.hpp" 2 | #include "ui_tabosd.h" 3 | 4 | 5 | tabosd::tabosd(QWidget *parent) : 6 | QWidget(parent), 7 | ui(new Ui::tabosd) 8 | { 9 | ui->setupUi(this); 10 | 11 | osdSettings = new std::vector(); 12 | manualPages = new QStringList(); 13 | manualPages->append(":/man/options.rst"); 14 | 15 | addOSDSetting(ui->box_no_osd); 16 | addOSDSetting(ui->valuebox_osd_duration, ui->box_osd_duration); 17 | osdSettings->push_back(new fontBoxSetting(ui->fontComboBox, ui->box_osd_font, manualPages)); 18 | addOSDSetting(ui->valuebox_osd_msg1, ui->box_osd_msg1); 19 | addOSDSetting(ui->valuebox_osd_msg2, ui->box_osd_msg2); 20 | addOSDSetting(ui->valuebox_osd_msg3, ui->box_osd_msg3); 21 | addOSDSetting(ui->valuebox_osd_status_msg, ui->box_osd_status_msg); 22 | addOSDSetting(ui->valuebox_osd_playing_msg, ui->box_osd_playing_msg); 23 | addOSDSetting(ui->box_osd_fractions); 24 | addOSDSetting(ui->comboBox_osd_level, ui->box_osd_level); 25 | addOSDSetting(ui->comboBox_osd_scale_by_window, ui->box_osd_scale_by_window); 26 | addOSDSetting(ui->comboBox_osd_align_x, ui->box_osd_align_x); 27 | addOSDSetting(ui->comboBox_osd_align_y, ui->box_osd_align_y); 28 | addOSDSetting(ui->comboBox_osd_bold, ui->box_osd_font_bold); 29 | 30 | addOSDSetting(ui->horizontalSlider_osd_bar_align_x, ui->slider_value_osd_align_x, 10, ui->box_osd_bar_align_x); 31 | addOSDSetting(ui->horizontalSlider_osd_bar_align_y, ui->slider_value_osd_align_y, 10, ui->box_osd_bar_align_y); 32 | addOSDSetting(ui->horizontalSlider_osd_bar_w, ui->slider_value_osd_bar_w, 1, ui->box_osd_bar_w); 33 | addOSDSetting(ui->horizontalSlider_osd_bar_h, ui->slider_value_osd_bar_h, 10, ui->box_osd_bar_h); 34 | addOSDSetting(ui->horizontalSlider_osd_margin_x, ui->slider_value_osd_margin_x, 1, ui->box_osd_margin_x); 35 | addOSDSetting(ui->horizontalSlider_osd_margin_y, ui->slider_value_osd_margin_y, 1, ui->box_osd_margin_y); 36 | addOSDSetting(ui->horizontalSlider_osd_blur, ui->slider_value_osd_blur, 10, ui->box_osd_blur); 37 | addOSDSetting(ui->horizontalSlider_osd_font_size, ui->slider_value_osd_font_size, 1, ui->box_osd_font_size); 38 | addOSDSetting(ui->horizontalSlider_osd_border_size, ui->slider_value_osd_border_size, 1, ui->box_osd_border_size); 39 | addOSDSetting(ui->horizontalSlider_osd_shadow_offset, ui->slider_value_osd_shadow_offset, 1, ui->box_osd_shadow_offset); 40 | addOSDSetting(ui->horizontalSlider_osd_spacing, ui->slider_value_osd_spacing, 1, ui->box_osd_spacing); 41 | 42 | addOSDSetting(ui->value_osd_back_color, ui->box_osd_back_color); 43 | addOSDSetting(ui->value_osd_color, ui->box_osd_color); 44 | addOSDSetting(ui->value_osd_border_color, ui->box_osd_border_color); 45 | addOSDSetting(ui->value_osd_shadow_color, ui->box_osd_shadow_color); 46 | 47 | colorPickerFontColor= new QColorDialog(); 48 | colorPickerFontColor->setOption(QColorDialog::ShowAlphaChannel); 49 | colorPickerBorderColor= new QColorDialog(); 50 | colorPickerBorderColor->setOption(QColorDialog::ShowAlphaChannel); 51 | colorPickerShadowColor= new QColorDialog(); 52 | colorPickerShadowColor->setOption(QColorDialog::ShowAlphaChannel); 53 | colorPickerBackColor= new QColorDialog(); 54 | colorPickerBackColor->setOption(QColorDialog::ShowAlphaChannel); 55 | 56 | connect(ui->button_pick_osd_color, SIGNAL(clicked()), colorPickerFontColor, SLOT(open())); 57 | connect(colorPickerFontColor, SIGNAL(colorSelected(QColor)), this, SLOT(setOSDFontColor(QColor))); 58 | 59 | connect(ui->button_pick_osd_border_color, SIGNAL(clicked()), colorPickerBorderColor, SLOT(open())); 60 | connect(colorPickerBorderColor, SIGNAL(colorSelected(QColor)), this, SLOT(setOSDBorderColor(QColor))); 61 | 62 | connect(ui->button_pick_osd_shadow_color, SIGNAL(clicked()), colorPickerShadowColor, SLOT(open())); 63 | connect(colorPickerShadowColor, SIGNAL(colorSelected(QColor)), this, SLOT(setOSDShadowColor(QColor))); 64 | 65 | connect(ui->button_pick_osd_back_color, SIGNAL(clicked()), colorPickerBackColor, SLOT(open())); 66 | connect(colorPickerBackColor, SIGNAL(colorSelected(QColor)), this, SLOT(setOSDBackColor(QColor))); 67 | } 68 | 69 | void tabosd::setOSDFontColor(QColor i){ 70 | fontColor = i; 71 | ui->value_osd_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 72 | } 73 | 74 | void tabosd::setOSDBorderColor(QColor i){ 75 | borderColor = i; 76 | ui->value_osd_border_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 77 | } 78 | 79 | void tabosd::setOSDShadowColor(QColor i){ 80 | shadowColor = i; 81 | ui->value_osd_shadow_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 82 | } 83 | 84 | void tabosd::setOSDBackColor(QColor i){ 85 | fontColor = i; 86 | ui->value_osd_back_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 87 | } 88 | 89 | void tabosd::addOSDSetting(QCheckBox* box) { 90 | osdSettings->push_back(new setting(box, manualPages)); 91 | } 92 | 93 | void tabosd::addOSDSetting(QComboBox* comboBox, QCheckBox* box) { 94 | osdSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 95 | } 96 | 97 | void tabosd::addOSDSetting(QLineEdit* valueBox, QCheckBox* box) { 98 | osdSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 99 | } 100 | 101 | void tabosd::addOSDSetting(QSlider* slider, QLabel* valueCounter, int divideBy, QCheckBox* box) { 102 | osdSettings->push_back(new sliderSetting(slider, valueCounter, divideBy, box, manualPages)); 103 | } 104 | 105 | void tabosd::parseToConf(QStringList* conf){ 106 | conf->append("\n# OSD settings"); 107 | for(auto & it : *osdSettings) { 108 | if(it->getSettingStatus()){ 109 | if(it->getType().compare("checkbox") == 0) 110 | conf->append(it->getName()); 111 | else{ 112 | if(it->getName().contains(QRegularExpression(".*msg.*")) && !it->getValue().startsWith('"')){ 113 | conf->append(QString(it->getName()).append("=").append(QString('"').append(it->getValue()).append('"'))); 114 | } 115 | else 116 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 117 | } 118 | } 119 | }; 120 | } 121 | 122 | void tabosd::applyFromReadConf(QMap* conf){ 123 | for(auto & readSetting : conf->keys()) { 124 | for(auto & it : *osdSettings){ 125 | if(readSetting.compare(it->getName()) == 0){ 126 | it->getCheckBox()->setChecked(true); 127 | if(it->getType().compare("combobox") == 0){ 128 | comboboxSetting* tempBox = (comboboxSetting*)it; 129 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 130 | } 131 | else if(it->getType().compare("valuebox") == 0){ 132 | valueboxSetting* tempBox = (valueboxSetting*)it; 133 | tempBox->getValueBox()->setText(conf->value(readSetting)); 134 | } 135 | else if(it->getType().compare("slider") == 0){ 136 | sliderSetting* tempBox = (sliderSetting*)it; 137 | tempBox->getSlider()->setValue((conf->value(readSetting).toFloat()*tempBox->getDivideBy())); // Sets slider's position properly. 138 | tempBox->updateShownValue(tempBox->getSlider()->value()); // Needed to set the label's proper value. 139 | } 140 | conf->remove(readSetting); // To find unknown settings added by user 141 | } 142 | } 143 | } 144 | } 145 | 146 | tabosd::~tabosd() 147 | { 148 | delete colorPickerFontColor; 149 | delete colorPickerBorderColor; 150 | delete colorPickerShadowColor; 151 | delete colorPickerBackColor; 152 | delete manualPages; 153 | delete osdSettings; 154 | delete ui; 155 | 156 | } 157 | -------------------------------------------------------------------------------- /src/tabosc.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | tabosc 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 900 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 100 19 | 20 | 21 | 100 22 | 23 | 24 | 30 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 16777215 34 | 30 35 | 36 | 37 | 38 | Seekbar settings: 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 250 47 | 50 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 250 57 | 50 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | Seekbar - Bar 66 | 67 | 68 | true 69 | 70 | 71 | true 72 | 73 | 74 | 75 | 76 | 77 | 78 | Seekbar - Diamond 79 | 80 | 81 | true 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | SlimBox OSC 95 | 96 | 97 | true 98 | 99 | 100 | 101 | 102 | 103 | 104 | Qt::Horizontal 105 | 106 | 107 | 108 | 40 109 | 20 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | Bottombar OSC 118 | 119 | 120 | true 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | Qt::Horizontal 134 | 135 | 136 | 137 | 40 138 | 20 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | Qt::Horizontal 147 | 148 | 149 | 150 | 40 151 | 20 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | Qt::Horizontal 160 | 161 | 162 | 163 | 40 164 | 20 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | Topbar OSC 173 | 174 | 175 | true 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | Classic 'box' OSC 189 | 190 | 191 | true 192 | 193 | 194 | true 195 | 196 | 197 | false 198 | 199 | 200 | true 201 | 202 | 203 | 204 | 205 | 206 | 207 | Qt::Horizontal 208 | 209 | 210 | 211 | 40 212 | 20 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | no-osc 221 | 222 | 223 | true 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | radio_no_osc 236 | toggled(bool) 237 | widget 238 | setDisabled(bool) 239 | 240 | 241 | 490 242 | 59 243 | 244 | 245 | 470 246 | 805 247 | 248 | 249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /src/tabscreenshot.cpp: -------------------------------------------------------------------------------- 1 | #include "tabscreenshot.hpp" 2 | #include "ui_tabscreenshot.h" 3 | 4 | tabScreenshot::tabScreenshot(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabScreenshot) 7 | { 8 | ui->setupUi(this); 9 | enablePNGandJPEGWidgets("Disable both!"); 10 | ui->frame->hide(); 11 | ui->label_custom_template->hide(); 12 | ui->valuebox_custom_template->hide(); 13 | 14 | screenshotSettings = new std::vector(); 15 | manualPages = new QStringList(); 16 | manualPages->append(":/man/options.rst"); 17 | 18 | addScreenshotSetting(ui->valuebox_screenshot_directory, ui->box_screenshot_directory); 19 | addScreenshotSetting(ui->comboBox_screenshot_format, ui->box_screenshot_format); 20 | addScreenshotSetting(ui->comboBox_screenshot_tag_colorspace, ui->box_screenshot_tag_colorspace); 21 | addScreenshotSetting(ui->comboBox_screenshot_high_bit_depth, ui->box_screenshot_high_bit_depth); 22 | addScreenshotSetting(ui->combobox_screenshot_template, ui->box_screenshot_template); 23 | addScreenshotSetting(ui->valuebox_screenshot_jpeg_quality, ui->box_screenshot_jpeg_quality); 24 | addScreenshotSetting(ui->comboBox_jpeg_source_chroma, ui->box_screenshot_jpeg_source_chroma); 25 | addScreenshotSetting(ui->comboBox_png_compression, ui->box_screenshot_png_compression); 26 | addScreenshotSetting(ui->comboBox_png_filter, ui->box_screenshot_png_filter); 27 | 28 | connect(ui->comboBox_screenshot_format, SIGNAL(currentTextChanged(QString)), this, SLOT(enablePNGandJPEGWidgets(QString))); 29 | connect(ui->combobox_screenshot_template, SIGNAL(currentTextChanged(QString)), this, SLOT(enableDisableCustomTemplate(QString))); 30 | connect(ui->browse_button, SIGNAL(clicked()), this, SLOT(browseForScreenshotFolder())); 31 | } 32 | 33 | 34 | // Then there's this ugly piece of shit. 35 | // Converts the visible choices into actual usable values. 36 | QString tabScreenshot::convertTemplateToFormat(){ 37 | QString output = ui->valuebox_screenshot_directory->text(); 38 | switch(ui->combobox_screenshot_template->currentIndex()){ 39 | case 0: 40 | output.append("%f-%n"); 41 | break; 42 | case 1: 43 | output.append("%f-%td-%tm-%ty-%n"); 44 | break; 45 | case 2: 46 | output.append("%f-%tm-%td-%ty-%n"); 47 | break; 48 | case 3: 49 | output.append("%f-%td-%tm-%ty-at-%tH.%tM-%n"); 50 | break; 51 | case 4: 52 | output.append("%f-%tm-%td-%ty-at-%tH.%tM-%n"); 53 | break; 54 | case 5: 55 | output.append("%f-screenshot-%n"); 56 | break; 57 | case 6: 58 | output.append("%f-screenshot-%td-%tm-%ty-%n"); 59 | break; 60 | case 7: 61 | output.append("%f-screenshot-%tm-%td-%ty-%n"); 62 | break; 63 | case 8: 64 | output.append("%f-screenshot-%td-%tm-%ty-at-%tH.%tM-%n"); 65 | break; 66 | case 9: 67 | output.append("%f-screenshot-%tm-%td-%ty-at-%tH.%tM-%n"); 68 | break; 69 | case 10: 70 | output.append("mpv-screenshot-%td-%tm-%ty-at-%tH.%tM-%n"); 71 | break; 72 | case 11: 73 | output.append("mpv-screenshot-%tm-%td-%ty-at-%tH.%tM-%n"); 74 | break; 75 | case 12: 76 | output.append("mpv-screenshot-%td-%tm-%ty-%n"); 77 | break; 78 | case 13: 79 | output.append("mpv-screenshot-%tm-%td-%ty-%n"); 80 | break; 81 | case 14: 82 | output.append("mpv-screenshot-%n"); 83 | break; 84 | case 15: 85 | output.append(ui->valuebox_custom_template->text()); 86 | } 87 | return output; 88 | } 89 | 90 | void tabScreenshot::addScreenshotSetting(QCheckBox* box) { 91 | screenshotSettings->push_back(new setting(box, manualPages)); 92 | } 93 | 94 | void tabScreenshot::addScreenshotSetting(QComboBox* comboBox, QCheckBox* box) { 95 | screenshotSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 96 | } 97 | 98 | void tabScreenshot::addScreenshotSetting(QLineEdit* valueBox, QCheckBox* box) { 99 | screenshotSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 100 | } 101 | 102 | // Clears all the file specific settings so that JPG won't suddenly have PNG settings or vice versa. 103 | void tabScreenshot::enablePNGandJPEGWidgets(QString changedTo){ 104 | if(changedTo.compare("png") == 0){ 105 | ui->widget_jpeg_settings->setDisabled(true); 106 | ui->widget_png_settings->setDisabled(false); 107 | ui->box_screenshot_jpeg_quality->setChecked(false); 108 | ui->box_screenshot_jpeg_source_chroma->setChecked(false); 109 | } 110 | else if(changedTo.compare("jpg") == 0){ 111 | ui->widget_jpeg_settings->setDisabled(false); 112 | ui->widget_png_settings->setDisabled(true); 113 | ui->box_screenshot_png_compression->setChecked(false); 114 | ui->box_screenshot_png_filter->setChecked(false); 115 | } 116 | else{ 117 | ui->widget_jpeg_settings->setDisabled(true); 118 | ui->widget_png_settings->setDisabled(true); 119 | ui->box_screenshot_png_compression->setChecked(false); 120 | ui->box_screenshot_png_filter->setChecked(false); 121 | ui->box_screenshot_jpeg_quality->setChecked(false); 122 | ui->box_screenshot_jpeg_source_chroma->setChecked(false); 123 | } 124 | } 125 | 126 | // Shows the custom template guide. 127 | void tabScreenshot::enableDisableCustomTemplate(QString changedTo){ 128 | if(changedTo.compare("Custom") == 0){ 129 | ui->frame->show(); 130 | ui->label_custom_template->show(); 131 | ui->valuebox_custom_template->show(); 132 | } 133 | else{ 134 | ui->frame->hide(); 135 | ui->label_custom_template->hide(); 136 | ui->valuebox_custom_template->hide(); 137 | } 138 | } 139 | 140 | void tabScreenshot::parseToConf(QStringList* conf){ 141 | conf->append("\n# Screenshot settings"); 142 | for(auto & it : *screenshotSettings) { 143 | if(it->getSettingStatus()){ 144 | if(it->getType().compare("checkbox") == 0) 145 | conf->append(it->getName()); 146 | else{ 147 | if(it->getCheckBox()->text().compare("screenshot-template") == 0) 148 | conf->append(QString(it->getName()).append("=").append(convertTemplateToFormat())); // Needed to convert example to actual format. 149 | else if(it->getCheckBox()->text().compare("screenshot-directory") == 0){ 150 | // Do nothing. It is automatically merged with screenshot-template. 151 | } 152 | else 153 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 154 | } 155 | } 156 | } 157 | } 158 | 159 | void tabScreenshot::applyFromReadConf(QMap* conf){ 160 | for(auto & readSetting : conf->keys()) { 161 | for(auto & it : *screenshotSettings){ 162 | if(readSetting.compare(it->getName()) == 0){ 163 | if(it->getName().compare("screenshot-template") == 0){ 164 | QStringList tempStringList = conf->value(readSetting).split(QDir::separator()); 165 | ui->box_screenshot_directory->setChecked(true); 166 | ui->valuebox_screenshot_directory->setText(tempStringList.join(QDir::separator()).remove(tempStringList.last())); 167 | ui->combobox_screenshot_template->setCurrentIndex(15); 168 | ui->valuebox_custom_template->setText(tempStringList.last()); 169 | } 170 | it->getCheckBox()->setChecked(true); 171 | if(it->getType().compare("combobox") == 0){ 172 | comboboxSetting* tempBox = (comboboxSetting*)it; 173 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 174 | } 175 | else if(it->getType().compare("valuebox") == 0){ 176 | valueboxSetting* tempBox = (valueboxSetting*)it; 177 | tempBox->getValueBox()->setText(conf->value(readSetting)); 178 | } 179 | conf->remove(readSetting); // To find unknown settings added by user 180 | } 181 | } 182 | } 183 | } 184 | 185 | void tabScreenshot::browseForScreenshotFolder(){ 186 | QString folderName = QFileDialog::getExistingDirectory(this, 187 | tr("Open screenshot folder..."), QDir::homePath()); 188 | ui->valuebox_screenshot_directory->setText(folderName.append(QDir::separator())); 189 | } 190 | 191 | tabScreenshot::~tabScreenshot() 192 | { 193 | delete screenshotSettings; 194 | delete manualPages; 195 | delete ui; 196 | } 197 | -------------------------------------------------------------------------------- /src/man/osc.rst: -------------------------------------------------------------------------------- 1 | ON SCREEN CONTROLLER 2 | ==================== 3 | 4 | The On Screen Controller (short: OSC) is a minimal GUI integrated with mpv to 5 | offer basic mouse-controllability. It is intended to make interaction easier 6 | for new users and to enable precise and direct seeking. 7 | 8 | The OSC is enabled by default if mpv was compiled with Lua support. It can be 9 | disabled entirely using the ``--osc=no`` option. 10 | 11 | Using the OSC 12 | ------------- 13 | 14 | By default, the OSC will show up whenever the mouse is moved inside the 15 | player window and will hide if the mouse is not moved outside the OSC for 16 | 0.5 seconds or if the mouse leaves the window. 17 | 18 | The Interface 19 | ~~~~~~~~~~~~~ 20 | 21 | :: 22 | 23 | +------------------+-----------+--------------------+ 24 | | playlist prev | title | playlist next | 25 | +-------+------+---+--+------+-+----+------+--------+ 26 | | audio | skip | seek | | seek | skip | full | 27 | +-------+ back | back | play | frwd | frwd | screen | 28 | | sub | | | | | | | 29 | +-------+------+------+------+------+------+--------+ 30 | | seekbar | 31 | +----------------+--------------+-------------------+ 32 | | time passed | cache status | time remaining | 33 | +----------------+--------------+-------------------+ 34 | 35 | 36 | playlist prev 37 | ============= ================================================ 38 | left-click play previous file in playlist 39 | shift+L-click show playlist 40 | ============= ================================================ 41 | 42 | title 43 | | Displays current media-title or filename 44 | 45 | ============= ================================================ 46 | left-click show playlist position and length and full title 47 | right-click show filename 48 | ============= ================================================ 49 | 50 | playlist next 51 | ============= ================================================ 52 | left-click play next file in playlist 53 | shift+L-click show playlist 54 | ============= ================================================ 55 | 56 | audio and sub 57 | | Displays selected track and amount of available tracks 58 | 59 | ============= ================================================ 60 | left-click cycle audio/sub tracks forward 61 | right-click cycle audio/sub tracks backwards 62 | shift+L-click show available audio/sub tracks 63 | ============= ================================================ 64 | 65 | skip back 66 | ============= ================================================ 67 | left-click go to beginning of chapter / previous chapter 68 | shift+L-click show chapters 69 | ============= ================================================ 70 | 71 | seek back 72 | ============= ================================================ 73 | left-click skip back 5 seconds 74 | right-click skip back 30 seconds 75 | shift-L-click skip back 1 frame 76 | ============= ================================================ 77 | 78 | play 79 | ============= ================================================ 80 | left-click toggle play/pause 81 | ============= ================================================ 82 | 83 | seek frwd 84 | ============= ================================================ 85 | left-click skip forward 10 seconds 86 | right-click skip forward 60 seconds 87 | shift-L-click skip forward 1 frame 88 | ============= ================================================ 89 | 90 | skip frwd 91 | ============= ================================================ 92 | left-click go to next chapter 93 | shift+L-click show chapters 94 | ============= ================================================ 95 | 96 | fullscreen 97 | ============= ================================================ 98 | left-click toggle fullscreen 99 | ============= ================================================ 100 | 101 | seekbar 102 | | Indicates current playback position and position of chapters 103 | 104 | ============= ================================================ 105 | left-click seek to position 106 | ============= ================================================ 107 | 108 | time passed 109 | | Shows current playback position timestamp 110 | 111 | ============= ================================================ 112 | left-click toggle displaying timecodes with milliseconds 113 | ============= ================================================ 114 | 115 | cache status 116 | | Shows current cache fill status (only visible when below 45%) 117 | 118 | time remaining 119 | | Shows remaining playback time timestamp 120 | 121 | ============= ================================================ 122 | left-click toggle between total and remaining time 123 | ============= ================================================ 124 | 125 | Key Bindings 126 | ~~~~~~~~~~~~ 127 | 128 | These key bindings are active by default if nothing else is already bound to 129 | these keys. In case of collision, the function needs to be bound to a 130 | different key. See the `Script Commands`_ section. 131 | 132 | ============= ================================================ 133 | del Hide the OSC permanently until mpv is restarted. 134 | ============= ================================================ 135 | 136 | Configuration 137 | ------------- 138 | 139 | The OSC offers limited configuration through a config file 140 | ``lua-settings/osc.conf`` placed in mpv's user dir and through the 141 | ``--script-opts`` command-line option. Options provided through the command-line 142 | will override those from the config file. 143 | 144 | Config Syntax 145 | ~~~~~~~~~~~~~ 146 | 147 | The config file must exactly follow the following syntax:: 148 | 149 | # this is a comment 150 | optionA=value1 151 | optionB=value2 152 | 153 | ``#`` can only be used at the beginning of a line and there may be no 154 | spaces around the ``=`` or anywhere else. 155 | 156 | Command-line Syntax 157 | ~~~~~~~~~~~~~~~~~~~ 158 | 159 | To avoid collisions with other scripts, all options need to be prefixed with 160 | ``osc-``. 161 | 162 | Example:: 163 | 164 | --script-opts=osc-optionA=value1,osc-optionB=value2 165 | 166 | 167 | Configurable Options 168 | ~~~~~~~~~~~~~~~~~~~~ 169 | 170 | ``showwindowed`` 171 | | Default: yes 172 | | Enable the OSC when windowed 173 | 174 | ``showfullscreen`` 175 | | Default: yes 176 | | Enable the OSC when fullscreen 177 | 178 | ``scalewindowed`` 179 | | Default: 1.0 180 | | Scale factor of the OSC when windowed 181 | 182 | ``scalefullscreen`` 183 | | Default: 1.0 184 | | Scale factor of the OSC when fullscreen 185 | 186 | ``scaleforcedwindow`` 187 | | Default: 2.0 188 | | Scale factor of the OSC when rendered on a forced (dummy) window 189 | 190 | ``vidscale`` 191 | | Default: yes 192 | | Scale the OSC with the video 193 | | ``no`` tries to keep the OSC size constant as much as the window size allows 194 | 195 | ``valign`` 196 | | Default: 0.8 197 | | Vertical alignment, -1 (top) to 1 (bottom) 198 | 199 | ``halign`` 200 | | Default: 0.0 201 | | Horizontal alignment, -1 (left) to 1 (right) 202 | 203 | ``boxalpha`` 204 | | Default: 80 205 | | Alpha of the background box, 0 (opaque) to 255 (fully transparent) 206 | 207 | ``hidetimeout`` 208 | | Default: 500 209 | | Duration in ms until the OSC hides if no mouse movement, negative value 210 | disables auto-hide 211 | 212 | ``fadeduration`` 213 | | Default: 200 214 | | Duration of fade out in ms, 0 = no fade 215 | 216 | ``deadzonesize`` 217 | | Default: 0 218 | | Size of the deadzone. The deadzone is an area that makes the mouse act 219 | like leaving the window. Movement there won't make the OSC show up and 220 | it will hide immediately if the mouse enters it. The deadzone starts 221 | at the window border opposite to the OSC and the size controls how much 222 | of the window it will span. Values between 0 and 1. 223 | 224 | ``minmousemove`` 225 | | Default: 3 226 | | Minimum amount of pixels the mouse has to move between ticks to make 227 | the OSC show up 228 | 229 | ``layout`` 230 | | Default: box 231 | | The layout for the OSC. Currently available are: box, slimbox, 232 | bottombar and topbar. 233 | 234 | ``seekbarstyle`` 235 | | Default: slider 236 | | Sets the style of the seekbar, slider (diamond marker) or bar (fill) 237 | 238 | ``timetotal`` 239 | | Default: no 240 | | Show total time instead of time remaining 241 | 242 | ``timems`` 243 | | Default: no 244 | | Display timecodes with milliseconds 245 | 246 | Script Commands 247 | ~~~~~~~~~~~~~~~ 248 | 249 | The OSC script listens to certain script commands. These commands can bound 250 | in ``input.conf``, or sent by other scripts. 251 | 252 | ``enable-osc`` 253 | Undoes ``disable-osc`` or the effect of the ``del`` key. 254 | 255 | ``disable-osc`` 256 | Hide the OSC permanently. This is also what the ``del`` key does. 257 | 258 | ``osc-message`` 259 | Show a message on screen using the OSC. First argument is the message, 260 | second the duration in seconds. 261 | 262 | 263 | Example 264 | 265 | You could put this into ``input.conf`` to hide the OSC with the ``a`` key and 266 | to unhide it with ``b``:: 267 | 268 | a script_message disable-osc 269 | b script_message enable-osc 270 | 271 | -------------------------------------------------------------------------------- /src/tabsubtitle.cpp: -------------------------------------------------------------------------------- 1 | #include "tabsubtitle.hpp" 2 | #include "ui_tabsubtitle.h" 3 | 4 | tabsubtitle::tabsubtitle(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabsubtitle) 7 | { 8 | ui->setupUi(this); 9 | 10 | subtitleSettings = new std::vector(); 11 | manualPages = new QStringList(); 12 | manualPages->append(":/man/options.rst"); 13 | 14 | addSubtitleSetting(ui->box_no_sub); 15 | addSubtitleSetting(ui->value_sub_delay, ui->box_sub_delay); 16 | addSubtitleSetting(ui->comboBox_sub_scale_by_window, ui->box_sub_scale_by_window); 17 | addSubtitleSetting(ui->comboBox_sub_scale_with_window, ui->box_sub_scale_with_window); 18 | addSubtitleSetting(ui->comboBox_ass_scale_with_window, ui->box_ass_scale_with_window); 19 | addSubtitleSetting(ui->box_no_embedded_fonts); 20 | addSubtitleSetting(ui->comboBox_ass_hinting, ui->box_ass_hinting); 21 | addSubtitleSetting(ui->comboBox_ass_sharper, ui->box_ass_sharper); 22 | addSubtitleSetting(ui->value_ass_force_style, ui->box_ass_force_style); 23 | addSubtitleSetting(ui->comboBox_ass_override, ui->box_ass_style_override); 24 | addSubtitleSetting(ui->comboBox_sub_auto, ui->box_sub_auto); 25 | addSubtitleSetting(ui->comboBox_stretch_dvd_subs, ui->box_stretch_dvd_subs); 26 | addSubtitleSetting(ui->box_no_sub_fix_timing); 27 | addSubtitleSetting(ui->value_sub_speed, ui->box_sub_speed); 28 | addSubtitleSetting(ui->box_demuxer_mkv_subtitle_preroll); 29 | addSubtitleSetting(ui->valuebox_slang, ui->box_slang); 30 | 31 | // Subtitle looks. 32 | addSubtitleSetting(ui->horizontalSlider_sub_text_font_size, ui->label_sub_text_font_size_counter, 1, ui->box_sub_text_font_size); 33 | addSubtitleSetting(ui->horizontalSlider_sub_text_font_shadow_offset, ui->label_sub_text_shadow_offset_counter, 2, ui->box_sub_text_font_shadow_offset); 34 | addSubtitleSetting(ui->horizontalSlider_sub_text_font_border_size, ui->label_sub_text_border_size_counter, 2, ui->box_sub_text_font_border_size); 35 | addSubtitleSetting(ui->value_sub_text_font_color, ui->box_sub_text_font_color); 36 | addSubtitleSetting(ui->value_sub_text_border_color, ui->box_sub_text_border_color); 37 | addSubtitleSetting(ui->value_sub_text_shadow_color, ui->box_sub_text_shadow_color); 38 | subtitleSettings->push_back(new fontBoxSetting(ui->fontComboBox_sub_text_font, ui->box_sub_text_font, manualPages)); 39 | connect(ui->fontComboBox_sub_text_font, SIGNAL(currentIndexChanged(int)), this, SLOT(updateTestText(int))); 40 | 41 | colorPickerFontColor= new QColorDialog(); 42 | colorPickerFontColor->setOption(QColorDialog::ShowAlphaChannel); 43 | colorPickerBorderColor= new QColorDialog(); 44 | colorPickerBorderColor->setOption(QColorDialog::ShowAlphaChannel); 45 | colorPickerShadowColor= new QColorDialog(); 46 | colorPickerShadowColor->setOption(QColorDialog::ShowAlphaChannel); 47 | 48 | // Font color dialog 49 | connect(ui->button_pick_color_font_color, SIGNAL(clicked()), colorPickerFontColor, SLOT(open())); 50 | connect(colorPickerFontColor, SIGNAL(colorSelected(QColor)), this, SLOT(setSubFontColor(QColor))); 51 | 52 | // Border color dialog 53 | connect(ui->button_pick_color_border_color, SIGNAL(clicked()), colorPickerBorderColor, SLOT(open())); 54 | connect(colorPickerBorderColor, SIGNAL(colorSelected(QColor)), this, SLOT(setSubBorderColor(QColor))); 55 | 56 | // Shadow color dialog. 57 | connect(ui->button_pick_color_shadow_color, SIGNAL(clicked()), colorPickerShadowColor, SLOT(open())); 58 | connect(colorPickerShadowColor, SIGNAL(colorSelected(QColor)), this, SLOT(setSubShadowColor(QColor))); 59 | 60 | connect(ui->horizontalSlider_sub_text_font_border_size, SIGNAL(valueChanged(int)), this, SLOT(updateTestText(int))); 61 | connect(ui->horizontalSlider_sub_text_font_size, SIGNAL(valueChanged(int)), this, SLOT(updateTestText(int))); 62 | connect(ui->horizontalSlider_sub_text_font_shadow_offset, SIGNAL(valueChanged(int)), this, SLOT(updateTestText(int))); 63 | 64 | subtitleScene = new QGraphicsScene(this); 65 | ui->subtitle_test_graphics_view->setScene(subtitleScene); 66 | testSubtitle = new QGraphicsSimpleTextItem(); 67 | testSubtitle->setText("I am a special little subtitle."); 68 | testShadow = new QGraphicsDropShadowEffect(); 69 | updateTestText(0); // Updates the shown subtitle in the GraphicsScene. 70 | subtitleScene->addItem(testSubtitle); 71 | //subtitleScene->setSceneRect(0,0,700,100); // Very specific boundaries. Should maybe fix? 72 | } 73 | 74 | void tabsubtitle::parseToConf(QStringList* conf){ 75 | conf->append("\n# Subtitle settings"); 76 | for(auto & it : *subtitleSettings) { 77 | if(it->getSettingStatus()){ 78 | if(it->getType().compare("checkbox") == 0) 79 | conf->append(it->getName()); 80 | else 81 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 82 | } 83 | } 84 | } 85 | 86 | void tabsubtitle::addSubtitleSetting(QCheckBox* box) { 87 | subtitleSettings->push_back(new setting(box, manualPages)); 88 | } 89 | 90 | void tabsubtitle::addSubtitleSetting(QComboBox* comboBox, QCheckBox* box) { 91 | subtitleSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 92 | } 93 | 94 | void tabsubtitle::addSubtitleSetting(QLineEdit* valueBox, QCheckBox* box) { 95 | subtitleSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 96 | } 97 | 98 | void tabsubtitle::addSubtitleSetting(QSlider* slider, QLabel* valueCounter, int divideBy, QCheckBox* box) { 99 | subtitleSettings->push_back(new sliderSetting(slider, valueCounter, divideBy, box, manualPages)); 100 | } 101 | 102 | // Subtitle viewer methods 103 | 104 | void tabsubtitle::setSubFontColor(QColor i){ 105 | fontColor = i; 106 | ui->value_sub_text_font_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 107 | updateTestText(0); 108 | } 109 | 110 | void tabsubtitle::setSubBorderColor(QColor i){ 111 | borderColor = i; 112 | ui->value_sub_text_border_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 113 | updateTestText(0); 114 | } 115 | 116 | void tabsubtitle::setSubShadowColor(QColor i){ 117 | shadowColor = i; 118 | ui->value_sub_text_shadow_color->setText(QString('"').append(i.name(QColor::HexArgb)).append('"')); 119 | updateTestText(0); 120 | } 121 | 122 | void tabsubtitle::updateTestText(int i){ 123 | QFont newFont; 124 | newFont.setFamily(ui->fontComboBox_sub_text_font->currentText()); 125 | newFont.setPointSize(ui->horizontalSlider_sub_text_font_size->value()); 126 | if(newFont.pointSize() > 90) 127 | testSubtitle->setText("I am a special BIG subtitle."); 128 | else 129 | testSubtitle->setText("I am a special little subtitle."); 130 | QBrush borderBrush(fontColor); 131 | QPen borderPen(borderColor); 132 | borderPen.setWidth(ui->horizontalSlider_sub_text_font_border_size->value()); 133 | borderPen.setStyle(Qt::SolidLine); 134 | testSubtitle->setFont(newFont); 135 | testSubtitle->setPen(borderPen); 136 | testSubtitle->setBrush(borderBrush); 137 | if(ui->horizontalSlider_sub_text_font_shadow_offset->value() != 0){ 138 | testShadow->setColor(shadowColor); 139 | testShadow->setOffset(ui->horizontalSlider_sub_text_font_shadow_offset->value()); 140 | testSubtitle->setGraphicsEffect(testShadow); 141 | } 142 | else 143 | testShadow->setColor(QColor("black")); 144 | } 145 | 146 | void tabsubtitle::applyFromReadConf(QMap* conf){ 147 | for(auto & readSetting : conf->keys()) { 148 | for(auto & it : *subtitleSettings){ 149 | if(readSetting.compare(it->getName()) == 0){ 150 | it->getCheckBox()->setChecked(true); 151 | if(it->getType().compare("combobox") == 0){ 152 | comboboxSetting* tempBox = (comboboxSetting*)it; 153 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 154 | } 155 | else if(it->getType().compare("valuebox") == 0){ 156 | valueboxSetting* tempBox = (valueboxSetting*)it; 157 | tempBox->getValueBox()->setText(conf->value(readSetting)); 158 | } 159 | else if(it->getType().compare("slider") == 0){ 160 | sliderSetting* tempBox = (sliderSetting*)it; 161 | tempBox->getSlider()->setValue((conf->value(readSetting).toFloat()*tempBox->getDivideBy())); // Sets slider's position properly. 162 | tempBox->updateShownValue(tempBox->getSlider()->value()); // Needed to set the label's proper value. 163 | } 164 | conf->remove(readSetting); // To find unknown settings added by user 165 | } 166 | } 167 | } 168 | fontColor.setNamedColor(ui->value_sub_text_font_color->text().remove('"')); // Removes the quotes required for the config. 169 | setSubFontColor(fontColor); // Converts the hex into a QColor. 170 | borderColor.setNamedColor(ui->value_sub_text_border_color->text().remove('"')); 171 | setSubBorderColor(borderColor); 172 | shadowColor.setNamedColor(ui->value_sub_text_shadow_color->text().remove('"')); 173 | setSubShadowColor(shadowColor); 174 | } 175 | 176 | tabsubtitle::~tabsubtitle() 177 | { 178 | delete subtitleSettings; 179 | delete manualPages; 180 | delete colorPickerFontColor; 181 | delete colorPickerBorderColor; 182 | delete colorPickerShadowColor; 183 | delete testShadow; 184 | delete testSubtitle; 185 | delete subtitleScene; 186 | delete ui; 187 | } 188 | -------------------------------------------------------------------------------- /src/mainwindow.cpp: -------------------------------------------------------------------------------- 1 | #include "mainwindow.hpp" 2 | #include "ui_mainwindow.h" 3 | 4 | MainWindow::MainWindow(QWidget *parent) : 5 | QMainWindow(parent), 6 | ui(new Ui::MainWindow) 7 | { 8 | ui->setupUi(this); 9 | 10 | // Needs to be initialized for parseFullConf. 11 | tabConfig = new tabconfig(); 12 | tabvideo = new tabVideo(); 13 | tabAudio = new tabaudio(); 14 | tabSubtitle = new tabsubtitle(); 15 | tabOSC = new tabosc(); 16 | tabOSD = new tabosd(); 17 | tabscreenshot = new tabScreenshot(); 18 | tabwindow = new tabWindow(); 19 | tabmisc = new tabMisc(); 20 | tabextensions = new tabExtensions(); 21 | tabunknown = new unknownsettingstab(); 22 | 23 | ui->tabWidget->addTab(tabConfig, "Config"); 24 | ui->tabWidget->addTab(tabvideo, "Video"); 25 | ui->tabWidget->addTab(tabAudio, "Audio"); 26 | ui->tabWidget->addTab(tabSubtitle, "Subtitles"); 27 | ui->tabWidget->addTab(tabOSC, "OSC"); 28 | ui->tabWidget->addTab(tabOSD, "OSD"); 29 | ui->tabWidget->addTab(tabscreenshot, "Screenshots"); 30 | ui->tabWidget->addTab(tabwindow, "Window"); 31 | ui->tabWidget->addTab(tabmisc, "Misc"); 32 | ui->tabWidget->addTab(tabextensions, "Extensions"); 33 | ui->tabWidget->addTab(tabunknown, "Unknown Settings"); 34 | ui->tabWidget->setStyleSheet("QTabBar::tab:hover { color: black; background: #e3e3e3 }" 35 | "QTabBar::tab:selected { color: white; background: #722b72; }"); // Purple tab color. 36 | setWindowTitle("mpv Configurator Beta 0.2"); 37 | connect(ui->actionNew, SIGNAL(triggered(bool)), this, SLOT(deleteAllSettings(bool))); 38 | connect(ui->actionOpen_2, SIGNAL(triggered()), this, SLOT(readFullConf())); 39 | connect(ui->actionSave_2, SIGNAL(triggered()), this, SLOT(parseFullConf())); 40 | connect(ui->actionSave_as_2, SIGNAL(triggered()), this, SLOT(saveAs())); 41 | connect(ui->action_Bar_Exit, SIGNAL(triggered()), this, SLOT(messageClose())); 42 | savedConf = new QFile(); 43 | 44 | windowSettings = new QSettings(); // Needs to be to new to be called from destructor. 45 | QByteArray tempArray = windowSettings->value("state/window/geometry").toByteArray(); 46 | if (!tempArray.isEmpty()) { 47 | this->restoreGeometry(tempArray); 48 | } 49 | } 50 | 51 | void MainWindow::deleteAllSettings(bool withMessage){ 52 | if(!withMessage){ // Ask before delete 53 | QMessageBox msgBox; 54 | msgBox.setText("All settings will be discarded."); 55 | msgBox.setInformativeText("Are you sure you want to start on a new config?"); 56 | msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); 57 | msgBox.setDefaultButton(QMessageBox::No); 58 | int answer = msgBox.exec(); 59 | if(answer == QMessageBox::No) 60 | return; 61 | } 62 | 63 | ui->tabWidget->clear(); 64 | 65 | delete tabAudio; delete tabConfig; delete tabextensions; 66 | delete tabmisc; delete tabOSC; delete tabOSD; delete tabscreenshot; 67 | delete tabSubtitle; delete tabunknown; delete tabvideo; delete tabwindow; 68 | 69 | tabConfig = new tabconfig(); 70 | tabvideo = new tabVideo(); 71 | tabAudio = new tabaudio(); 72 | tabSubtitle = new tabsubtitle(); 73 | tabOSC = new tabosc(); 74 | tabOSD = new tabosd(); 75 | tabscreenshot = new tabScreenshot(); 76 | tabwindow = new tabWindow(); 77 | tabmisc = new tabMisc(); 78 | tabextensions = new tabExtensions(); 79 | tabunknown = new unknownsettingstab(); 80 | 81 | ui->tabWidget->addTab(tabConfig, "Config"); 82 | ui->tabWidget->addTab(tabvideo, "Video"); 83 | ui->tabWidget->addTab(tabAudio, "Audio"); 84 | ui->tabWidget->addTab(tabSubtitle, "Subtitles"); 85 | ui->tabWidget->addTab(tabOSC, "OSC"); 86 | ui->tabWidget->addTab(tabOSD, "OSD"); 87 | ui->tabWidget->addTab(tabscreenshot, "Screenshots"); 88 | ui->tabWidget->addTab(tabwindow, "Window"); 89 | ui->tabWidget->addTab(tabmisc, "Misc"); 90 | ui->tabWidget->addTab(tabextensions, "Extensions"); 91 | ui->tabWidget->addTab(tabunknown, "Unknown Settings"); 92 | } 93 | 94 | void MainWindow::saveAs(){ 95 | if(savedConf->exists()) 96 | savedConf->setFileName(""); // Clear current path 97 | parseFullConf(); 98 | } 99 | 100 | void MainWindow::messageClose(){ 101 | QMessageBox closingMessage; 102 | closingMessage.setText("Do you want to save before exiting?"); 103 | closingMessage.setStandardButtons(QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel); 104 | closingMessage.setDefaultButton(QMessageBox::Cancel); 105 | int answer = closingMessage.exec(); 106 | if(answer == QMessageBox::Yes){ 107 | saveAs(); 108 | } 109 | else if(answer == QMessageBox::Cancel){ 110 | return; 111 | } 112 | this->close(); 113 | } 114 | 115 | // Saves the config to a file. 116 | void MainWindow::parseFullConf(){ 117 | QStringList conf; 118 | tabvideo->parseToConf(&conf); 119 | tabAudio->parseToConf(&conf); 120 | tabSubtitle->parseToConf(&conf); 121 | tabOSC->parseToConf(&conf); 122 | tabOSD->parseToConf(&conf); 123 | tabscreenshot->parseToConf(&conf); 124 | tabwindow->parseToConf(&conf); 125 | tabmisc->parseToConf(&conf); 126 | tabunknown->parseToConf(&conf); 127 | tabextensions->parseToConf(&conf); 128 | 129 | if(!savedConf->exists()){ 130 | QFileDialog saveDialog; 131 | QString filename = saveDialog.getSaveFileName(this, 132 | tr("Please choose a save location..."), QDir::homePath() , tr("conf files (*.conf)")); 133 | if(filename.isNull()){ 134 | return; 135 | } 136 | savedConf = new QFile(filename); 137 | } 138 | if (!savedConf->open(QFile::WriteOnly | QFile::Text)) { 139 | QMessageBox msg; 140 | msg.setText("ERROR: COULD NOT READ FILE. CORRUPTED?"); 141 | savedConf->close(); 142 | delete savedConf; 143 | return; 144 | } 145 | else { 146 | QTextStream out(savedConf); 147 | for(auto & it : conf){ 148 | out << it << "\n"; 149 | } 150 | savedConf->close(); 151 | } 152 | 153 | } 154 | 155 | // Reads the config from a file. 156 | void MainWindow::readFullConf(){ 157 | QMap confMap; 158 | QFileDialog openDialog; 159 | QString fileName = openDialog.getOpenFileName(this, tr("Please choose a mpv.conf file."), QDir::homePath(), tr("conf files (*.conf)")); 160 | if(fileName.isNull()) 161 | return; 162 | savedConf->setFileName(fileName); 163 | if(!savedConf->open(QFile::ReadOnly | QFile::Text)) { 164 | QMessageBox msg; 165 | msg.setText("ERROR: COULD NOT READ FILE. CORRUPTED?"); 166 | savedConf->close(); 167 | delete savedConf; 168 | return; 169 | } 170 | else{ 171 | deleteAllSettings(true); 172 | QTextStream in(savedConf); 173 | QString line; 174 | while (!in.atEnd() && !line.startsWith("[extension")) { 175 | if(line.startsWith("#") || line.isEmpty() || line.startsWith("\n")){ 176 | // Ignore comments 177 | } 178 | else if(line.startsWith("vo=")){ // Override for vo= line 179 | tabvideo->readVOLine(line); 180 | } 181 | else if(line.startsWith("ao=")){ // Override for ao= line 182 | tabAudio->readAOLine(line); 183 | } 184 | else if(line.startsWith("script-opts") || line.startsWith("no-osc")){ // Override for OSC settings 185 | tabOSC->readFromConf(line); 186 | } 187 | else if(line.startsWith("ass-force-style")){ // Override for ass-force-style 188 | QString style = line.section("", 17); // This is due to style settings can have = in the value. 189 | confMap.insert("ass-force-style", style); // For example: Kerning=Yes 190 | } 191 | else if(line.contains(QRegularExpression(".*=.*"))){ // Normal setting with value. 192 | QStringList splitLine = line.split("="); 193 | confMap.insert(splitLine.first(), splitLine.last()); 194 | } 195 | else{ // Setting without a value. 196 | confMap.insert(line, ""); 197 | } 198 | line = in.readLine(); // Read instead of first to break while when extensions arrive. 199 | } 200 | 201 | // Read every extension the user has added. 202 | while(!in.atEnd()){ 203 | if(line.startsWith("[extension")){ 204 | QString extensionName = line.remove("[extension").remove("]"); 205 | QStringList extensionSettings; 206 | line = in.readLine(); // Skip to the next line since current is still [extension]. 207 | while(!in.atEnd() && !line.startsWith("[extension")){ // Read all the settings until a new extension appears, or the conf is at the end. 208 | extensionSettings.append(line); 209 | line = in.readLine(); 210 | } 211 | tabextensions->readExtensions(extensionName, extensionSettings); // Add those settings to the extensions tab. 212 | } 213 | else 214 | line = in.readLine(); 215 | } 216 | } 217 | tabvideo->applyFromReadConf(&confMap); 218 | tabAudio->applyFromReadConf(&confMap); 219 | tabSubtitle->applyFromReadConf(&confMap); 220 | tabOSD->applyFromReadConf(&confMap); 221 | tabmisc->applyFromReadConf(&confMap); 222 | tabscreenshot->applyFromReadConf(&confMap); 223 | tabwindow->applyFromReadConf(&confMap); 224 | tabunknown->applyFromReadConf(&confMap); 225 | savedConf->close(); 226 | } 227 | 228 | MainWindow::~MainWindow() 229 | { 230 | windowSettings->setValue("state/window/geometry", this->saveGeometry()); 231 | // Cannot be comma'd due to operator precedence. 232 | delete tabAudio; delete tabConfig; delete tabextensions; 233 | delete tabmisc; delete tabOSC; delete tabOSD; delete tabscreenshot; 234 | delete tabSubtitle; delete tabunknown; delete tabvideo; delete tabwindow; 235 | delete savedConf; 236 | delete ui; 237 | } 238 | -------------------------------------------------------------------------------- /src/tabvideo.cpp: -------------------------------------------------------------------------------- 1 | #include "tabvideo.hpp" 2 | #include "ui_tabvideo.h" 3 | 4 | tabVideo::tabVideo(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabVideo) 7 | { 8 | ui->setupUi(this); 9 | ui->video_settings_direct3d->hide(); 10 | ui->video_settings_opengl->hide(); 11 | voSettings = new std::vector(); 12 | videoSettings = new std::vector(); 13 | manualPages = new QStringList(); 14 | manualPages->append(":/man/options.rst"); 15 | manualPages->append(":/man/vf.rst"); 16 | manualPages->append(":/man/vo.rst"); 17 | 18 | connect(ui->radio_preset_opengl, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 19 | connect(ui->radio_preset_openglhq, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 20 | connect(ui->radio_preset_direct3d, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 21 | connect(ui->radio_preset_direct3d_shaders, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 22 | connect(ui->button_browse_source_shader, SIGNAL(clicked()), this, SLOT(browseForShader())); 23 | connect(ui->button_browse_icc_profile, SIGNAL(clicked()), this, SLOT(browseForICC())); 24 | 25 | // VO settings. 26 | addVOSetting(ui->scaler_combobox, ui->box_scale); 27 | addVOSetting(ui->dscale_combobox, ui->box_dscale); 28 | addVOSetting(ui->cscale_combobox, ui->box_cscale); 29 | addVOSetting(ui->tscale_combobox, ui->box_tscale); 30 | addVOSetting(ui->value_scale_radius, ui->box_scale_radius); 31 | addVOSetting(ui->value_scale_antiring, ui->box_scale_antiring); 32 | addVOSetting(ui->box_scale_resizes_only); 33 | addVOSetting(ui->box_fancy_downscaling); 34 | addVOSetting(ui->box_pbo); 35 | addVOSetting(ui->value_dither_depth, ui->box_dither_depth); 36 | addVOSetting(ui->box_temporal_dither); 37 | addVOSetting(ui->box_interpolation); 38 | addVOSetting(ui->box_waitvsync); 39 | addVOSetting(ui->value_gamma, ui->box_gamma); 40 | addVOSetting(ui->box_gamma_auto); 41 | addVOSetting(ui->target_prim_combobox, ui->box_target_prim); 42 | addVOSetting(ui->value_icc_profile, ui->box_icc_profile); 43 | addVOSetting(ui->box_icc_profile_auto); 44 | addVOSetting(ui->fbo_format_combobox, ui->box_fbo_format); 45 | addVOSetting(ui->value_source_shader, ui->box_source_shader); 46 | 47 | // Direct3D VO 48 | addVOSetting(ui->box_prefer_stretchrect); 49 | addVOSetting(ui->box_disablestretchrect); 50 | addVOSetting(ui->box_disable_textures); 51 | addVOSetting(ui->box_disable_shaders); 52 | addVOSetting(ui->box_only_8_bit); 53 | addVOSetting(ui->box_disable_texture_align); 54 | addVOSetting(ui->box_force_power_of_2); 55 | addVOSetting(ui->texture_memory_combobox, ui->box_texture_memory); 56 | 57 | // Video settings - Not connected to the vo=opengl:settings:here. 58 | addVideoSetting(ui->framedrop_combobox, ui->box_framedrop_mode); 59 | addVideoSetting(ui->deinterlace_combobox, ui->box_deinterlace); 60 | addVideoSetting(ui->fielddominance_combobox, ui->box_fielddominance); 61 | addVideoSetting(ui->value_video_aspect, ui->box_video_aspect); 62 | addVideoSetting(ui->box_no_video_aspect_2); 63 | addVideoSetting(ui->value_video_stereo_mode, ui->box_video_stereo_mode); 64 | addVideoSetting(ui->value_display_fps, ui->box_display_fps); 65 | addVideoSetting(ui->hwdec_combobox, ui->box_hwdec); 66 | addVideoSetting(ui->value_panscan, ui->box_panscan); 67 | } 68 | 69 | // VO Settings. These will connect to parseVOSetting to update the "VO String" 70 | // box at the top of the widget. 71 | void tabVideo::addVOSetting(QCheckBox* box) { 72 | voSettings->push_back(new setting(box, manualPages)); 73 | connect(box, SIGNAL(clicked()), this, SLOT(parseVOSettings())); 74 | } 75 | 76 | void tabVideo::addVOSetting(QComboBox* comboBox, QCheckBox* box) { 77 | voSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 78 | connect(box, SIGNAL(clicked()), this, SLOT(parseVOSettings())); 79 | connect(comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(parseVOSettings(QString))); 80 | } 81 | 82 | void tabVideo::addVOSetting(QLineEdit* valueBox, QCheckBox* box) { 83 | voSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 84 | connect(box, SIGNAL(clicked()), this, SLOT(parseVOSettings())); 85 | connect(valueBox, SIGNAL(editingFinished()), this, SLOT(parseVOSettings())); 86 | } 87 | 88 | // Video settings not in VO. 89 | // These are not connected to parseVOSettings, which means they won't update the VO string. 90 | void tabVideo::addVideoSetting(QCheckBox* box) { 91 | videoSettings->push_back(new setting(box, manualPages)); 92 | } 93 | 94 | void tabVideo::addVideoSetting(QComboBox* comboBox, QCheckBox* box) { 95 | videoSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 96 | } 97 | 98 | void tabVideo::addVideoSetting(QLineEdit* valueBox, QCheckBox* box) { 99 | videoSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 100 | } 101 | 102 | 103 | // Changed to QStringList with join instead of regex manipulation with replace. Fuck regex with a stick. 104 | 105 | void tabVideo::parseVOSettings(){ 106 | QStringList tempVO; 107 | tempVO.append(""); // Empty insert to create seperator between driver and first option if any option is chosen. 108 | for (auto & it : *voSettings) { 109 | if(it->getSettingStatus()){ 110 | if(it->getType().compare("checkbox") == 0) 111 | tempVO.append(it->getName()); 112 | else 113 | tempVO.append(it->getName().append("=").append(it->getValue())); 114 | } 115 | } 116 | if(!tempVO.isEmpty()) 117 | ui->textEdit->setText(QString(vo).append(tempVO.join(":"))); 118 | else 119 | ui->textEdit->setText(vo); 120 | } 121 | 122 | 123 | // Only here to satifsy combobox SLOT requirements. Easier than using a signal mapper. 124 | void tabVideo::parseVOSettings(QString becauseFuckSlots){ 125 | parseVOSettings(); 126 | } 127 | 128 | void tabVideo::parseToConf(QStringList* conf){ 129 | parseVOSettings(); 130 | conf->append("# Video settings"); 131 | conf->append(ui->textEdit->toPlainText()); 132 | for(auto & it : *videoSettings) { 133 | if(it->getSettingStatus()){ 134 | if(it->getType().compare("checkbox") == 0) 135 | conf->append(it->getName()); 136 | else 137 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 138 | } 139 | } 140 | } 141 | 142 | // Bool parameter is dummy to satisfy slot requirements. 143 | // This changes the driver to another oen, clearing the settings if opengl<->direct3d, but only replaces if opengl<->opengl-hq 144 | void tabVideo::changeDriver(bool slotnecessity){ 145 | QString newDriver; 146 | if(ui->radio_preset_openglhq->isChecked()) 147 | newDriver = "opengl-hq"; 148 | else if(ui->radio_preset_direct3d->isChecked()) 149 | newDriver = "direct3d"; 150 | else if(ui->radio_preset_direct3d_shaders->isChecked()) 151 | newDriver = "direct3d_shaders"; 152 | else 153 | newDriver = "opengl"; 154 | 155 | // Clears the string and unchecks all VO boxes if you change from opengl to direct3d or vice versa. 156 | if((vo.contains(QRegularExpression("vo=opengl.*")) && newDriver.contains(QRegularExpression("direct.*"))) || 157 | (vo.contains(QRegularExpression("vo=direct.*")) && newDriver.contains(QRegularExpression("opengl.*")))){ 158 | for(auto & it : *voSettings) { 159 | it->getCheckBox()->setChecked(false); 160 | it->toggleSetting(false); 161 | } 162 | vo="vo="; 163 | } 164 | 165 | // Checks if it still is direct3d or opengl, if so replace. If not append. 166 | if(vo.contains(QRegularExpression(QString("vo=").append("(opengl.*)|(direct3d.*)")))){ 167 | ui->textEdit->setText(ui->textEdit->toPlainText().replace(QRegularExpression(QRegularExpression(QString("vo=").append( 168 | "((opengl-hq)|(opengl)|(direct3d_shaders)|(direct3d))"))), QString("vo=").append(newDriver))); 169 | } 170 | else{ 171 | vo.append(newDriver); 172 | ui->textEdit->setText(vo); 173 | } 174 | } 175 | 176 | // File dialog for GLSL shader. 177 | void tabVideo::browseForShader(){ 178 | QString shader = QFileDialog::getOpenFileName(this, 179 | tr("Please choose a shader file."), QDir::homePath(), tr("GLSL files (*.glsl)")); 180 | ui->value_source_shader->setText(QString('"').append(shader).append('"')); 181 | parseVOSettings(); 182 | } 183 | 184 | // File dialog for ICC profile. 185 | void tabVideo::browseForICC(){ 186 | QString shader = QFileDialog::getOpenFileName(this, 187 | tr("Please choose an ICC profile."), QDir::homePath(), tr("ICC files (*.icc)")); 188 | ui->value_icc_profile->setText(QString('"').append(shader).append('"')); 189 | parseVOSettings(); 190 | } 191 | 192 | void tabVideo::applyFromReadConf(QMap* conf){ 193 | for(auto & readSetting : conf->keys()) { 194 | for(auto & it : *videoSettings){ 195 | if(readSetting.compare(it->getName()) == 0){ 196 | it->getCheckBox()->setChecked(true); 197 | if(it->getType().compare("combobox") == 0){ 198 | comboboxSetting* tempBox = (comboboxSetting*)it; 199 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 200 | } 201 | else if(it->getType().compare("valuebox") == 0){ 202 | valueboxSetting* tempBox = (valueboxSetting*)it; 203 | tempBox->getValueBox()->setText(conf->value(readSetting)); 204 | } 205 | conf->remove(readSetting); // To find unknown settings added by user 206 | } 207 | } 208 | 209 | // Reading VO settings. 210 | for(auto & it : *voSettings){ 211 | if(readSetting.compare(it->getName()) == 0){ 212 | it->getCheckBox()->setChecked(true); 213 | if(it->getType().compare("combobox") == 0){ 214 | comboboxSetting* tempBox = (comboboxSetting*)it; 215 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 216 | } 217 | else if(it->getType().compare("valuebox") == 0){ 218 | valueboxSetting* tempBox = (valueboxSetting*)it; 219 | tempBox->getValueBox()->setText(conf->value(readSetting)); 220 | } 221 | conf->remove(readSetting); // To find unknown settings added by user 222 | } 223 | } 224 | } 225 | } 226 | 227 | void tabVideo::readVOLine(QString readVO){ 228 | readVO = readVO.replace(QRegularExpression("vo="), ""); // Remove vo= because it makes it easier to read. 229 | if(readVO.startsWith("opengl-hq")){ 230 | readVO = readVO.replace(QRegularExpression("opengl-hq"), ""); 231 | ui->radio_preset_openglhq->setChecked(true); 232 | } 233 | else if(readVO.startsWith("direct3d-shaders")){ 234 | readVO = readVO.replace(QRegularExpression("direct3d-shaders"), ""); 235 | ui->radio_preset_direct3d_shaders->setChecked(true); 236 | } 237 | else if(readVO.startsWith("direct3d")){ 238 | readVO = readVO.replace(QRegularExpression("direct3d"), ""); 239 | ui->radio_preset_direct3d->setChecked(true); 240 | } 241 | else{ 242 | readVO = readVO.replace(QRegularExpression("opengl"), ""); 243 | ui->radio_preset_opengl->setChecked(true); 244 | } 245 | 246 | QMap mappedVO; 247 | QStringList splittedVO = readVO.split(":"); 248 | for(auto & voset : splittedVO){ 249 | if(voset.contains(QRegularExpression("="))){ 250 | QStringList furtherSplit = voset.split("="); 251 | mappedVO.insert(furtherSplit.first(), furtherSplit.back()); 252 | } 253 | else 254 | mappedVO.insert(voset, ""); 255 | } 256 | applyFromReadConf(&mappedVO); 257 | if(!mappedVO.isEmpty()){ // Add unknown custom settings added by user to VO. 258 | for(auto & readSetting : mappedVO.keys()) { 259 | if(mappedVO.value(readSetting).isEmpty()) 260 | vo.append(readSetting); 261 | else 262 | vo.append(readSetting).append("=").append(mappedVO.value(readSetting)); 263 | } 264 | } 265 | parseVOSettings(); 266 | } 267 | 268 | tabVideo::~tabVideo() { 269 | delete voSettings; 270 | delete videoSettings; 271 | delete manualPages; 272 | delete ui; 273 | } 274 | -------------------------------------------------------------------------------- /src/tabaudio.cpp: -------------------------------------------------------------------------------- 1 | #include "tabaudio.hpp" 2 | #include "ui_tabaudio.h" 3 | 4 | tabaudio::tabaudio(QWidget *parent) : 5 | QWidget(parent), 6 | ui(new Ui::tabaudio) 7 | { 8 | ui->setupUi(this); 9 | ui->alsa_settings->hide(); 10 | ui->coreaudio_settings->hide(); 11 | ui->dsound_settings->hide(); 12 | ui->pulseaudio_settings->hide(); 13 | ui->jack_settings->hide(); 14 | ui->oss_settings->hide(); 15 | manualPages = new QStringList(); 16 | manualPages->append(":/man/options.rst"); 17 | manualPages->append(":/man/af.rst"); 18 | manualPages->append(":/man/ao.rst"); 19 | audioSettings = new std::vector(); 20 | aoSettings = new std::vector(); 21 | 22 | // Connect all radio buttons to clear a VO setting if the driver is changed. 23 | connect(ui->radio_preset_alsa, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 24 | connect(ui->radio_preset_auto, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 25 | connect(ui->radio_preset_coreaudio, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 26 | connect(ui->radio_preset_dsound, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 27 | connect(ui->radio_preset_jack, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 28 | connect(ui->radio_preset_oss, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 29 | connect(ui->radio_preset_pulse, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 30 | connect(ui->radio_preset_wasapi, SIGNAL(clicked(bool)), this, SLOT(changeDriver(bool))); 31 | 32 | // General settings. 33 | addAudioSetting(ui->comboBox_audio_pitch, ui->box_audio_pitch_correction); 34 | addAudioSetting(ui->value_audio_device, ui->box_audio_device); 35 | addAudioSetting(ui->value_volume, ui->box_volume); 36 | addAudioSetting(ui->value_audio_delay, ui->box_audio_delay); 37 | addAudioSetting(ui->comboBox_mute, ui->box_mute); 38 | addAudioSetting(ui->comboBox_softvol, ui->box_softvol); 39 | addAudioSetting(ui->box_no_softvol); 40 | addAudioSetting(ui->value_softvol_max, ui->box_softvol_max); 41 | addAudioSetting(ui->value_audio_demuxer, ui->box_audio_demuxer); 42 | addAudioSetting(ui->box_ad_lavc_downmix); 43 | addAudioSetting(ui->comboBox_lavc_threads, ui->box_ad_lavc_threads); 44 | addAudioSetting(ui->value_audio_channels, ui->box_audio_channels); 45 | addAudioSetting(ui->comboBox_audio_display, ui->box_audio_display); 46 | addAudioSetting(ui->comboBox_gapless_audio, ui->box_gapless_audio); 47 | addAudioSetting(ui->box_initial_audio_sync); 48 | addAudioSetting(ui->box_no_initial_audio_sync); 49 | addAudioSetting(ui->value_audio_buffer, ui->box_audio_buffer); 50 | addAudioSetting(ui->valuebox_alang, ui->box_alang); 51 | 52 | // alsa settings 53 | addAOSetting(ui->value_device, ui->box_device); 54 | addAOSetting(ui->comboBox_resample_alsa, ui->box_resample); 55 | addAOSetting(ui->value_mixer_device, ui->box_mixer_device); 56 | addAOSetting(ui->box_non_interleaved); 57 | 58 | // OSS settings 59 | addAOSetting(ui->value_dsp_device, ui->box_dsp_device); 60 | addAOSetting(ui->value_mixer_channel, ui->box_mixer_channel); 61 | 62 | // JACK settings 63 | addAOSetting(ui->value_jack_port, ui->box_jack_port); 64 | addAOSetting(ui->value_name_client, ui->box_name_client); 65 | addAOSetting(ui->box_autostart); 66 | addAOSetting(ui->box_connect); 67 | addAOSetting(ui->comboBox_std_channel_layout, ui->box_std_channel_layout); 68 | 69 | // CoreAudio settings 70 | addAOSetting(ui->comboBox_change_physical_format, ui->box_change_physical_format); 71 | addAOSetting(ui->box_exclusive); 72 | 73 | // PulseAudio settings 74 | addAOSetting(ui->value_pulse_buffer, ui->box_pulse_buffer); 75 | addAOSetting(ui->comboBox_latency_hacks, ui->box_latency_hacks); 76 | 77 | // DirectSound setings 78 | addAOSetting(ui->value_dsound_buffer, ui->box_dsound_buffer); 79 | } 80 | 81 | // Audio settings not in AO. 82 | // These are not connected to parseAOSettings, which means they won't update the VO string. 83 | void tabaudio::addAudioSetting(QCheckBox* box) { 84 | audioSettings->push_back(new setting(box, manualPages)); 85 | } 86 | 87 | void tabaudio::addAudioSetting(QComboBox* comboBox, QCheckBox* box) { 88 | audioSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 89 | } 90 | 91 | void tabaudio::addAudioSetting(QLineEdit* valueBox, QCheckBox* box) { 92 | audioSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 93 | } 94 | 95 | // AO Settings. These will connect to parseAOSetting to update the "AO String" 96 | // box at the top of the widget. 97 | void tabaudio::addAOSetting(QCheckBox* box) { 98 | aoSettings->push_back(new setting(box, manualPages)); 99 | connect(box, SIGNAL(clicked()), this, SLOT(parseAOSettings())); 100 | } 101 | 102 | void tabaudio::addAOSetting(QComboBox* comboBox, QCheckBox* box) { 103 | aoSettings->push_back(new comboboxSetting(comboBox, box, manualPages)); 104 | connect(box, SIGNAL(clicked()), this, SLOT(parseAOSettings())); 105 | connect(comboBox, SIGNAL(currentIndexChanged(QString)), this, SLOT(parseAOSettings(QString))); 106 | } 107 | 108 | void tabaudio::addAOSetting(QLineEdit* valueBox, QCheckBox* box) { 109 | aoSettings->push_back(new valueboxSetting(valueBox, box, manualPages)); 110 | connect(box, SIGNAL(clicked()), this, SLOT(parseAOSettings())); 111 | connect(valueBox, SIGNAL(editingFinished()), this, SLOT(parseAOSettings())); 112 | } 113 | 114 | 115 | // Parses all settings to a QStringList. Called from MainWindow. 116 | void tabaudio::parseToConf(QStringList* conf){ 117 | conf->append("\n# Audio settings"); 118 | if(ao.compare("ao=") != 0) 119 | conf->append(ui->textEdit->toPlainText()); 120 | for(auto & it : *audioSettings) { 121 | if(it->getSettingStatus()){ 122 | if(it->getType().compare("checkbox") == 0) 123 | conf->append(it->getName()); 124 | else 125 | conf->append(QString(it->getName()).append("=").append(it->getValue())); 126 | } 127 | } 128 | } 129 | 130 | void tabaudio::parseAOSettings(){ 131 | QStringList aoToBe; 132 | aoToBe.append(""); // Empty insert to create a seperator between driver and first option if any option is chosen. 133 | for (auto & it : *aoSettings) { 134 | if(it->getSettingStatus()){ 135 | if(it->getType().compare("checkbox") == 0) 136 | aoToBe.append(it->getName()); 137 | else 138 | aoToBe.append(it->getName().append("=").append(it->getValue())); 139 | } 140 | } 141 | if(!aoToBe.isEmpty()) 142 | ui->textEdit->setText(QString(ao).append(aoToBe.join(":"))); 143 | else 144 | ui->textEdit->setText(ao); 145 | } 146 | 147 | void tabaudio::parseAOSettings(QString neededToSolveSignalSlot){ 148 | parseAOSettings(); 149 | } 150 | 151 | // Could unfortunatley not use switch case here unless a vector or array of 152 | // each radio button is created which would be more code than this. 153 | 154 | void tabaudio::changeDriver(bool slotnecessity){ 155 | QString newDriver; 156 | if(ui->radio_preset_alsa->isChecked()) 157 | newDriver = "alsa"; 158 | else if(ui->radio_preset_coreaudio->isChecked()) 159 | newDriver = "coreaudio"; 160 | else if(ui->radio_preset_dsound->isChecked()) 161 | newDriver = "dsound"; 162 | else if(ui->radio_preset_jack->isChecked()) 163 | newDriver = "jack"; 164 | else if(ui->radio_preset_oss->isChecked()) 165 | newDriver = "oss"; 166 | else if(ui->radio_preset_pulse->isChecked()) 167 | newDriver = "pulse"; 168 | else if(ui->radio_preset_wasapi->isChecked()) 169 | newDriver = "wasapi"; 170 | else 171 | newDriver = ""; // This is the auto driver. Which is literally nothing. 172 | 173 | // Clears the string and unchecks all AO boxes if you change any driver as they are not compatible. 174 | for(auto & it : *aoSettings) { 175 | it->getCheckBox()->setChecked(false); 176 | it->toggleSetting(false); 177 | } 178 | ao="ao="; 179 | ao.append(newDriver); // No point in replacing the ao= like done in vo because the setting are never compatible. 180 | 181 | ui->textEdit->setText(ao); 182 | } 183 | 184 | void tabaudio::applyFromReadConf(QMap* conf){ 185 | for(auto & readSetting : conf->keys()) { // For each setting in the config 186 | for(auto & it : *audioSettings){ // Search each setting available here 187 | if(readSetting.compare(it->getName()) == 0){ // If checkbox's text and the setting name is identical. 188 | it->getCheckBox()->setChecked(true); // Check the checkbox. 189 | if(it->getType().compare("combobox") == 0){ // If it is a combobox, set the text accordingly. 190 | comboboxSetting* tempBox = (comboboxSetting*)it; 191 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 192 | } 193 | else if(it->getType().compare("valuebox") == 0){ // Or if QEditLine, set the text accordingly. 194 | valueboxSetting* tempBox = (valueboxSetting*)it; 195 | tempBox->getValueBox()->setText(conf->value(readSetting)); 196 | } 197 | conf->remove(readSetting); // To find unknown settings added by user 198 | } 199 | } 200 | 201 | // Reading AO settings. 202 | for(auto & it : *aoSettings){ 203 | if(readSetting.compare(it->getName()) == 0){ 204 | it->getCheckBox()->setChecked(true); 205 | if(it->getType().compare("combobox") == 0){ 206 | comboboxSetting* tempBox = (comboboxSetting*)it; 207 | tempBox->getComboBox()->setCurrentText(conf->value(readSetting)); 208 | } 209 | else if(it->getType().compare("valuebox") == 0){ 210 | valueboxSetting* tempBox = (valueboxSetting*)it; 211 | tempBox->getValueBox()->setText(conf->value(readSetting)); 212 | } 213 | conf->remove(readSetting); 214 | } 215 | } 216 | } 217 | } 218 | 219 | void tabaudio::readAOLine(QString readAO){ 220 | readAO = readAO.replace(QRegularExpression("ao="), ""); 221 | 222 | // Why the fuck doesn't C++ have switch case with string? What is this, 1991? Holy shit this is ugly. Should rewrite. 223 | if(readAO.startsWith("alsa")){ 224 | readAO = readAO.replace(QRegularExpression("alsa"), ""); 225 | ui->radio_preset_alsa->setChecked(true); 226 | } 227 | else if(readAO.startsWith("coreaudio")){ 228 | readAO = readAO.replace(QRegularExpression("coreaudio"), ""); 229 | ui->radio_preset_coreaudio->setChecked(true); 230 | } 231 | else if(readAO.startsWith("dsound")){ 232 | readAO = readAO.replace(QRegularExpression("dsound"), ""); 233 | ui->radio_preset_dsound->setChecked(true); 234 | } 235 | else if(readAO.startsWith("jack")){ 236 | readAO = readAO.replace(QRegularExpression("jack"), ""); 237 | ui->radio_preset_jack->setChecked(true); 238 | } 239 | else if(readAO.startsWith("oss")){ 240 | readAO = readAO.replace(QRegularExpression("oss"), ""); 241 | ui->radio_preset_oss->setChecked(true); 242 | } 243 | else if(readAO.startsWith("pulse")){ 244 | readAO = readAO.replace(QRegularExpression("pulse"), ""); 245 | ui->radio_preset_pulse->setChecked(true); 246 | } 247 | else if(readAO.startsWith("wasapi")){ 248 | readAO = readAO.replace(QRegularExpression("wasapi"), ""); 249 | ui->radio_preset_wasapi->setChecked(true); 250 | } 251 | else 252 | ui->radio_preset_auto->setChecked(true); 253 | changeDriver(true); 254 | QMap mappedAO; 255 | QStringList splittedAO = readAO.split(":"); 256 | for(auto & aoset : splittedAO){ 257 | if(aoset.contains(QRegularExpression("="))){ 258 | QStringList furtherSplit = aoset.split("="); 259 | mappedAO.insert(furtherSplit.first(), furtherSplit.back()); 260 | } 261 | else{ 262 | mappedAO.insert(aoset, ""); 263 | } 264 | } 265 | applyFromReadConf(&mappedAO); 266 | if(!mappedAO.isEmpty()){ // If there are unknown settings, add them last. 267 | for(auto & readSetting : mappedAO.keys()) { 268 | if(mappedAO.value(readSetting).isEmpty()){ 269 | ao.append(readSetting); 270 | } 271 | else{ 272 | ao.append(readSetting).append("=").append(mappedAO.value(readSetting)); 273 | } 274 | } 275 | } 276 | parseAOSettings(); 277 | } 278 | 279 | tabaudio::~tabaudio() 280 | { 281 | delete audioSettings; 282 | delete aoSettings; 283 | delete manualPages; 284 | delete ui; 285 | } 286 | -------------------------------------------------------------------------------- /src/tabconfig.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | tabconfig 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 900 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Form 21 | 22 | 23 | 24 | 120 25 | 26 | 27 | 28 | 29 | Qt::Vertical 30 | 31 | 32 | 33 | 20 34 | 40 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Qt::Vertical 43 | 44 | 45 | 46 | 20 47 | 40 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 56 | 57 | 58 | 30 59 | 60 | 61 | 15 62 | 63 | 64 | 10 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 59 75 | 59 76 | 59 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 59 86 | 59 87 | 59 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 127 97 | 127 98 | 127 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 15 108 | 50 109 | false 110 | false 111 | false 112 | 113 | 114 | 115 | <html><head/><body><p><a href="http://mpv.io/"><span style=" font-size:14pt; text-decoration: none; color:#454545">mpv.io</span></a></p></body></html> 116 | 117 | 118 | Qt::AutoText 119 | 120 | 121 | true 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 150 130 | 0 131 | 132 | 133 | 134 | Qt::Horizontal 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 59 147 | 59 148 | 59 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 59 158 | 59 159 | 59 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 127 169 | 127 170 | 127 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 15 180 | false 181 | 182 | 183 | 184 | <html><head/><body><p><a href="http://mpv.io/manual/master/"><span style=" font-size:14pt; text-decoration: none; color:#454545">mpv Manual</span></a></p></body></html> 185 | 186 | 187 | true 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 59 200 | 59 201 | 59 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 59 211 | 59 212 | 59 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 127 222 | 127 223 | 127 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 15 233 | false 234 | 235 | 236 | 237 | <html><head/><body><p><a href="https://github.com/mpv-player/mpv"><span style=" font-size:14pt; text-decoration: none; color:#454545">mpv GitHub</span></a></p></body></html> 238 | 239 | 240 | true 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 59 253 | 59 254 | 59 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 59 264 | 59 265 | 59 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 127 275 | 127 276 | 127 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 15 286 | false 287 | 288 | 289 | 290 | <html><head/><body><p><a href="https://github.com/mpv-player/mpv/commits/master"><span style=" font-size:14pt; text-decoration: none; color:#454545 ">mpv Change Log</span></a></p></body></html> 291 | 292 | 293 | true 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 150 302 | 0 303 | 304 | 305 | 306 | Qt::Horizontal 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 150 315 | 0 316 | 317 | 318 | 319 | Qt::Horizontal 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 150 328 | 0 329 | 330 | 331 | 332 | Qt::Horizontal 333 | 334 | 335 | 336 | 337 | 338 | 339 | <html><head/><body><p><span style=" font-size:14pt; color:#454545;">&gt;</span></p></body></html> 340 | 341 | 342 | 343 | 344 | 345 | 346 | <html><head/><body><p><span style=" font-size:14pt; color:#454545;">&gt;</span></p></body></html> 347 | 348 | 349 | 350 | 351 | 352 | 353 | <html><head/><body><p><span style=" font-size:14pt; color:#454545;">&gt;</span></p></body></html> 354 | 355 | 356 | 357 | 358 | 359 | 360 | <html><head/><body><p><span style=" font-size:14pt; color:#454545;">&gt;</span></p></body></html> 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | -------------------------------------------------------------------------------- /src/tabwindow.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | tabWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 900 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 21 | 22 | 23 | 30 24 | 25 | 26 | 6 27 | 28 | 29 | 10 30 | 31 | 32 | 33 | 34 | Window settings: 35 | 36 | 37 | 38 | 39 | 40 | 41 | screen 42 | 43 | 44 | 45 | 46 | 47 | 48 | false 49 | 50 | 51 | 52 | 0 53 | 54 | 55 | 56 | 57 | 1 58 | 59 | 60 | 61 | 62 | 2 63 | 64 | 65 | 66 | 67 | 3 68 | 69 | 70 | 71 | 72 | 4 73 | 74 | 75 | 76 | 77 | 5 78 | 79 | 80 | 81 | 82 | 6 83 | 84 | 85 | 86 | 87 | 7 88 | 89 | 90 | 91 | 92 | 8 93 | 94 | 95 | 96 | 97 | 9 98 | 99 | 100 | 101 | 102 | 10 103 | 104 | 105 | 106 | 107 | 11 108 | 109 | 110 | 111 | 112 | 12 113 | 114 | 115 | 116 | 117 | 13 118 | 119 | 120 | 121 | 122 | 14 123 | 124 | 125 | 126 | 127 | 15 128 | 129 | 130 | 131 | 132 | 16 133 | 134 | 135 | 136 | 137 | 17 138 | 139 | 140 | 141 | 142 | 18 143 | 144 | 145 | 146 | 147 | 19 148 | 149 | 150 | 151 | 152 | 20 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | fullscreen 161 | 162 | 163 | 164 | 165 | 166 | 167 | keep-open 168 | 169 | 170 | 171 | 172 | 173 | 174 | false 175 | 176 | 177 | 178 | yes 179 | 180 | 181 | 182 | 183 | no 184 | 185 | 186 | 187 | 188 | always 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | force-window 197 | 198 | 199 | 200 | 201 | 202 | 203 | false 204 | 205 | 206 | 207 | yes 208 | 209 | 210 | 211 | 212 | no 213 | 214 | 215 | 216 | 217 | immediate 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | ontop 226 | 227 | 228 | 229 | 230 | 231 | 232 | no-border 233 | 234 | 235 | 236 | 237 | 238 | 239 | on-all-workspaces 240 | 241 | 242 | 243 | 244 | 245 | 246 | autofit 247 | 248 | 249 | 250 | 251 | 252 | 253 | false 254 | 255 | 256 | 257 | 258 | 259 | 260 | autofit-larger 261 | 262 | 263 | 264 | 265 | 266 | 267 | false 268 | 269 | 270 | 271 | 272 | 273 | 274 | autofit-smaller 275 | 276 | 277 | 278 | 279 | 280 | 281 | false 282 | 283 | 284 | 285 | 286 | 287 | 288 | cursor-autohide 289 | 290 | 291 | 292 | 293 | 294 | 295 | false 296 | 297 | 298 | 299 | number 300 | 301 | 302 | 303 | 304 | no 305 | 306 | 307 | 308 | 309 | always 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | cursor-autohide-fs-only 318 | 319 | 320 | 321 | 322 | 323 | 324 | no-fixed-vo 325 | 326 | 327 | 328 | 329 | 330 | 331 | no-keepaspect 332 | 333 | 334 | 335 | 336 | 337 | 338 | no-keepaspect-window 339 | 340 | 341 | 342 | 343 | 344 | 345 | monitoraspect 346 | 347 | 348 | 349 | 350 | 351 | 352 | false 353 | 354 | 355 | 356 | 357 | 358 | 359 | no-stop-screensaver 360 | 361 | 362 | 363 | 364 | 365 | 366 | no-window-dragging 367 | 368 | 369 | 370 | 371 | 372 | 373 | x11-name 374 | 375 | 376 | 377 | 378 | 379 | 380 | false 381 | 382 | 383 | 384 | 385 | 386 | 387 | x11-netwm 388 | 389 | 390 | 391 | 392 | 393 | 394 | false 395 | 396 | 397 | 398 | auto 399 | 400 | 401 | 402 | 403 | yes 404 | 405 | 406 | 407 | 408 | no 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 150 418 | 0 419 | 420 | 421 | 422 | Qt::Horizontal 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | Qt::Horizontal 432 | 433 | 434 | 435 | 40 436 | 20 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | Qt::Horizontal 445 | 446 | 447 | 448 | 40 449 | 20 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | -------------------------------------------------------------------------------- /src/tabmisc.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | tabMisc 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1000 10 | 900 11 | 12 | 13 | 14 | Form 15 | 16 | 17 | 18 | 19 | 20 | Qt::Vertical 21 | 22 | 23 | 24 | 20 25 | 40 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 34 | 35 | 36 | 30 37 | 38 | 39 | 15 40 | 41 | 42 | 10 43 | 44 | 45 | 46 | 47 | network-timeout 48 | 49 | 50 | 51 | 52 | 53 | 54 | false 55 | 56 | 57 | 58 | 59 | 60 | 61 | hls-bitrate 62 | 63 | 64 | 65 | 66 | 67 | 68 | false 69 | 70 | 71 | true 72 | 73 | 74 | 75 | <rate> 76 | 77 | 78 | 79 | 80 | no 81 | 82 | 83 | 84 | 85 | min 86 | 87 | 88 | 89 | 90 | max 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | Network Settings: 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 108 | 109 | 110 | 30 111 | 112 | 113 | 15 114 | 115 | 116 | 10 117 | 118 | 119 | 120 | 121 | ytdl-format 122 | 123 | 124 | 125 | 126 | 127 | 128 | false 129 | 130 | 131 | true 132 | 133 | 134 | 135 | bestvideo+bestaudio 136 | 137 | 138 | 139 | 140 | 133+bestaudio 141 | 142 | 143 | 144 | 145 | 134+bestaudio 146 | 147 | 148 | 149 | 150 | 135+bestaudio 151 | 152 | 153 | 154 | 155 | 136+bestaudio 156 | 157 | 158 | 159 | 160 | 137+bestaudio 161 | 162 | 163 | 164 | 165 | 138+bestaudio 166 | 167 | 168 | 169 | 170 | 139+bestaudio 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | save-position-on-quit 179 | 180 | 181 | 182 | 183 | 184 | 185 | priority 186 | 187 | 188 | 189 | 190 | 191 | 192 | false 193 | 194 | 195 | 196 | idle 197 | 198 | 199 | 200 | 201 | belownormal 202 | 203 | 204 | 205 | 206 | normal 207 | 208 | 209 | 210 | 211 | abovenormal 212 | 213 | 214 | 215 | 216 | high 217 | 218 | 219 | 220 | 221 | realtime 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | force-seekable 230 | 231 | 232 | 233 | 234 | 235 | 236 | false 237 | 238 | 239 | 240 | yes 241 | 242 | 243 | 244 | 245 | no 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | cdrom-device 254 | 255 | 256 | 257 | 258 | 259 | 260 | false 261 | 262 | 263 | 264 | 265 | 266 | 267 | false 268 | 269 | 270 | Browse... 271 | 272 | 273 | 274 | 275 | 276 | 277 | heartbeat-cmd 278 | 279 | 280 | 281 | 282 | 283 | 284 | false 285 | 286 | 287 | 288 | 289 | 290 | 291 | heartbeat-interval 292 | 293 | 294 | 295 | 296 | 297 | 298 | false 299 | 300 | 301 | 302 | 303 | 304 | 305 | General misc settings: 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter 315 | 316 | 317 | 30 318 | 319 | 320 | 15 321 | 322 | 323 | 10 324 | 325 | 326 | 327 | 328 | cache 329 | 330 | 331 | 332 | 333 | 334 | 335 | false 336 | 337 | 338 | true 339 | 340 | 341 | 342 | auto 343 | 344 | 345 | 346 | 347 | <kBytes> 348 | 349 | 350 | 351 | 352 | yes 353 | 354 | 355 | 356 | 357 | no 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | cache-default 369 | 370 | 371 | 372 | 373 | 374 | 375 | false 376 | 377 | 378 | true 379 | 380 | 381 | 382 | <kBytes> 383 | 384 | 385 | 386 | 387 | no 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | cache-initial 396 | 397 | 398 | 399 | 400 | 401 | 402 | false 403 | 404 | 405 | 406 | 407 | 408 | 409 | cache-seek-min 410 | 411 | 412 | 413 | 414 | 415 | 416 | false 417 | 418 | 419 | 420 | 421 | 422 | 423 | no-cache 424 | 425 | 426 | 427 | 428 | 429 | 430 | cache-secs 431 | 432 | 433 | 434 | 435 | 436 | 437 | false 438 | 439 | 440 | 441 | 442 | 443 | 444 | no-cache-pause 445 | 446 | 447 | 448 | 449 | 450 | 451 | Cache settings: 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | Miscellaneous settings: 461 | 462 | 463 | 464 | 465 | 466 | 467 | Qt::Horizontal 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | box_cdrom_device 477 | toggled(bool) 478 | button_browse_cdrom 479 | setEnabled(bool) 480 | 481 | 482 | 221 483 | 315 484 | 485 | 486 | 389 487 | 356 488 | 489 | 490 | 491 | 492 | 493 | -------------------------------------------------------------------------------- /src/man/ao.rst: -------------------------------------------------------------------------------- 1 | AUDIO OUTPUT DRIVERS 2 | ==================== 3 | 4 | Audio output drivers are interfaces to different audio output facilities. The 5 | syntax is: 6 | 7 | ``--ao=`` 8 | Specify a priority list of audio output drivers to be used. 9 | 10 | If the list has a trailing ',', mpv will fall back on drivers not contained 11 | in the list. Suboptions are optional and can mostly be omitted. 12 | 13 | You can also set defaults for each driver. The defaults are applied before the 14 | normal driver parameters. 15 | 16 | ``--ao-defaults=`` 17 | Set defaults for each driver. 18 | 19 | .. note:: 20 | 21 | See ``--ao=help`` for a list of compiled-in audio output drivers. The 22 | driver ``--ao=alsa`` is preferred. ``--ao=pulse`` is preferred on systems 23 | where PulseAudio is used. On Windows, ``--ao=wasapi`` is preferred, 24 | though it might cause trouble sometimes, in which case ``--ao=dsound`` 25 | should be used. On BSD systems, ``--ao=oss`` or `--ao=sndio`` may work 26 | (the latter being experimental). On OS X systems, use ``--ao=coreaudio``. 27 | 28 | .. admonition:: Examples 29 | 30 | - ``--ao=alsa,oss,`` Try the ALSA driver, then the OSS driver, then others. 31 | - ``--ao=alsa:resample=yes:device=[plughw:0,3]`` Lets ALSA resample and 32 | sets the device-name as first card, fourth device. 33 | 34 | Available audio output drivers are: 35 | 36 | ``alsa`` (Linux only) 37 | ALSA audio output driver 38 | 39 | ``device=`` 40 | Sets the device name. For ac3 output via S/PDIF, use an "iec958" or 41 | "spdif" device, unless you really know how to set it correctly. 42 | ``resample=yes`` 43 | Enable ALSA resampling plugin. (This is disabled by default, because 44 | some drivers report incorrect audio delay in some cases.) 45 | ``mixer-device=`` 46 | Set the mixer device used with ``--no-softvol`` (default: ``default``). 47 | ``mixer-name=`` 48 | Set the name of the mixer element (default: ``Master``). This is for 49 | example ``PCM`` or ``Master``. 50 | ``mixer-index=`` 51 | Set the index of the mixer channel (default: 0). Consider the output of 52 | "``amixer scontrols``", then the index is the number that follows the 53 | name of the element. 54 | ``non-interleaved`` 55 | Allow output of non-interleaved formats (if the audio decoder uses 56 | this format). Currently disabled by default, because some popular 57 | ALSA plugins are utterly broken with non-interleaved formats. 58 | ``ingore-chmap`` 59 | Don't read or set the channel map of the ALSA device - only request the 60 | required number of channels, and then pass the audio as-is to it. This 61 | option most likely should not be used. It can be useful for debugging, 62 | or for static setups with a specially engineered ALSA configuration (in 63 | this case you should always force the same layout with ``--audio-channels``, 64 | or it will work only for files which use the layout implicit to your 65 | ALSA device). 66 | 67 | .. note:: 68 | 69 | MPlayer and mplayer2 required you to replace any ',' with '.' and 70 | any ':' with '=' in the ALSA device name. mpv does not do this anymore. 71 | Instead, quote the device name: 72 | 73 | ``--ao=alsa:device=[plug:surround50]`` 74 | 75 | Note that the ``[`` and ``]`` simply quote the device name. With some 76 | shells (like zsh), you have to quote the option string to prevent the 77 | shell from interpreting the brackets instead of passing them to mpv. 78 | 79 | Actually, you should use the ``--audio-device`` option, instead of 80 | setting the device directly. 81 | 82 | .. warning:: 83 | 84 | Handling of multichannel/surround audio changed in mpv 0.8.0 from the 85 | behavior in MPlayer/mplayer2 and older versions of mpv. 86 | 87 | The old behavior is that the player always downmixed to stereo by 88 | default. The ``--audio-channels`` (or ``--channels`` before that) option 89 | had to be set to get multichannel audio. Then playing stereo would 90 | use the ``default`` device (which typically allows multiple programs 91 | to play audio at the same time via dmix), while playing anything with 92 | more channels would open one of the hardware devices, e.g. via the 93 | ``surround51`` alias (typically with exclusive access). Whether the 94 | player would use exclusive access or not would depend on the file 95 | being played. 96 | 97 | The new behavior since mpv 0.8.0 always enables multichannel audio, 98 | i.e. ``--audio-channels=auto`` is the default. However, since ALSA 99 | provides no good way to play multichannel audio in a non-exclusive 100 | way (without blocking other applications from using audio), the player 101 | is restricted to the capabilities of the ``default`` device by default, 102 | which means it supports only stereo and mono (at least with current 103 | typical ALSA configurations). But if a hardware device is selected, 104 | then multichannel audio will typically work. 105 | 106 | The short story is: if you want multichannel audio with ALSA, use 107 | ``--audio-device`` to select the device (use ``--audio-device=help`` 108 | to get a list of all devices and their mpv name). 109 | 110 | You can also try `using the upmix plugin `_. 111 | This setup enables multichannel audio on the ``default`` device 112 | with automatic upmixing with shared access, so playing stereo 113 | and multichannel audio at the same time will work as expected. 114 | 115 | ``oss`` 116 | OSS audio output driver 117 | 118 | ```` 119 | Sets the audio output device (default: ``/dev/dsp``). 120 | ```` 121 | Sets the audio mixer device (default: ``/dev/mixer``). 122 | ```` 123 | Sets the audio mixer channel (default: ``pcm``). Other valid values 124 | include **vol, pcm, line**. For a complete list of options look for 125 | ``SOUND_DEVICE_NAMES`` in ``/usr/include/linux/soundcard.h``. 126 | 127 | ``jack`` 128 | JACK (Jack Audio Connection Kit) audio output driver 129 | 130 | ``port=`` 131 | Connects to the ports with the given name (default: physical ports). 132 | ``name=`` 133 | Client name that is passed to JACK (default: ``mpv``). Useful 134 | if you want to have certain connections established automatically. 135 | ``(no-)autostart`` 136 | Automatically start jackd if necessary (default: disabled). Note that 137 | this tends to be unreliable and will flood stdout with server messages. 138 | ``(no-)connect`` 139 | Automatically create connections to output ports (default: enabled). 140 | When enabled, the maximum number of output channels will be limited to 141 | the number of available output ports. 142 | ``std-channel-layout=alsa|waveext|any`` 143 | Select the standard channel layout (default: alsa). JACK itself has no 144 | notion of channel layouts (i.e. assigning which speaker a given 145 | channel is supposed to map to) - it just takes whatever the application 146 | outputs, and reroutes it to whatever the user defines. This means the 147 | user and the application are in charge of dealing with the channel 148 | layout. ``alsa`` uses the old MPlayer layout, which is inspired by 149 | ALSA's standard layouts. In this mode, ao_jack will refuse to play 3 150 | or 7 channels (because these do not really have a defined meaning in 151 | MPlayer). ``waveext`` uses WAVE_FORMAT_EXTENSIBLE order, which, even 152 | though it was defined by Microsoft, is the standard on many systems. 153 | The value ``any`` makes JACK accept whatever comes from the audio 154 | filter chain, regardless of channel layout and without reordering. This 155 | mode is probably not very useful, other than for debugging or when used 156 | with fixed setups. 157 | 158 | ``coreaudio`` (Mac OS X only) 159 | Native Mac OS X audio output driver using AudioUnits and the CoreAudio 160 | sound server. 161 | 162 | Automatically redirects to ``coreaudio_exclusive`` when playing compressed 163 | formats. 164 | 165 | ``change-physical-format=`` 166 | Change the physical format to one similar to the requested audio format 167 | (default: no). This has the advantage that multichannel audio output 168 | will actually work. The disadvantage is that it will change the 169 | system-wide audio settings. This is equivalent to changing the ``Format`` 170 | setting in the ``Audio Devices`` dialog in the ``Audio MIDI Setup`` 171 | utility. Note that this does not effect the selected speaker setup. 172 | 173 | ``exclusive`` 174 | Use exclusive mode access. This merely redirects to 175 | ``coreaudio_exclusive``, but should be preferred over using that AO 176 | directly. 177 | 178 | ``coreaudio_exclusive`` (Mac OS X only) 179 | Native Mac OS X audio output driver using direct device access and 180 | exclusive mode (bypasses the sound server). 181 | 182 | ``openal`` 183 | Experimental OpenAL audio output driver 184 | 185 | .. note:: This driver is not very useful. Playing multi-channel audio with 186 | it is slow. 187 | 188 | ``pulse`` 189 | PulseAudio audio output driver 190 | 191 | ``[][:]`` 192 | Specify the host and optionally output sink to use. An empty 193 | string uses a local connection, "localhost" uses network transfer 194 | (most likely not what you want). 195 | 196 | ``buffer=<1-2000|native>`` 197 | Set the audio buffer size in milliseconds. A higher value buffers 198 | more data, and has a lower probability of buffer underruns. A smaller 199 | value makes the audio stream react faster, e.g. to playback speed 200 | changes. Default: 250. 201 | 202 | ``latency-hacks=`` 203 | Enable hacks to workaround PulseAudio timing bugs (default: no). If 204 | enabled, mpv will do elaborate latency calculations on its own. If 205 | disabled, it will use PulseAudio automatically updated timing 206 | information. Disabling this might help with e.g. networked audio or 207 | some plugins, while enabling it might help in some unknown situations 208 | (it used to be required to get good behavior on old PulseAudio versions). 209 | 210 | If you have stuttering video when using pulse, try to enable this 211 | option. (Or alternatively, try to update PulseAudio.) 212 | 213 | ``dsound`` (Windows only) 214 | DirectX DirectSound audio output driver 215 | 216 | .. note:: This driver is for compatibility with old systems. 217 | 218 | ``device=`` 219 | Sets the device number to use. Playing a file with ``-v`` will show a 220 | list of available devices. 221 | 222 | ``buffersize=`` 223 | DirectSound buffer size in milliseconds (default: 200). 224 | 225 | ``sdl`` 226 | SDL 1.2+ audio output driver. Should work on any platform supported by SDL 227 | 1.2, but may require the ``SDL_AUDIODRIVER`` environment variable to be set 228 | appropriately for your system. 229 | 230 | .. note:: This driver is for compatibility with extremely foreign 231 | environments, such as systems where none of the other drivers 232 | are available. 233 | 234 | ``buflen=`` 235 | Sets the audio buffer length in seconds. Is used only as a hint by the 236 | sound system. Playing a file with ``-v`` will show the requested and 237 | obtained exact buffer size. A value of 0 selects the sound system 238 | default. 239 | 240 | ``bufcnt=`` 241 | Sets the number of extra audio buffers in mpv. Usually needs not be 242 | changed. 243 | 244 | ``null`` 245 | Produces no audio output but maintains video playback speed. Use 246 | ``--ao=null:untimed`` for benchmarking. 247 | 248 | ``untimed`` 249 | Do not simulate timing of a perfect audio device. This means audio 250 | decoding will go as fast as possible, instead of timing it to the 251 | system clock. 252 | 253 | ``buffer`` 254 | Simulated buffer length in seconds. 255 | 256 | ``outburst`` 257 | Simulated chunk size in samples. 258 | 259 | ``speed`` 260 | Simulated audio playback speed as a multiplier. Usually, a real audio 261 | device will not go exactly as fast as the system clock. It will deviate 262 | just a little, and this option helps simulating this. 263 | 264 | ``latency`` 265 | Simulated device latency. This is additional to EOF. 266 | 267 | ``broken-eof`` 268 | Simulate broken audio drivers, which always add the fixed device 269 | latency to the reported audio playback position. 270 | 271 | ``broken-delay`` 272 | Simulate broken audio drivers, which don't report latency correctly. 273 | 274 | ``channel-layouts`` 275 | If not empty, this is a ``,`` separated list of channel layouts the 276 | AO allows. This can be used to test channel layout selection. 277 | 278 | ``pcm`` 279 | Raw PCM/WAVE file writer audio output 280 | 281 | ``(no-)waveheader`` 282 | Include or do not include the WAVE header (default: included). When 283 | not included, raw PCM will be generated. 284 | ``file=`` 285 | Write the sound to ```` instead of the default 286 | ``audiodump.wav``. If ``no-waveheader`` is specified, the default is 287 | ``audiodump.pcm``. 288 | ``(no-)append`` 289 | Append to the file, instead of overwriting it. Always use this with the 290 | ``no-waveheader`` option - with ``waveheader`` it's broken, because 291 | it will write a WAVE header every time the file is opened. 292 | 293 | ``rsound`` 294 | Audio output to an RSound daemon 295 | 296 | .. note:: Completely useless, unless you intend to run RSound. Not to be 297 | confused with RoarAudio, which is something completely 298 | different. 299 | 300 | ``host=`` 301 | Set the address of the server (default: localhost). Can be either a 302 | network hostname for TCP connections or a Unix domain socket path 303 | starting with '/'. 304 | ``port=`` 305 | Set the TCP port used for connecting to the server (default: 12345). 306 | Not used if connecting to a Unix domain socket. 307 | 308 | ``sndio`` 309 | Audio output to the OpenBSD sndio sound system 310 | 311 | .. note:: Experimental. There are known bugs and issues. 312 | 313 | (Note: only supports mono, stereo, 4.0, 5.1 and 7.1 channel 314 | layouts.) 315 | 316 | ``device=`` 317 | sndio device to use (default: ``$AUDIODEVICE``, resp. ``snd0``). 318 | 319 | ``wasapi`` 320 | Audio output to the Windows Audio Session API. 321 | 322 | ``exclusive`` 323 | Requests exclusive, direct hardware access. By definition prevents 324 | sound playback of any other program until mpv exits. 325 | ``device=`` 326 | Uses the requested endpoint instead of the system's default audio 327 | endpoint. Both an ordinal number (0,1,2,...) and the GUID 328 | String are valid; the GUID string is guaranteed to not change 329 | unless the driver is uninstalled. 330 | 331 | Also supports searching active devices by human readable name. If more 332 | than one device matches the name, refuses loading it. 333 | 334 | This option is mostly deprecated in favour of the more general 335 | ``--audio-device`` option. That said, ``--audio-device=help`` will give 336 | a list of valid device GUIDs (prefixed with ``wasapi/``), as well as 337 | their human readable names, which should work here. 338 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | --------------------------------------------------------------------------------