@@ -39,6 +39,7 @@ struct source_record_filter_context {
39
39
obs_hotkey_pair_id enableHotkey ;
40
40
obs_hotkey_pair_id pauseHotkeys ;
41
41
obs_hotkey_id splitHotkey ;
42
+ obs_hotkey_id chapterHotkey ;
42
43
int audio_track ;
43
44
obs_weak_source_t * audio_source ;
44
45
bool closing ;
@@ -614,7 +615,8 @@ static void set_encoder_defaults(obs_data_t *settings)
614
615
obs_data_release (enc_defaults );
615
616
}
616
617
617
- static void update_encoder (struct source_record_filter_context * filter , obs_data_t * settings ) {
618
+ static void update_encoder (struct source_record_filter_context * filter , obs_data_t * settings )
619
+ {
618
620
const char * enc_id = get_encoder_id (settings );
619
621
if (!filter -> encoder || strcmp (obs_encoder_get_id (filter -> encoder ), enc_id ) != 0 ) {
620
622
obs_encoder_release (filter -> encoder );
@@ -975,6 +977,7 @@ static void *source_record_filter_create(obs_data_t *settings, obs_source_t *sou
975
977
context -> enableHotkey = OBS_INVALID_HOTKEY_PAIR_ID ;
976
978
context -> pauseHotkeys = OBS_INVALID_HOTKEY_PAIR_ID ;
977
979
context -> splitHotkey = OBS_INVALID_HOTKEY_ID ;
980
+ context -> chapterHotkey = OBS_INVALID_HOTKEY_ID ;
978
981
source_record_filter_update (context , settings );
979
982
obs_frontend_add_event_callback (frontend_event , context );
980
983
return context ;
@@ -1058,6 +1061,9 @@ static void source_record_filter_destroy(void *data)
1058
1061
if (context -> splitHotkey != OBS_INVALID_HOTKEY_ID )
1059
1062
obs_hotkey_unregister (context -> splitHotkey );
1060
1063
1064
+ if (context -> chapterHotkey != OBS_INVALID_HOTKEY_ID )
1065
+ obs_hotkey_unregister (context -> chapterHotkey );
1066
+
1061
1067
source_record_delayed_destroy (context );
1062
1068
}
1063
1069
@@ -1118,7 +1124,8 @@ static bool source_record_unpause_hotkey(void *data, obs_hotkey_pair_id id, obs_
1118
1124
return true;
1119
1125
}
1120
1126
1121
- static void source_record_split_hotkey (void * data , obs_hotkey_id id , obs_hotkey_t * hotkey , bool pressed ) {
1127
+ static void source_record_split_hotkey (void * data , obs_hotkey_id id , obs_hotkey_t * hotkey , bool pressed )
1128
+ {
1122
1129
UNUSED_PARAMETER (id );
1123
1130
UNUSED_PARAMETER (hotkey );
1124
1131
if (!pressed )
@@ -1133,6 +1140,22 @@ static void source_record_split_hotkey(void *data, obs_hotkey_id id, obs_hotkey_
1133
1140
calldata_free (& cd );
1134
1141
}
1135
1142
1143
+ static void source_record_chapter_hotkey (void * data , obs_hotkey_id id , obs_hotkey_t * hotkey , bool pressed )
1144
+ {
1145
+ UNUSED_PARAMETER (id );
1146
+ UNUSED_PARAMETER (hotkey );
1147
+ if (!pressed )
1148
+ return ;
1149
+ struct source_record_filter_context * context = data ;
1150
+ if (!context -> fileOutput )
1151
+ return ;
1152
+ proc_handler_t * ph = obs_output_get_proc_handler (context -> fileOutput );
1153
+ struct calldata cd ;
1154
+ calldata_init (& cd );
1155
+ proc_handler_call (ph , "add_chapter" , & cd );
1156
+ calldata_free (& cd );
1157
+ }
1158
+
1136
1159
static void source_record_filter_tick (void * data , float seconds )
1137
1160
{
1138
1161
UNUSED_PARAMETER (seconds );
@@ -1161,6 +1184,11 @@ static void source_record_filter_tick(void *data, float seconds)
1161
1184
obs_frontend_get_locale_string ("Basic.Main.SplitFile" ),
1162
1185
source_record_split_hotkey , context );
1163
1186
1187
+ if (context -> chapterHotkey == OBS_INVALID_HOTKEY_ID )
1188
+ context -> chapterHotkey = obs_hotkey_register_source (parent , "source_record.AddChapterMarker" ,
1189
+ obs_frontend_get_locale_string ("Basic.Main.AddChapterMarker" ),
1190
+ source_record_chapter_hotkey , context );
1191
+
1164
1192
uint32_t width = obs_source_get_width (parent );
1165
1193
width += (width & 1 );
1166
1194
uint32_t height = obs_source_get_height (parent );
@@ -1756,6 +1784,28 @@ static bool split_record_source(obs_source_t *source, obs_data_t *request_data,
1756
1784
return true;
1757
1785
}
1758
1786
1787
+ static bool add_chapter_record_source (obs_source_t * source , obs_data_t * request_data , obs_data_t * response_data )
1788
+ {
1789
+ obs_source_t * filter = get_source_record_filter (source , request_data , response_data , false);
1790
+ if (!filter )
1791
+ return false;
1792
+
1793
+ struct source_record_filter_context * context = obs_obj_get_data (filter );
1794
+ obs_source_release (filter );
1795
+ if (!context -> fileOutput )
1796
+ return false;
1797
+ proc_handler_t * ph = obs_output_get_proc_handler (context -> fileOutput );
1798
+ struct calldata cd ;
1799
+ calldata_init (& cd );
1800
+ calldata_set_string (& cd , "chapter_name" , obs_data_get_string (request_data , "chapter_name" ));
1801
+ if (!proc_handler_call (ph , "add_chapter" , & cd )) {
1802
+ calldata_free (& cd );
1803
+ return false;
1804
+ }
1805
+ calldata_free (& cd );
1806
+ return true;
1807
+ }
1808
+
1759
1809
static bool stop_record_source (obs_source_t * source , obs_data_t * request_data , obs_data_t * response_data )
1760
1810
{
1761
1811
obs_source_t * filter = get_source_record_filter (source , request_data , response_data , false);
@@ -1896,6 +1946,37 @@ static void websocket_split_record(obs_data_t *request_data, obs_data_t *respons
1896
1946
obs_data_set_bool (response_data , "success" , success );
1897
1947
}
1898
1948
1949
+ static void websocket_add_chapter_record (obs_data_t * request_data , obs_data_t * response_data , void * param )
1950
+ {
1951
+ UNUSED_PARAMETER (param );
1952
+ const char * source_name = obs_data_get_string (request_data , "source" );
1953
+ bool success = true;
1954
+ if (strlen (source_name )) {
1955
+ obs_source_t * source = obs_get_source_by_name (source_name );
1956
+ if (!source ) {
1957
+ obs_data_set_string (response_data , "error" , "source not found" );
1958
+ obs_data_set_bool (response_data , "success" , false);
1959
+ return ;
1960
+ }
1961
+ success = add_chapter_record_source (source , request_data , response_data );
1962
+ obs_source_release (source );
1963
+ } else {
1964
+ DARRAY (obs_source_t * ) sources = {0 };
1965
+ obs_enum_sources (find_source , & sources );
1966
+ obs_enum_scenes (find_source , & sources );
1967
+ if (!sources .num ) {
1968
+ obs_data_set_string (response_data , "error" , "no source found" );
1969
+ obs_data_set_bool (response_data , "success" , false);
1970
+ return ;
1971
+ }
1972
+ for (size_t i = 0 ; i < sources .num ; i ++ ) {
1973
+ success = add_chapter_record_source (sources .array [i ], request_data , response_data ) && success ;
1974
+ }
1975
+ da_free (sources );
1976
+ }
1977
+ obs_data_set_bool (response_data , "success" , success );
1978
+ }
1979
+
1899
1980
static void websocket_stop_record (obs_data_t * request_data , obs_data_t * response_data , void * param )
1900
1981
{
1901
1982
UNUSED_PARAMETER (param );
@@ -2197,6 +2278,7 @@ bool obs_module_load(void)
2197
2278
obs_websocket_vendor_register_request (vendor , "record_pause" , websocket_pause_record , NULL );
2198
2279
obs_websocket_vendor_register_request (vendor , "record_unpause" , websocket_unpause_record , NULL );
2199
2280
obs_websocket_vendor_register_request (vendor , "record_split" , websocket_split_record , NULL );
2281
+ obs_websocket_vendor_register_request (vendor , "record_add_chapter" , websocket_add_chapter_record , NULL );
2200
2282
obs_websocket_vendor_register_request (vendor , "record_stop" , websocket_stop_record , NULL );
2201
2283
obs_websocket_vendor_register_request (vendor , "replay_buffer_start" , websocket_start_replay_buffer , NULL );
2202
2284
obs_websocket_vendor_register_request (vendor , "replay_buffer_stop" , websocket_stop_replay_buffer , NULL );
0 commit comments