output-timer.cpp 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. #include <obs-frontend-api.h>
  2. #include <obs-module.h>
  3. #include <obs.hpp>
  4. #include <util/util.hpp>
  5. #include <QAction>
  6. #include <QMainWindow>
  7. #include <QTimer>
  8. #include <QObject>
  9. #include "output-timer.hpp"
  10. using namespace std;
  11. OutputTimer *ot;
  12. OutputTimer::OutputTimer(QWidget *parent)
  13. : QDialog(parent),
  14. ui(new Ui_OutputTimer)
  15. {
  16. ui->setupUi(this);
  17. setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
  18. QObject::connect(ui->outputTimerStream, &QPushButton::clicked, this,
  19. &OutputTimer::StreamingTimerButton);
  20. QObject::connect(ui->outputTimerRecord, &QPushButton::clicked, this,
  21. &OutputTimer::RecordingTimerButton);
  22. QObject::connect(ui->buttonBox->button(QDialogButtonBox::Close),
  23. &QPushButton::clicked, this, &OutputTimer::hide);
  24. streamingTimer = new QTimer(this);
  25. streamingTimerDisplay = new QTimer(this);
  26. recordingTimer = new QTimer(this);
  27. recordingTimerDisplay = new QTimer(this);
  28. QObject::connect(streamingTimer, &QTimer::timeout, this,
  29. &OutputTimer::EventStopStreaming);
  30. QObject::connect(streamingTimerDisplay, &QTimer::timeout, this,
  31. &OutputTimer::UpdateStreamTimerDisplay);
  32. QObject::connect(recordingTimer, &QTimer::timeout, this,
  33. &OutputTimer::EventStopRecording);
  34. QObject::connect(recordingTimerDisplay, &QTimer::timeout, this,
  35. &OutputTimer::UpdateRecordTimerDisplay);
  36. }
  37. void OutputTimer::closeEvent(QCloseEvent *)
  38. {
  39. obs_frontend_save();
  40. }
  41. void OutputTimer::StreamingTimerButton()
  42. {
  43. if (!obs_frontend_streaming_active()) {
  44. blog(LOG_INFO, "Starting stream due to OutputTimer");
  45. obs_frontend_streaming_start();
  46. } else if (streamingAlreadyActive) {
  47. StreamTimerStart();
  48. streamingAlreadyActive = false;
  49. } else if (obs_frontend_streaming_active()) {
  50. blog(LOG_INFO, "Stopping stream due to OutputTimer");
  51. obs_frontend_streaming_stop();
  52. }
  53. }
  54. void OutputTimer::RecordingTimerButton()
  55. {
  56. if (!obs_frontend_recording_active()) {
  57. blog(LOG_INFO, "Starting recording due to OutputTimer");
  58. obs_frontend_recording_start();
  59. } else if (recordingAlreadyActive) {
  60. RecordTimerStart();
  61. recordingAlreadyActive = false;
  62. } else if (obs_frontend_recording_active()) {
  63. blog(LOG_INFO, "Stopping recording due to OutputTimer");
  64. obs_frontend_recording_stop();
  65. }
  66. }
  67. void OutputTimer::StreamTimerStart()
  68. {
  69. if (!isVisible() && ui->autoStartStreamTimer->isChecked() == false) {
  70. streamingAlreadyActive = true;
  71. return;
  72. }
  73. int hours = ui->streamingTimerHours->value();
  74. int minutes = ui->streamingTimerMinutes->value();
  75. int seconds = ui->streamingTimerSeconds->value();
  76. int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
  77. if (total == 0)
  78. total = 1000;
  79. streamingTimer->setInterval(total);
  80. streamingTimer->setSingleShot(true);
  81. streamingTimer->start();
  82. streamingTimerDisplay->start(1000);
  83. ui->outputTimerStream->setText(obs_module_text("Stop"));
  84. UpdateStreamTimerDisplay();
  85. ui->outputTimerStream->setChecked(true);
  86. }
  87. void OutputTimer::RecordTimerStart()
  88. {
  89. if (!isVisible() && ui->autoStartRecordTimer->isChecked() == false) {
  90. recordingAlreadyActive = true;
  91. return;
  92. }
  93. int hours = ui->recordingTimerHours->value();
  94. int minutes = ui->recordingTimerMinutes->value();
  95. int seconds = ui->recordingTimerSeconds->value();
  96. int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
  97. if (total == 0)
  98. total = 1000;
  99. recordingTimer->setInterval(total);
  100. recordingTimer->setSingleShot(true);
  101. recordingTimer->start();
  102. recordingTimerDisplay->start(1000);
  103. ui->outputTimerRecord->setText(obs_module_text("Stop"));
  104. UpdateRecordTimerDisplay();
  105. ui->outputTimerRecord->setChecked(true);
  106. }
  107. void OutputTimer::StreamTimerStop()
  108. {
  109. streamingAlreadyActive = false;
  110. if (!isVisible() && streamingTimer->isActive() == false)
  111. return;
  112. if (streamingTimer->isActive())
  113. streamingTimer->stop();
  114. ui->outputTimerStream->setText(obs_module_text("Start"));
  115. if (streamingTimerDisplay->isActive())
  116. streamingTimerDisplay->stop();
  117. ui->streamTime->setText("00:00:00");
  118. ui->outputTimerStream->setChecked(false);
  119. }
  120. void OutputTimer::RecordTimerStop()
  121. {
  122. recordingAlreadyActive = false;
  123. if (!isVisible() && recordingTimer->isActive() == false)
  124. return;
  125. if (recordingTimer->isActive())
  126. recordingTimer->stop();
  127. ui->outputTimerRecord->setText(obs_module_text("Start"));
  128. if (recordingTimerDisplay->isActive())
  129. recordingTimerDisplay->stop();
  130. ui->recordTime->setText("00:00:00");
  131. ui->outputTimerRecord->setChecked(false);
  132. }
  133. void OutputTimer::UpdateStreamTimerDisplay()
  134. {
  135. int remainingTime = streamingTimer->remainingTime() / 1000;
  136. int seconds = remainingTime % 60;
  137. int minutes = (remainingTime % 3600) / 60;
  138. int hours = remainingTime / 3600;
  139. QString text =
  140. QString::asprintf("%02d:%02d:%02d", hours, minutes, seconds);
  141. ui->streamTime->setText(text);
  142. }
  143. void OutputTimer::UpdateRecordTimerDisplay()
  144. {
  145. int remainingTime = 0;
  146. if (obs_frontend_recording_paused() &&
  147. ui->pauseRecordTimer->isChecked())
  148. remainingTime = recordingTimeLeft / 1000;
  149. else
  150. remainingTime = recordingTimer->remainingTime() / 1000;
  151. int seconds = remainingTime % 60;
  152. int minutes = (remainingTime % 3600) / 60;
  153. int hours = remainingTime / 3600;
  154. QString text =
  155. QString::asprintf("%02d:%02d:%02d", hours, minutes, seconds);
  156. ui->recordTime->setText(text);
  157. }
  158. void OutputTimer::PauseRecordingTimer()
  159. {
  160. if (!ui->pauseRecordTimer->isChecked())
  161. return;
  162. if (recordingTimer->isActive()) {
  163. recordingTimeLeft = recordingTimer->remainingTime();
  164. recordingTimer->stop();
  165. }
  166. }
  167. void OutputTimer::UnpauseRecordingTimer()
  168. {
  169. if (!ui->pauseRecordTimer->isChecked())
  170. return;
  171. if (recordingTimeLeft > 0 && !recordingTimer->isActive())
  172. recordingTimer->start(recordingTimeLeft);
  173. }
  174. void OutputTimer::ShowHideDialog()
  175. {
  176. if (!isVisible()) {
  177. setVisible(true);
  178. QTimer::singleShot(250, this, &OutputTimer::show);
  179. } else {
  180. setVisible(false);
  181. QTimer::singleShot(250, this, &OutputTimer::hide);
  182. }
  183. }
  184. void OutputTimer::EventStopStreaming()
  185. {
  186. blog(LOG_INFO, "Stopping stream due to OutputTimer timeout");
  187. obs_frontend_streaming_stop();
  188. }
  189. void OutputTimer::EventStopRecording()
  190. {
  191. blog(LOG_INFO, "Stopping recording due to OutputTimer timeout");
  192. obs_frontend_recording_stop();
  193. }
  194. static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
  195. {
  196. if (saving) {
  197. OBSDataAutoRelease obj = obs_data_create();
  198. obs_data_set_int(obj, "streamTimerHours",
  199. ot->ui->streamingTimerHours->value());
  200. obs_data_set_int(obj, "streamTimerMinutes",
  201. ot->ui->streamingTimerMinutes->value());
  202. obs_data_set_int(obj, "streamTimerSeconds",
  203. ot->ui->streamingTimerSeconds->value());
  204. obs_data_set_int(obj, "recordTimerHours",
  205. ot->ui->recordingTimerHours->value());
  206. obs_data_set_int(obj, "recordTimerMinutes",
  207. ot->ui->recordingTimerMinutes->value());
  208. obs_data_set_int(obj, "recordTimerSeconds",
  209. ot->ui->recordingTimerSeconds->value());
  210. obs_data_set_bool(obj, "autoStartStreamTimer",
  211. ot->ui->autoStartStreamTimer->isChecked());
  212. obs_data_set_bool(obj, "autoStartRecordTimer",
  213. ot->ui->autoStartRecordTimer->isChecked());
  214. obs_data_set_bool(obj, "pauseRecordTimer",
  215. ot->ui->pauseRecordTimer->isChecked());
  216. obs_data_set_obj(save_data, "output-timer", obj);
  217. } else {
  218. OBSDataAutoRelease obj =
  219. obs_data_get_obj(save_data, "output-timer");
  220. if (!obj)
  221. obj = obs_data_create();
  222. ot->ui->streamingTimerHours->setValue(
  223. obs_data_get_int(obj, "streamTimerHours"));
  224. ot->ui->streamingTimerMinutes->setValue(
  225. obs_data_get_int(obj, "streamTimerMinutes"));
  226. ot->ui->streamingTimerSeconds->setValue(
  227. obs_data_get_int(obj, "streamTimerSeconds"));
  228. ot->ui->recordingTimerHours->setValue(
  229. obs_data_get_int(obj, "recordTimerHours"));
  230. ot->ui->recordingTimerMinutes->setValue(
  231. obs_data_get_int(obj, "recordTimerMinutes"));
  232. ot->ui->recordingTimerSeconds->setValue(
  233. obs_data_get_int(obj, "recordTimerSeconds"));
  234. ot->ui->autoStartStreamTimer->setChecked(
  235. obs_data_get_bool(obj, "autoStartStreamTimer"));
  236. ot->ui->autoStartRecordTimer->setChecked(
  237. obs_data_get_bool(obj, "autoStartRecordTimer"));
  238. ot->ui->pauseRecordTimer->setChecked(
  239. obs_data_get_bool(obj, "pauseRecordTimer"));
  240. }
  241. }
  242. extern "C" void FreeOutputTimer() {}
  243. static void OBSEvent(enum obs_frontend_event event, void *)
  244. {
  245. if (event == OBS_FRONTEND_EVENT_EXIT) {
  246. obs_frontend_save();
  247. FreeOutputTimer();
  248. } else if (event == OBS_FRONTEND_EVENT_STREAMING_STARTED) {
  249. ot->StreamTimerStart();
  250. } else if (event == OBS_FRONTEND_EVENT_STREAMING_STOPPING) {
  251. ot->StreamTimerStop();
  252. } else if (event == OBS_FRONTEND_EVENT_RECORDING_STARTED) {
  253. ot->RecordTimerStart();
  254. } else if (event == OBS_FRONTEND_EVENT_RECORDING_STOPPING) {
  255. ot->RecordTimerStop();
  256. } else if (event == OBS_FRONTEND_EVENT_RECORDING_PAUSED) {
  257. ot->PauseRecordingTimer();
  258. } else if (event == OBS_FRONTEND_EVENT_RECORDING_UNPAUSED) {
  259. ot->UnpauseRecordingTimer();
  260. }
  261. }
  262. extern "C" void InitOutputTimer()
  263. {
  264. QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
  265. obs_module_text("OutputTimer"));
  266. obs_frontend_push_ui_translation(obs_module_get_string);
  267. QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window();
  268. ot = new OutputTimer(window);
  269. auto cb = []() {
  270. ot->ShowHideDialog();
  271. };
  272. obs_frontend_pop_ui_translation();
  273. obs_frontend_add_save_callback(SaveOutputTimer, nullptr);
  274. obs_frontend_add_event_callback(OBSEvent, nullptr);
  275. action->connect(action, &QAction::triggered, cb);
  276. }