/** * Start execution of call output component * @param component to start * @param session the session to output to * @param output the output request * @param iq the original request */ static iks *start_call_output(struct rayo_component *component, switch_core_session_t *session, iks *output, iks *iq) { switch_stream_handle_t stream = { 0 }; /* acknowledge command */ rayo_component_send_start(component, iq); /* build playback command */ SWITCH_STANDARD_STREAM(stream); stream.write_function(&stream, "{id=%s,session=%s,pause=%s", RAYO_JID(component), switch_core_session_get_uuid(session), OUTPUT_COMPONENT(component)->start_paused ? "true" : "false"); if (OUTPUT_COMPONENT(component)->max_time > 0) { stream.write_function(&stream, ",timeout=%i", OUTPUT_COMPONENT(component)->max_time * 1000); } stream.write_function(&stream, "}fileman://rayo://%s", RAYO_JID(component)); if (switch_ivr_displace_session(session, stream.data, 0, "m") == SWITCH_STATUS_SUCCESS) { RAYO_UNLOCK(component); } else { if (OUTPUT_COMPONENT(component)->document) { iks_delete(OUTPUT_COMPONENT(component)->document); } if (switch_channel_get_state(switch_core_session_get_channel(session)) >= CS_HANGUP) { rayo_component_send_complete(component, COMPONENT_COMPLETE_HANGUP); component = NULL; } else { rayo_component_send_complete(component, COMPONENT_COMPLETE_ERROR); component = NULL; } } switch_safe_free(stream.data); return NULL; }
/** * Notify completion of record component */ static void complete_record(struct rayo_component *component, const char *reason, const char *reason_namespace) { switch_core_session_t *session = NULL; const char *uuid = component->parent->id; char *uri = switch_mprintf("file://%s", RECORD_COMPONENT(component)->local_file_path); iks *recording; switch_size_t file_size = 0; /* TODO this doesn't work with HTTP */ #if 0 switch_file_t *file; if (switch_file_open(&file, RECORD_COMPONENT(component)->local_file_path, SWITCH_FOPEN_READ, SWITCH_FPROT_UREAD, RAYO_POOL(component)) == SWITCH_STATUS_SUCCESS) { file_size = switch_file_get_size(file); switch_file_close(file); } else { switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_INFO, "Failed to open %s.\n", RECORD_COMPONENT(component)->local_file_path); } #endif switch_log_printf(SWITCH_CHANNEL_UUID_LOG(uuid), SWITCH_LOG_DEBUG, "Recording %s done.\n", RECORD_COMPONENT(component)->local_file_path); if (RECORD_COMPONENT(component)->stop_beep && (session = switch_core_session_locate(uuid))) { switch_ivr_displace_session(session, RECORD_BEEP, 0, ""); switch_core_session_rwunlock(session); } /* send complete event to client */ recording = iks_new("recording"); iks_insert_attrib(recording, "xmlns", RAYO_RECORD_COMPLETE_NS); iks_insert_attrib(recording, "uri", uri); iks_insert_attrib_printf(recording, "duration", "%i", RECORD_COMPONENT(component)->duration_ms); iks_insert_attrib_printf(recording, "size", "%"SWITCH_SIZE_T_FMT, file_size); rayo_component_send_complete_with_metadata(component, reason, reason_namespace, recording, 1); iks_delete(recording); RAYO_UNLOCK(component); switch_safe_free(uri); }
/** * Start recording call * @param session the session to record * @param record the record component */ static int start_call_record(switch_core_session_t *session, struct rayo_component *component) { struct record_component *record_component = RECORD_COMPONENT(component); switch_channel_t *channel = switch_core_session_get_channel(session); int max_duration_sec = 0; switch_channel_set_variable(channel, "RECORD_HANGUP_ON_ERROR", "false"); switch_channel_set_variable(channel, "RECORD_TOGGLE_ON_REPEAT", ""); switch_channel_set_variable(channel, "RECORD_CHECK_BRIDGE", ""); switch_channel_set_variable(channel, "RECORD_MIN_SEC", "0"); switch_channel_set_variable(channel, "RECORD_STEREO", ""); switch_channel_set_variable(channel, "RECORD_READ_ONLY", ""); switch_channel_set_variable(channel, "RECORD_WRITE_ONLY", ""); switch_channel_set_variable(channel, "RECORD_APPEND", ""); switch_channel_set_variable(channel, "RECORD_WRITE_OVER", "true"); switch_channel_set_variable(channel, "RECORD_ANSWER_REQ", ""); switch_channel_set_variable(channel, "RECORD_SILENCE_THRESHOLD", "200"); if (record_component->initial_timeout > 0) { switch_channel_set_variable_printf(channel, "RECORD_INITIAL_TIMEOUT_MS", "%i", record_component->initial_timeout); } else { switch_channel_set_variable(channel, "RECORD_INITIAL_TIMEOUT_MS", ""); } if (record_component->final_timeout > 0) { switch_channel_set_variable_printf(channel, "RECORD_FINAL_TIMEOUT_MS", "%i", record_component->final_timeout); } else { switch_channel_set_variable(channel, "RECORD_FINAL_TIMEOUT_MS", ""); } /* allow dialplan override for these variables */ //switch_channel_set_variable(channel, "RECORD_PRE_BUFFER_FRAMES", ""); //switch_channel_set_variable(channel, "record_sample_rate", ""); //switch_channel_set_variable(channel, "enable_file_write_buffering", ""); /* max duration attribute is in milliseconds- convert to seconds */ if (record_component->max_duration > 0) { max_duration_sec = ceil((double)(record_component->max_duration - record_component->duration_ms) / 1000.0); } if (!strcmp(record_component->direction, "duplex")) { if (!record_component->mix) { /* STEREO */ switch_channel_set_variable(channel, "RECORD_STEREO", "true"); } /* else MONO (default) */ } else if (!strcmp(record_component->direction, "send")) { /* record audio sent from the caller */ switch_channel_set_variable(channel, "RECORD_READ_ONLY", "true"); } else if (!strcmp(record_component->direction, "recv")) { /* record audio received by the caller */ switch_channel_set_variable(channel, "RECORD_WRITE_ONLY", "true"); }; if (record_component->start_beep) { switch_ivr_displace_session(session, RECORD_BEEP, 0, ""); record_component->start_time = switch_micro_time_now(); } if (switch_ivr_record_session(session, (char *)RAYO_ID(component), max_duration_sec, NULL) == SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Recording started: file = %s\n", RAYO_ID(component)); return 1; } return 0; }