settings_page.cpp 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include "settings_page.h"
  2. #include <QFileDialog>
  3. #include "encoder/video_encoder.h"
  4. #include "encoder/audio_encoder.h"
  5. SettingsPage::SettingsPage(Param* param, QWidget* parent)
  6. : QDialog(parent)
  7. , _param(param)
  8. {
  9. setFont(QFont("Microsoft Yahei"));
  10. _InitUi();
  11. _InitConnect();
  12. }
  13. void SettingsPage::_InitConnect()
  14. {
  15. connect(_applyBtn, &QPushButton::released, [this] { _WriteSettings(); });
  16. connect(_cancelBtn, &QPushButton::released, [this] { this->close(); });
  17. connect(_yesBtn, &QPushButton::released, [this] {
  18. _WriteSettings();
  19. this->close();
  20. });
  21. connect(_selDirBtn, &QPushButton::released, [this] {
  22. QString selectedDir = QFileDialog::getExistingDirectory(this,
  23. "选择输出目录",
  24. "./",
  25. QFileDialog::ShowDirsOnly);
  26. // 若目录路径不为空
  27. if (!selectedDir.isEmpty()) {
  28. // 显示选择的目录路径
  29. _fileDirEdit->setText(selectedDir);
  30. }
  31. });
  32. if (_resetBestBtn) {
  33. connect(_resetBestBtn, &QPushButton::released, [this] {
  34. _ApplyBestDefaults();
  35. });
  36. }
  37. }
  38. void SettingsPage::_WriteSettings()
  39. {
  40. _param->videoParam.bitRate = _videoBitRateBox->value() * 1000;
  41. _param->videoParam.fps = _videoFpsBox->value();
  42. _param->videoParam.name = _videoEncoderBox->currentText().toStdString();
  43. _param->videoParam.width = _videoWidthBox ? _videoWidthBox->value() : _param->videoParam.width;
  44. _param->videoParam.height = _videoHeightBox ? _videoHeightBox->value() : _param->videoParam.height;
  45. _param->audioParam.bitRate = _audioBitRateBox->value() * 1000;
  46. if (_audioEncoderBox) {
  47. _param->audioParam.name = _audioEncoderBox->currentText().toStdString();
  48. }
  49. _param->outputDir = _fileDirEdit->text().toStdString();
  50. // 直播参数为项目内置设置,不从UI写回
  51. }
  52. void SettingsPage::_InitUi()
  53. {
  54. setWindowTitle("Settings");
  55. auto layout = new QVBoxLayout;
  56. layout->addWidget(_InitVideoUi());
  57. layout->addWidget(_InitAudioUi());
  58. layout->addWidget(_InitOutputUi());
  59. // 不显示“直播”设置(项目内置配置,不需要在UI中展示)
  60. auto hLayout = new QHBoxLayout;
  61. _resetBestBtn = new QPushButton("最佳默认");
  62. _applyBtn = new QPushButton("应用");
  63. _cancelBtn = new QPushButton("取消");
  64. _yesBtn = new QPushButton("确定");
  65. hLayout->setAlignment(Qt::AlignRight);
  66. hLayout->addWidget(_resetBestBtn);
  67. hLayout->addStretch();
  68. hLayout->addWidget(_applyBtn);
  69. hLayout->addWidget(_cancelBtn);
  70. hLayout->addWidget(_yesBtn);
  71. layout->addLayout(hLayout);
  72. setLayout(layout);
  73. }
  74. QGroupBox* SettingsPage::_InitVideoUi()
  75. {
  76. auto groupBox = new QGroupBox("视频");
  77. auto layout = new QVBoxLayout;
  78. _videoBitRateBox = new QSpinBox;
  79. _videoBitRateBox->setMinimum(0);
  80. _videoBitRateBox->setMaximum(INT_MAX);
  81. _videoBitRateBox->setValue(_param->videoParam.bitRate / 1000);
  82. _videoFpsBox = new QSpinBox;
  83. _videoFpsBox->setMinimum(1);
  84. _videoFpsBox->setMaximum(120);
  85. _videoFpsBox->setValue(_param->videoParam.fps);
  86. // 分辨率设置
  87. _videoWidthBox = new QSpinBox;
  88. _videoWidthBox->setMinimum(160);
  89. _videoWidthBox->setMaximum(7680);
  90. _videoWidthBox->setValue(_param->videoParam.width > 0 ? _param->videoParam.width : 1920);
  91. _videoHeightBox = new QSpinBox;
  92. _videoHeightBox->setMinimum(120);
  93. _videoHeightBox->setMaximum(4320);
  94. _videoHeightBox->setValue(_param->videoParam.height > 0 ? _param->videoParam.height : 1080);
  95. _videoEncoderBox = new QComboBox;
  96. auto&& encoders = Encoder<MediaType::VIDEO>::GetUsableEncoders();
  97. for (auto&& encoder : encoders) {
  98. _videoEncoderBox->addItem(encoder.c_str());
  99. }
  100. if (_videoEncoderBox->count() == 0) {
  101. _videoEncoderBox->addItem("libx264");
  102. }
  103. // 如果当前参数名不在列表中,则默认选中第一项
  104. if (_videoEncoderBox->findText(_param->videoParam.name.c_str()) == -1) {
  105. _videoEncoderBox->setCurrentIndex(0);
  106. } else {
  107. _videoEncoderBox->setCurrentText(_param->videoParam.name.c_str());
  108. }
  109. layout->addLayout(
  110. _CreateDescription("比特率(kB):", "越高的比特率越清晰, 但越占用硬件资源", _videoBitRateBox));
  111. layout->addLayout(
  112. _CreateDescription("帧率:", "越高的帧率越流畅, 但越占用硬件资源", _videoFpsBox));
  113. layout->addLayout(
  114. _CreateDescription("分辨率-宽:", "输出视频宽度,建议与屏幕或窗口比例一致", _videoWidthBox));
  115. layout->addLayout(
  116. _CreateDescription("分辨率-高:", "输出视频高度,建议与屏幕或窗口比例一致", _videoHeightBox));
  117. layout->addLayout(_CreateDescription(
  118. "编码器:",
  119. "libx264 为软件编码, CPU占用高但兼容性强, 其他为硬件编码, 效果与软件编码相反",
  120. _videoEncoderBox));
  121. groupBox->setLayout(layout);
  122. return groupBox;
  123. }
  124. QGroupBox* SettingsPage::_InitAudioUi()
  125. {
  126. auto groupBox = new QGroupBox("音频");
  127. auto layout = new QVBoxLayout;
  128. _audioBitRateBox = new QSpinBox;
  129. _audioBitRateBox->setMinimum(0);
  130. _audioBitRateBox->setMaximum(INT_MAX);
  131. _audioBitRateBox->setValue(_param->audioParam.bitRate / 1000);
  132. // 音频编码器选择
  133. _audioEncoderBox = new QComboBox;
  134. {
  135. auto&& encoders = Encoder<MediaType::AUDIO>::GetUsableEncoders();
  136. for (auto&& encoder : encoders) {
  137. _audioEncoderBox->addItem(encoder.c_str());
  138. }
  139. if (_audioEncoderBox->count() == 0) {
  140. _audioEncoderBox->addItem("aac");
  141. }
  142. // 如果当前参数名不在列表中,则默认选中第一项
  143. if (_audioEncoderBox->findText(_param->audioParam.name.c_str()) == -1) {
  144. _audioEncoderBox->setCurrentIndex(0);
  145. } else {
  146. _audioEncoderBox->setCurrentText(_param->audioParam.name.c_str());
  147. }
  148. }
  149. layout->addLayout(
  150. _CreateDescription("比特率(kB):", "越高的比特率越清晰, 但越占用硬件资源", _audioBitRateBox));
  151. layout->addLayout(_CreateDescription(
  152. "编码器:",
  153. "aac 兼容性最好;opus 音质高但需容器/推流支持;mp3 不建议用于flv",
  154. _audioEncoderBox));
  155. groupBox->setLayout(layout);
  156. return groupBox;
  157. }
  158. QGroupBox* SettingsPage::_InitOutputUi()
  159. {
  160. auto groupBox = new QGroupBox("输出");
  161. auto layout = new QHBoxLayout;
  162. _fileDirEdit = new QLineEdit(_param->outputDir.c_str());
  163. _selDirBtn = new QPushButton("选择");
  164. layout->addWidget(_fileDirEdit);
  165. layout->addWidget(_selDirBtn);
  166. groupBox->setLayout(layout);
  167. return groupBox;
  168. }
  169. QGroupBox* SettingsPage::_InitLiveUi()
  170. {
  171. auto groupBox = new QGroupBox("直播");
  172. auto layout = new QVBoxLayout;
  173. _liveUrlEdit = new QLineEdit(QString::fromStdString(_param->liveUrl));
  174. _liveNameEdit = new QLineEdit(QString::fromStdString(_param->liveName));
  175. layout->addLayout(_CreateDescription("推流地址:", "例如: rtmp://<server>:1935/stream/V1 或 rtsp://...", _liveUrlEdit));
  176. layout->addLayout(_CreateDescription("流名称:", "推流路径中的名称或Key", _liveNameEdit));
  177. groupBox->setLayout(layout);
  178. return groupBox;
  179. }
  180. void SettingsPage::_ApplyBestDefaults()
  181. {
  182. // 优先选择可用编码器列表的第一项(通常为硬件加速编码器)
  183. if (_videoEncoderBox && _videoEncoderBox->count() > 0) {
  184. _videoEncoderBox->setCurrentIndex(0);
  185. }
  186. if (_audioEncoderBox && _audioEncoderBox->count() > 0) {
  187. _audioEncoderBox->setCurrentIndex(0);
  188. }
  189. // 设置为通用的高质量方案:1080p@30fps, 8 Mbps;音频 160 kbps
  190. if (_videoWidthBox) _videoWidthBox->setValue(1920);
  191. if (_videoHeightBox) _videoHeightBox->setValue(1080);
  192. if (_videoFpsBox) _videoFpsBox->setValue(30);
  193. if (_videoBitRateBox) _videoBitRateBox->setValue(8000);
  194. if (_audioBitRateBox) _audioBitRateBox->setValue(160);
  195. }
  196. QHBoxLayout* SettingsPage::_CreateDescription(std::string_view text,
  197. std::string_view textEx,
  198. QWidget* widget)
  199. {
  200. auto layout = new QHBoxLayout;
  201. auto label = new QLabel(text.data());
  202. label->setToolTip(textEx.data());
  203. layout->addWidget(label);
  204. layout->addWidget(widget);
  205. return layout;
  206. }