-
Notifications
You must be signed in to change notification settings - Fork 929
pjsua: Add audio play/rec commands to CLI framework #4723
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
ba603d5
65a77f4
d339ebf
a145ec7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -192,12 +192,56 @@ static void on_call_state(pjsua_call_id call_id, pjsip_event *e) | |||||||
| pjsip_endpt_cancel_timer(endpt, &cd->timer); | ||||||||
| } | ||||||||
|
|
||||||||
| /* Rewind play file when hangup automatically, | ||||||||
| /* Rewind play file when hangup automatically, | ||||||||
| * since file is not looped | ||||||||
| */ | ||||||||
| if (app_config.auto_play_hangup) | ||||||||
| pjsua_player_set_pos(app_config.wav_id, 0); | ||||||||
|
|
||||||||
| /* Cleanup dynamic playback if attached to this call */ | ||||||||
| if (app_config.dyn_player_active && | ||||||||
| app_config.dyn_player_call == call_id) | ||||||||
| { | ||||||||
| PJ_LOG(3, (THIS_FILE, "Call ended, stopping playback")); | ||||||||
|
|
||||||||
| /* Disconnect and destroy player if created */ | ||||||||
| if (app_config.dyn_player_id != PJSUA_INVALID_ID) { | ||||||||
| /* Destroy player (connections to call's slot will be cleaned | ||||||||
| * up automatically as the call is terminating) */ | ||||||||
| pjsua_player_destroy(app_config.dyn_player_id); | ||||||||
| } | ||||||||
|
|
||||||||
| /* Reset state */ | ||||||||
| app_config.dyn_player_id = PJSUA_INVALID_ID; | ||||||||
| app_config.dyn_player_port = PJSUA_INVALID_ID; | ||||||||
| app_config.dyn_player_call = PJSUA_INVALID_ID; | ||||||||
| app_config.dyn_player_active = PJ_FALSE; | ||||||||
| app_config.dyn_play_filename[0] = '\0'; | ||||||||
| } | ||||||||
|
|
||||||||
| /* Cleanup dynamic recording if attached to this call */ | ||||||||
| if (app_config.dyn_rec_active && | ||||||||
| app_config.dyn_rec_call == call_id) | ||||||||
| { | ||||||||
| PJ_LOG(3, (THIS_FILE, "Call ended, stopping recording")); | ||||||||
|
|
||||||||
| /* Disconnect and destroy recorder if created */ | ||||||||
| if (app_config.dyn_rec_id != PJSUA_INVALID_ID) { | ||||||||
| /* Disconnect microphone from recorder (mic is always slot 0) | ||||||||
| * (call's slot is being torn down, so that disconnects automatically) */ | ||||||||
| pjsua_conf_disconnect(0, app_config.dyn_rec_port); | ||||||||
|
|
||||||||
| /* Destroy recorder */ | ||||||||
| pjsua_recorder_destroy(app_config.dyn_rec_id); | ||||||||
| } | ||||||||
|
|
||||||||
| /* Reset state */ | ||||||||
| app_config.dyn_rec_id = PJSUA_INVALID_ID; | ||||||||
| app_config.dyn_rec_port = PJSUA_INVALID_ID; | ||||||||
| app_config.dyn_rec_call = PJSUA_INVALID_ID; | ||||||||
| app_config.dyn_rec_active = PJ_FALSE; | ||||||||
| app_config.dyn_rec_filename[0] = '\0'; | ||||||||
| } | ||||||||
|
|
||||||||
| PJ_LOG(3,(THIS_FILE, "Call %d is DISCONNECTED [reason=%d (%.*s)]", | ||||||||
| call_id, | ||||||||
|
|
@@ -423,6 +467,41 @@ static void on_call_audio_state(pjsua_call_info *ci, unsigned mi, | |||||||
| pjsua_conf_connect(call_conf_slot, app_config.rec_port); | ||||||||
| } | ||||||||
|
|
||||||||
| /* Dynamic recording - start if queued */ | ||||||||
| if (app_config.dyn_rec_active && | ||||||||
| app_config.dyn_rec_id == PJSUA_INVALID_ID && | ||||||||
| app_config.dyn_rec_filename[0] != '\0') | ||||||||
| { | ||||||||
| pj_status_t status; | ||||||||
| pjsua_recorder_id rec_id; | ||||||||
| pjsua_conf_port_id rec_port; | ||||||||
| pj_str_t rec_file; | ||||||||
|
|
||||||||
| /* Create recorder */ | ||||||||
| rec_file = pj_str(app_config.dyn_rec_filename); | ||||||||
| status = pjsua_recorder_create(&rec_file, 0, NULL, 0, 0, &rec_id); | ||||||||
| if (status == PJ_SUCCESS) { | ||||||||
| rec_port = pjsua_recorder_get_conf_port(rec_id); | ||||||||
|
|
||||||||
| /* Connect call to recorder */ | ||||||||
| pjsua_conf_connect(call_conf_slot, rec_port); | ||||||||
|
|
||||||||
| /* Connect microphone to recorder */ | ||||||||
| pjsua_conf_connect(0, rec_port); | ||||||||
|
|
||||||||
| /* Save state */ | ||||||||
| app_config.dyn_rec_id = rec_id; | ||||||||
| app_config.dyn_rec_port = rec_port; | ||||||||
| app_config.dyn_rec_call = ci->id; | ||||||||
|
|
||||||||
| PJ_LOG(3, (THIS_FILE, "Dynamic recording auto-started")); | ||||||||
| } else { | ||||||||
| PJ_LOG(2, (THIS_FILE, "Failed to auto-start recording: %d", status)); | ||||||||
| app_config.dyn_rec_active = PJ_FALSE; | ||||||||
| app_config.dyn_rec_filename[0] = '\0'; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| /* Record audio into AVI, if desired */ | ||||||||
| if (app_config.avi_auto_rec && app_config.avi_rec_audio && | ||||||||
| app_config.avi_aud_slot != PJSUA_INVALID_ID) | ||||||||
|
|
@@ -431,13 +510,49 @@ static void on_call_audio_state(pjsua_call_info *ci, unsigned mi, | |||||||
| } | ||||||||
|
|
||||||||
| /* Stream a file, if desired */ | ||||||||
| if ((app_config.auto_play || app_config.auto_play_hangup) && | ||||||||
| if ((app_config.auto_play || app_config.auto_play_hangup) && | ||||||||
| app_config.wav_port != PJSUA_INVALID_ID) | ||||||||
| { | ||||||||
| pjsua_conf_connect(app_config.wav_port, call_conf_slot); | ||||||||
| connect_sound = PJ_FALSE; | ||||||||
| } | ||||||||
|
|
||||||||
| /* Dynamic playback - start if queued */ | ||||||||
| if (app_config.dyn_player_active && | ||||||||
| app_config.dyn_player_id == PJSUA_INVALID_ID && | ||||||||
| app_config.dyn_play_filename[0] != '\0') | ||||||||
| { | ||||||||
| pj_status_t status; | ||||||||
| pjsua_player_id player_id; | ||||||||
| pjsua_conf_port_id player_port; | ||||||||
| pj_str_t play_file; | ||||||||
|
|
||||||||
| /* Create player */ | ||||||||
| play_file = pj_str(app_config.dyn_play_filename); | ||||||||
| status = pjsua_player_create(&play_file, 0, &player_id); | ||||||||
| if (status == PJ_SUCCESS) { | ||||||||
| player_port = pjsua_player_get_conf_port(player_id); | ||||||||
|
|
||||||||
| /* Connect player to call */ | ||||||||
| pjsua_conf_connect(player_port, call_conf_slot); | ||||||||
|
|
||||||||
| /* Disconnect microphone (like auto-play) */ | ||||||||
| pjsua_conf_disconnect(0, call_conf_slot); | ||||||||
|
|
||||||||
| /* Save state */ | ||||||||
| app_config.dyn_player_id = player_id; | ||||||||
| app_config.dyn_player_port = player_port; | ||||||||
| app_config.dyn_player_call = ci->id; | ||||||||
|
|
||||||||
| PJ_LOG(3, (THIS_FILE, "Dynamic playback auto-started")); | ||||||||
| connect_sound = PJ_FALSE; | ||||||||
| } else { | ||||||||
| PJ_LOG(2, (THIS_FILE, "Failed to auto-start playback: %d", status)); | ||||||||
| app_config.dyn_player_active = PJ_FALSE; | ||||||||
|
||||||||
| app_config.dyn_player_active = PJ_FALSE; | |
| app_config.dyn_player_active = PJ_FALSE; | |
| app_config.dyn_play_filename[0] = '\0'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When auto-start of recording fails and dyn_rec_active is set to FALSE (line 500), the dyn_rec_filename is not cleared. This creates an inconsistent state. The filename should be cleared along with the active flag to maintain consistency.