需求:选中多个播放终端,通过会议呼叫多个终端,在呼叫接通后,播放指定的音乐文件。
思路:通过动态拨号计划,下发播放指令和指定的终端进行文件播放。
PHP控制的拨号计划:
1 2 3 4 5 6 7 8 9 10 | //通过conference_inject_music_play控制播放循环和播放曲目个数。 $ this ->Gateway_XML .= "\n<action application=\"conference_inject_music_play\" data=\"repeat=1&count=2\"/>" ; //需要修改主叫时,是sendonly $ this ->Gateway_XML .= "\n<action application=\"conference_inject_music_url\" data=\"/tmp/123.wav,/tmp/456.wav\"/>" ; //根据会议中的人员动态添加呼叫的对象 $ this ->Gateway_XML .= "\n<action application=\"conference_set_auto_outcall\" data=\"user/\${dialed_extension}@\${domain_name}\"/>" ; //进入会议 $ this ->Gateway_XML .= "\n<action application=\"conference\" data=\"999$1@default\"/>" ; |
修改conference_mod.c,添加conference_inject_music_api和conference_inject_music_url_api两个api
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | SWITCH_STANDARD_APP(conference_inject_music_api) { switch_channel_t *channel = switch_core_session_get_channel(session); char *play_url_string = NULL; play_url_string = switch_channel_get_private(channel, "_conference_inject_music_play_" ); if (zstr(data)) { play_url_string = NULL; } else { int repeat = 0; int mp3_count = 0; int count = 0; play_url_string = switch_core_session_strdup(session, data); count = sscanf (( char * )play_url_string, "repeat=%d&count=%d" , &repeat, &mp3_count); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "play_url_string:%s,count:%d, mp3_count:%d, repeat=%d.\n" , play_url_string, count, mp3_count, repeat); } switch_channel_set_private(channel, "_conference_inject_music_play_" , play_url_string); } SWITCH_STANDARD_APP(conference_inject_music_url_api) { switch_channel_t *channel = switch_core_session_get_channel(session); char *play_url_string = NULL; int repeat = 0; int mp3_count = 0; play_url_string = switch_channel_get_private(channel, "_conference_inject_music_play_" ); if (play_url_string != NULL){ int count = 0; count = sscanf (( char * )play_url_string, "repeat=%d&count=%d" , &repeat, &mp3_count); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference_inject_music_url_api :%s,count:%d, mp3_count:%d, repeat=%d.\n" , play_url_string, count, mp3_count, repeat); } if (zstr(data)) { play_url_string = NULL; } else { char *token; char *saveptr; char name_url[128]; char *play_url_list = switch_core_session_strdup(session, data); int i=0; token = strtok_r(play_url_list, "," , &saveptr); while (token) { sprintf (name_url, "_conference_inject_music_play_%d" , i++); switch_channel_set_private(channel, name_url, token); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "name_url:%s,name_url=%s.\n" , name_url, token); token = strtok_r(NULL, "," , &saveptr); } } } |
修改:给会议根据播放控制动态播放音乐文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /* marshall frames from the call leg to the conference thread for muxing to other call legs */ void *SWITCH_THREAD_FUNC conference_loop_music_play(switch_thread_t * thread , void *obj) { conference_member_t *member = obj; switch_channel_t *channel = NULL; char name_url[128]; int repeat = 0; int mp3_count = 0; int count = 0; int i = 0; char *play_url_string; channel = switch_core_session_get_channel(member->session); play_url_string = switch_channel_get_private(channel, "_conference_inject_music_play_" ); if (play_url_string == NULL){ return NULL; } count = sscanf (( char * )play_url_string, "repeat=%d&count=%d" , &repeat, &mp3_count); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference_loop_music_play loop:%s,count:%d, mp3_count:%d, repeat=%d.\n" , play_url_string, count, mp3_count, repeat); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference_loop_music_play loop: %d running:%d, read:%d \n" , member->loop_loop, conference_utils_member_test_flag(member, MFLAG_RUNNING), switch_channel_ready(channel)); while (conference_utils_member_test_flag(member, MFLAG_RUNNING) && switch_channel_ready(channel)) { char *play_url_path = NULL; const char *temp = NULL; sprintf (name_url, "_conference_inject_music_play_%d" , i++); temp = switch_channel_get_private(channel, name_url); if (temp == NULL){ break ; } play_url_path = switch_core_session_strdup(member->session, temp); conference_file_play(member->conference, ( char *)play_url_path, CONF_DEFAULT_LEADIN, NULL, 0); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "start play:%s \n" , play_url_path); //conference_file_local_play(member->conference, //member->session, (char *)play_url_path, CONF_DEFAULT_LEADIN, NULL, 0); switch_sleep(5000000); if (i == mp3_count){ if (repeat != 0){ i = 0; } else { break ; } } } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "conference_loop_music_play end.\n" ); conference_utils_member_clear_flag_locked(member, MFLAG_ITHREAD); return NULL; } /* launch an music thread for the conference */ void conference_loop_launch_music_play(conference_member_t *member, switch_memory_pool_t *pool) { switch_threadattr_t *thd_attr = NULL; if (member == NULL || member->music_thread) return ; switch_threadattr_create(&thd_attr, pool); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); conference_utils_member_set_flag_locked(member, MFLAG_ITHREAD); if (switch_thread_create(&member->music_thread, thd_attr, conference_loop_music_play, member, pool) != SWITCH_STATUS_SUCCESS) { conference_utils_member_clear_flag_locked(member, MFLAG_ITHREAD); } } 在conference_loop_output的合适地方添加下面的代码。 #if 1//start a thread to play files { char *play_url_string = switch_channel_get_private(channel, "_conference_inject_music_play_" ); if (play_url_string != NULL){ int repeat = 0; int mp3_count = 0; int count = 0; count = sscanf (( char * )play_url_string, "repeat=%d&count=%d" , &repeat, &mp3_count); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "loop:%s,count:%d, mp3_count:%d, repeat=%d.\n" , play_url_string, count, mp3_count, repeat); if (count > 0){ conference_loop_launch_music_play(member, switch_core_session_get_pool(member->session)); } } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "play_url_string is null.\n" ); } } #endif //add for play mp3 in conference |
验证OK。
但是格式只支持wav,后面使用playback的功能播放mp3文件。
-------------------广告线---------------
项目、合作,欢迎勾搭,邮箱:promall@qq.com
本文为呱牛笔记原创文章,转载无需和我联系,但请注明来自呱牛笔记 ,it3q.com