output-timer.cpp 9.2 KB

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