mirror of
https://github.com/jambonz/freeswitch-modules.git
synced 2026-01-25 02:08:27 +00:00
Fix/audio pipe (#4)
* use explicit namespaces for mod_audio_fork * fix crash in reload scenarios Signed-off-by: Dave Horton <daveh@beachdognet.com> --------- Signed-off-by: Dave Horton <daveh@beachdognet.com>
This commit is contained in:
@@ -102,11 +102,12 @@ namespace {
|
||||
return path;
|
||||
}
|
||||
|
||||
static void eventCallback(const char* sessionId, assemblyai::AudioPipe::NotifyEvent_t event, const char* message, bool finished) {
|
||||
static void eventCallback(const char* sessionId, const char* bugname,
|
||||
assemblyai::AudioPipe::NotifyEvent_t event, const char* message, bool finished) {
|
||||
switch_core_session_t* session = switch_core_session_locate(sessionId);
|
||||
if (session) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_media_bug_t *bug = (switch_media_bug_t*) switch_channel_get_private(channel, MY_BUG_NAME);
|
||||
switch_media_bug_t *bug = (switch_media_bug_t*) switch_channel_get_private(channel, bugname);
|
||||
if (bug) {
|
||||
private_t* tech_pvt = (private_t*) switch_core_media_bug_get_user_data(bug);
|
||||
if (tech_pvt) {
|
||||
@@ -194,7 +195,8 @@ namespace {
|
||||
tech_pvt->channels = channels;
|
||||
tech_pvt->id = ++idxCallCount;
|
||||
tech_pvt->buffer_overrun_notified = 0;
|
||||
|
||||
strncpy(tech_pvt->bugname, bugname, MAX_BUG_LEN);
|
||||
|
||||
size_t buflen = LWS_PRE + (FRAME_SIZE_8000 * desiredSampling / 8000 * channels * 1000 / RTP_PACKETIZATION_PERIOD * nAudioBufferSecs);
|
||||
|
||||
const char* apiKey = switch_channel_get_variable(channel, "ASSEMBLYAI_API_KEY");
|
||||
@@ -204,7 +206,7 @@ namespace {
|
||||
return SWITCH_STATUS_FALSE;
|
||||
}
|
||||
|
||||
assemblyai::AudioPipe* ap = new assemblyai::AudioPipe(tech_pvt->sessionId, tech_pvt->host, tech_pvt->port, tech_pvt->path,
|
||||
assemblyai::AudioPipe* ap = new assemblyai::AudioPipe(tech_pvt->sessionId, bugname, tech_pvt->host, tech_pvt->port, tech_pvt->path,
|
||||
buflen, read_impl.decoded_bytes_per_packet, apiKey, eventCallback);
|
||||
if (!ap) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error allocating AudioPipe\n");
|
||||
@@ -251,7 +253,8 @@ extern "C" {
|
||||
switch_status_t aai_transcribe_init() {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "mod_assemblyai_transcribe: audio buffer (in secs): %d secs\n", nAudioBufferSecs);
|
||||
|
||||
int logs = LLL_ERR | LLL_WARN | LLL_NOTICE || LLL_INFO | LLL_PARSER | LLL_HEADER | LLL_EXT | LLL_CLIENT | LLL_LATENCY | LLL_DEBUG ;
|
||||
int logs = LLL_ERR | LLL_WARN | LLL_NOTICE ;
|
||||
//| LLL_INFO | LLL_PARSER | LLL_HEADER | LLL_EXT | LLL_CLIENT | LLL_LATENCY | LLL_DEBUG ;
|
||||
|
||||
assemblyai::AudioPipe::initialize(logs, lws_logger);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "AudioPipe::initialize completed\n");
|
||||
@@ -306,7 +309,7 @@ extern "C" {
|
||||
|
||||
switch_status_t aai_transcribe_session_stop(switch_core_session_t *session,int channelIsClosing, char* bugname) {
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_media_bug_t *bug = (switch_media_bug_t*) switch_channel_get_private(channel, MY_BUG_NAME);
|
||||
switch_media_bug_t *bug = (switch_media_bug_t*) switch_channel_get_private(channel, bugname);
|
||||
if (!bug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "aai_transcribe_session_stop: no bug - websocket conection already closed\n");
|
||||
return SWITCH_STATUS_FALSE;
|
||||
|
||||
@@ -72,7 +72,7 @@ int AudioPipe::lws_callback(struct lws *wsi,
|
||||
lwsl_err("AudioPipe::lws_service_thread LWS_CALLBACK_CLIENT_CONNECTION_ERROR: %s, response status %d\n", in ? (char *)in : "(null)", rc);
|
||||
if (ap) {
|
||||
ap->m_state = LWS_CLIENT_FAILED;
|
||||
ap->m_callback(ap->m_uuid.c_str(), AudioPipe::CONNECT_FAIL, (char *) in, ap->isFinished());
|
||||
ap->m_callback(ap->m_uuid.c_str(), ap->m_bugname.c_str(), AudioPipe::CONNECT_FAIL, (char *) in, ap->isFinished());
|
||||
}
|
||||
else {
|
||||
lwsl_err("AudioPipe::lws_service_thread LWS_CALLBACK_CLIENT_CONNECTION_ERROR unable to find wsi %p..\n", wsi);
|
||||
@@ -87,7 +87,7 @@ int AudioPipe::lws_callback(struct lws *wsi,
|
||||
*ppAp = ap;
|
||||
ap->m_vhd = vhd;
|
||||
ap->m_state = LWS_CLIENT_CONNECTED;
|
||||
ap->m_callback(ap->m_uuid.c_str(), AudioPipe::CONNECT_SUCCESS, NULL, ap->isFinished());
|
||||
ap->m_callback(ap->m_uuid.c_str(), ap->m_bugname.c_str(), AudioPipe::CONNECT_SUCCESS, NULL, ap->isFinished());
|
||||
}
|
||||
else {
|
||||
lwsl_err("AudioPipe::lws_service_thread LWS_CALLBACK_CLIENT_ESTABLISHED %s unable to find wsi %p..\n", ap->m_uuid.c_str(), wsi);
|
||||
@@ -105,12 +105,12 @@ int AudioPipe::lws_callback(struct lws *wsi,
|
||||
// closed by us
|
||||
|
||||
lwsl_debug("%s socket closed by us\n", ap->m_uuid.c_str());
|
||||
ap->m_callback(ap->m_uuid.c_str(), AudioPipe::CONNECTION_CLOSED_GRACEFULLY, NULL, ap->isFinished());
|
||||
ap->m_callback(ap->m_uuid.c_str(), ap->m_bugname.c_str(), AudioPipe::CONNECTION_CLOSED_GRACEFULLY, NULL, ap->isFinished());
|
||||
}
|
||||
else if (ap->m_state == LWS_CLIENT_CONNECTED) {
|
||||
// closed by far end
|
||||
lwsl_info("%s socket closed by far end\n", ap->m_uuid.c_str());
|
||||
ap->m_callback(ap->m_uuid.c_str(), AudioPipe::CONNECTION_DROPPED, NULL, ap->isFinished());
|
||||
ap->m_callback(ap->m_uuid.c_str(), ap->m_bugname.c_str(), AudioPipe::CONNECTION_DROPPED, NULL, ap->isFinished());
|
||||
}
|
||||
ap->m_state = LWS_CLIENT_DISCONNECTED;
|
||||
ap->setClosed();
|
||||
@@ -172,7 +172,7 @@ int AudioPipe::lws_callback(struct lws *wsi,
|
||||
if (lws_is_final_fragment(wsi)) {
|
||||
if (nullptr != ap->m_recv_buf) {
|
||||
std::string msg((char *)ap->m_recv_buf, ap->m_recv_buf_ptr - ap->m_recv_buf);
|
||||
ap->m_callback(ap->m_uuid.c_str(), AudioPipe::MESSAGE, msg.c_str(), ap->isFinished());
|
||||
ap->m_callback(ap->m_uuid.c_str(), ap->m_bugname.c_str(), AudioPipe::MESSAGE, msg.c_str(), ap->isFinished());
|
||||
if (nullptr != ap->m_recv_buf) free(ap->m_recv_buf);
|
||||
}
|
||||
ap->m_recv_buf = ap->m_recv_buf_ptr = nullptr;
|
||||
@@ -261,6 +261,7 @@ static const lws_retry_bo_t retry = {
|
||||
};
|
||||
|
||||
struct lws_context *AudioPipe::context = nullptr;
|
||||
std::thread AudioPipe::serviceThread;
|
||||
std::string AudioPipe::protocolName;
|
||||
std::mutex AudioPipe::mutex_connects;
|
||||
std::mutex AudioPipe::mutex_disconnects;
|
||||
@@ -429,26 +430,28 @@ bool AudioPipe::lws_service_thread() {
|
||||
|
||||
void AudioPipe::initialize(int loglevel, log_emit_function logger) {
|
||||
|
||||
lws_set_log_level(loglevel, logger);
|
||||
//lws_set_log_level(loglevel, logger);
|
||||
|
||||
lwsl_notice("AudioPipe::initialize starting\n");
|
||||
std::lock_guard<std::mutex> lock(mapMutex);
|
||||
std::thread t(&AudioPipe::lws_service_thread);
|
||||
stopFlag = false;
|
||||
t.detach();
|
||||
serviceThread = std::thread(&AudioPipe::lws_service_thread);
|
||||
}
|
||||
|
||||
bool AudioPipe::deinitialize() {
|
||||
lwsl_notice("AudioPipe::deinitialize\n");
|
||||
std::lock_guard<std::mutex> lock(mapMutex);
|
||||
stopFlag = true;
|
||||
if (serviceThread.joinable()) {
|
||||
serviceThread.join();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// instance members
|
||||
AudioPipe::AudioPipe(const char* uuid, const char* host, unsigned int port, const char* path,
|
||||
AudioPipe::AudioPipe(const char* uuid, const char* bugname, const char* host, unsigned int port, const char* path,
|
||||
size_t bufLen, size_t minFreespace, const char* apiKey, notifyHandler_t callback) :
|
||||
m_uuid(uuid), m_host(host), m_port(port), m_path(path), m_finished(false),
|
||||
m_uuid(uuid), m_host(host), m_port(port), m_path(path), m_finished(false), m_bugname(bugname),
|
||||
m_audio_buffer_min_freespace(minFreespace), m_audio_buffer_max_len(bufLen), m_gracefulShutdown(false),
|
||||
m_audio_buffer_write_offset(LWS_PRE), m_recv_buf(nullptr), m_recv_buf_ptr(nullptr),
|
||||
m_state(LWS_CLIENT_IDLE), m_wsi(nullptr), m_vhd(nullptr), m_apiKey(apiKey), m_callback(callback) {
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
MESSAGE
|
||||
};
|
||||
typedef void (*log_emit_function)(int level, const char *line);
|
||||
typedef void (*notifyHandler_t)(const char *sessionId, NotifyEvent_t event, const char* message, bool finished);
|
||||
typedef void (*notifyHandler_t)(const char *sessionId,const char* bugname, NotifyEvent_t event, const char* message, bool finished);
|
||||
|
||||
struct lws_per_vhost_data {
|
||||
struct lws_context *context;
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
static bool lws_service_thread();
|
||||
|
||||
// constructor
|
||||
AudioPipe(const char* uuid, const char* host, unsigned int port, const char* path,
|
||||
AudioPipe(const char* uuid, const char* bugname, const char* host, unsigned int port, const char* path,
|
||||
size_t bufLen, size_t minFreespace, const char* apiKey, notifyHandler_t callback);
|
||||
~AudioPipe();
|
||||
|
||||
@@ -86,6 +86,7 @@ public:
|
||||
void operator=(const AudioPipe&) = delete;
|
||||
|
||||
private:
|
||||
static std::thread serviceThread;
|
||||
|
||||
static int lws_callback(struct lws *wsi, enum lws_callback_reasons reason, void *user, void *in, size_t len);
|
||||
static struct lws_context *context;
|
||||
|
||||
@@ -74,7 +74,7 @@ static switch_status_t start_capture(switch_core_session_t *session, switch_medi
|
||||
void *pUserData;
|
||||
uint32_t samples_per_second;
|
||||
|
||||
if (switch_channel_get_private(channel, MY_BUG_NAME)) {
|
||||
if (switch_channel_get_private(channel, bugname)) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "removing bug from previous transcribe\n");
|
||||
do_stop(session, bugname);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ static switch_status_t start_capture(switch_core_session_t *session, switch_medi
|
||||
if ((status = switch_core_media_bug_add(session, "aai_transcribe", NULL, capture_callback, pUserData, 0, flags, &bug)) != SWITCH_STATUS_SUCCESS) {
|
||||
return status;
|
||||
}
|
||||
switch_channel_set_private(channel, MY_BUG_NAME, bug);
|
||||
switch_channel_set_private(channel, bugname, bug);
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "added media bug for assemblyai transcribe\n");
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
@@ -105,7 +105,7 @@ static switch_status_t do_stop(switch_core_session_t *session, char* bugname)
|
||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||
|
||||
switch_channel_t *channel = switch_core_session_get_channel(session);
|
||||
switch_media_bug_t *bug = switch_channel_get_private(channel, MY_BUG_NAME);
|
||||
switch_media_bug_t *bug = switch_channel_get_private(channel, bugname);
|
||||
|
||||
if (bug) {
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Received user command command to stop transcribe.\n");
|
||||
|
||||
Reference in New Issue
Block a user