Freeswitch播放音乐文件的扩展方案记录

需求:选中多个播放终端,通过会议呼叫多个终端,在呼叫接通后,播放指定的音乐文件。


思路:通过动态拨号计划,下发播放指令和指定的终端进行文件播放。

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 *threadvoid *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

请先登录后发表评论
  • 最新评论
  • 总共0条评论