Multiple revisions 419565-419566
authorMatthew Jordan <mjordan@digium.com>
Fri, 25 Jul 2014 14:47:09 +0000 (14:47 +0000)
committerMatthew Jordan <mjordan@digium.com>
Fri, 25 Jul 2014 14:47:09 +0000 (14:47 +0000)
........
  r419565 | mjordan | 2014-07-25 09:41:23 -0500 (Fri, 25 Jul 2014) | 21 lines

  ARI: report duration values in LiveRecording objects

  This patch adds three new fields to the LiveRecording model:
   - total_duration: the total length of the live recording
   - talking_duration: optional. The duration of talking energy that was
     detected while the recording was made.
   - silence_duration: optional. The duration of silence that was detected while
     the recording was made.

  These values are reported in the RecordingFinished ARI event.

  When a DSP is enabled on the channel during the recording - which occurs when
  the recording is created with max_silence_seconds (indicating that the user
  actually cares about how much silence is in the file), we will report the
  talking_duration and silence_duration in addition to the total_duration.

  Review: https://reviewboard.asterisk.org/r/3770/

  ASTERISK-24037 #close
  Reported by: Samuel Galarneau
........
  r419566 | mjordan | 2014-07-25 09:46:15 -0500 (Fri, 25 Jul 2014) | 1 line

  Update CHANGES for r419565
........

Merged revisions 419565-419566 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419567 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
res/ari/ari_model_validators.c
res/ari/ari_model_validators.h
res/res_stasis_recording.c
rest-api/api-docs/recordings.json

diff --git a/CHANGES b/CHANGES
index 8770147..a8564b8 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -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
index d15ec49..0302db3 100644 (file)
@@ -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;
index c851156..0186168 100644 (file)
@@ -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)
index 55954cd..f749743 100644 (file)
@@ -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);
 }
index 54daa33..b0a6566 100644 (file)
                                        "description": "URI for the channel or bridge being recorded"
                                },
                                "state": {
-                                       "required": false,
+                                       "required": true,
                                        "type": "string",
                                        "allowableValues": {
                                                "valueType": "LIST",
                                                ]
                                        }
                                },
+                               "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"
                                }
                        }
                }