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

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


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

PHP控制的拨号计划:

//通过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

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);
		}
	}
}


修改:给会议根据播放控制动态播放音乐文件。

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

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