diff options
-rw-r--r-- | CHANGES | 11 | ||||
-rw-r--r-- | res/ari/ari_model_validators.c | 27 | ||||
-rw-r--r-- | res/ari/ari_model_validators.h | 3 | ||||
-rw-r--r-- | res/res_stasis_recording.c | 24 | ||||
-rw-r--r-- | rest-api/api-docs/recordings.json | 25 |
5 files changed, 78 insertions, 12 deletions
@@ -228,6 +228,17 @@ ARI existing stored recording and copy it to a new location in the recordings directory. + * LiveRecording objects now have three additional fields that can be reported + in a RecordingFinished ARI event: + - total_duration: the duration of the recording + - talking_duration: optional. The duration of talking detected in the + recording. This is only available if max_silence_seconds was specified + when the recording was started. + - silence_duration: optional. The duration of silence detected in the + recording. This is only available if max_silence_seconds was specified + when the recording was started. + Note that all duration values are reported in seconds. + res_pjsip ------------------ * The endpoint configuration object now supports 'accountcode'. Any channel diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c index d15ec494d..0302db327 100644 --- a/res/ari/ari_model_validators.c +++ b/res/ari/ari_model_validators.c @@ -1038,6 +1038,15 @@ int ast_ari_validate_live_recording(struct ast_json *json) res = 0; } } else + if (strcmp("duration", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI LiveRecording field duration failed validation\n"); + res = 0; + } + } else if (strcmp("format", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_format = 1; @@ -1058,6 +1067,15 @@ int ast_ari_validate_live_recording(struct ast_json *json) res = 0; } } else + if (strcmp("silence_duration", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI LiveRecording field silence_duration failed validation\n"); + res = 0; + } + } else if (strcmp("state", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_state = 1; @@ -1068,6 +1086,15 @@ int ast_ari_validate_live_recording(struct ast_json *json) res = 0; } } else + if (strcmp("talking_duration", ast_json_object_iter_key(iter)) == 0) { + int prop_is_valid; + prop_is_valid = ast_ari_validate_int( + ast_json_object_iter_value(iter)); + if (!prop_is_valid) { + ast_log(LOG_ERROR, "ARI LiveRecording field talking_duration failed validation\n"); + res = 0; + } + } else if (strcmp("target_uri", ast_json_object_iter_key(iter)) == 0) { int prop_is_valid; has_target_uri = 1; diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h index c85115634..0186168b2 100644 --- a/res/ari/ari_model_validators.h +++ b/res/ari/ari_model_validators.h @@ -1179,9 +1179,12 @@ ari_validator ast_ari_validate_application_fn(void); * - technology: string (required) * LiveRecording * - cause: string + * - duration: int * - format: string (required) * - name: string (required) + * - silence_duration: int * - state: string (required) + * - talking_duration: int * - target_uri: string (required) * StoredRecording * - format: string (required) diff --git a/res/res_stasis_recording.c b/res/res_stasis_recording.c index 55954cd1e..f74974349 100644 --- a/res/res_stasis_recording.c +++ b/res/res_stasis_recording.c @@ -61,6 +61,13 @@ struct stasis_app_recording { struct stasis_app_control *control; /*! Current state of the recording. */ enum stasis_app_recording_state state; + /*! Duration calculations */ + struct { + /*! Total duration */ + int total; + /*! Duration minus any silence */ + int energy_only; + } duration; /*! Indicates whether the recording is currently muted */ int muted:1; }; @@ -285,7 +292,6 @@ static int record_file(struct stasis_app_control *control, NULL, recording_cleanup); char *acceptdtmf; int res; - int duration = 0; recording = data; ast_assert(recording != NULL); @@ -325,8 +331,8 @@ static int record_file(struct stasis_app_control *control, recording->absolute_name, recording->options->max_duration_seconds, recording->options->format, - &duration, - NULL, /* sound_duration */ + &recording->duration.total, + recording->options->max_silence_seconds ? &recording->duration.energy_only : NULL, recording->options->beep, -1, /* silencethreshold */ recording->options->max_silence_seconds * 1000, @@ -381,6 +387,8 @@ struct stasis_app_recording *stasis_app_control_record( errno = ENOMEM; return NULL; } + recording->duration.total = -1; + recording->duration.energy_only = -1; ast_asprintf(&recording->absolute_name, "%s/%s", ast_config_AST_RECORDING_DIR, options->name); @@ -480,6 +488,16 @@ struct ast_json *stasis_app_recording_to_json( "format", recording->options->format, "state", state_to_string(recording->state), "target_uri", recording->options->target); + if (json && recording->duration.total > -1) { + ast_json_object_set(json, "duration", + ast_json_integer_create(recording->duration.total)); + } + if (json && recording->duration.energy_only > -1) { + ast_json_object_set(json, "talking_duration", + ast_json_integer_create(recording->duration.energy_only)); + ast_json_object_set(json, "silence_duration", + ast_json_integer_create(recording->duration.total - recording->duration.energy_only)); + } return ast_json_ref(json); } diff --git a/rest-api/api-docs/recordings.json b/rest-api/api-docs/recordings.json index 54daa33cf..b0a65664c 100644 --- a/rest-api/api-docs/recordings.json +++ b/rest-api/api-docs/recordings.json @@ -338,7 +338,7 @@ "description": "URI for the channel or bridge being recorded" }, "state": { - "required": false, + "required": true, "type": "string", "allowableValues": { "valueType": "LIST", @@ -352,18 +352,25 @@ ] } }, + "duration": { + "required": false, + "type": "int", + "description": "Duration in seconds of the recording" + }, + "talking_duration": { + "required": false, + "type": "int", + "description": "Duration of talking, in seconds, detected in the recording. This is only available if the recording was initiated with a non-zero maxSilenceSeconds." + }, + "silence_duration": { + "required": false, + "type": "int", + "description": "Duration of silence, in seconds, detected in the recording. This is only available if the recording was initiated with a non-zero maxSilenceSeconds." + }, "cause": { "required": false, "type": "string", "description": "Cause for recording failure if failed" - }, - "state": { - "required": true, - "type": "string" - }, - "format": { - "required": true, - "type": "string" } } } |