[Asterisk-cvs] asterisk/apps app_meetme.c,1.71,1.72

markster at lists.digium.com markster at lists.digium.com
Fri Jan 21 22:48:41 CST 2005


Update of /usr/cvsroot/asterisk/apps
In directory mongoose.digium.com:/tmp/cvs-serv27602/apps

Modified Files:
	app_meetme.c 
Log Message:
Add option for recording conference (bug #3393), thanks moc!


Index: app_meetme.c
===================================================================
RCS file: /usr/cvsroot/asterisk/apps/app_meetme.c,v
retrieving revision 1.71
retrieving revision 1.72
diff -u -d -r1.71 -r1.72
--- app_meetme.c	21 Jan 2005 07:06:24 -0000	1.71
+++ app_meetme.c	22 Jan 2005 04:51:30 -0000	1.72
@@ -70,6 +70,9 @@
 "      'e' -- select an empty conference\n"
 "      'E' -- select an empty pinless conference\n"
 "      'v' -- video mode\n"
+"      'r' -- Record conference (records as ${MEETME_RECORDINGFILE}\n"
+"             using format ${MEETME_RECORDINGFORMAT}). Default filename is\n"
+"             meetme-conf-rec-${CONFNO}-${UNIQUEID} and the default format is wav.\n"
 "      'q' -- quiet mode (don't play enter/leave sounds)\n"
 "      'M' -- enable music on hold when the conference has a single caller\n"
 "      'x' -- close the conference when last marked user exits\n"
@@ -114,8 +117,13 @@
 	struct ast_conf_user *firstuser;  /* Pointer to the first user struct */
 	struct ast_conf_user *lastuser;   /* Pointer to the last user struct */
 	time_t start;			/* Start time (s) */
+	int recording;			/* recording status */
 	int isdynamic;			/* Created on the fly? */
 	int locked;			  /* Is the conference locked? */
+	pthread_t recordthread;		/* thread for recording */
+	pthread_attr_t attr;		/* thread attribute */
+	char *recordingfilename;	/* Filename to record the Conference into */
+	char *recordingformat;		/* Format to record the Conference in */
 	char pin[AST_MAX_EXTENSION];			/* If protected by a PIN */
 	struct ast_conference *next;
 } *confs;
@@ -140,12 +148,18 @@
 
 static int admin_exec(struct ast_channel *chan, void *data);
 
+static void *recordthread(void *args);
+
 #include "enter.h"
 #include "leave.h"
 
 #define ENTER	0
 #define LEAVE	1
 
+#define MEETME_RECORD_OFF	0
+#define MEETME_RECORD_ACTIVE	1
+#define MEETME_RECORD_TERMINATE	2
+
 #define CONF_SIZE 320
 
 #define CONFFLAG_ADMIN	(1 << 1)	/* If set the user has admin access on the conference */
@@ -162,6 +176,7 @@
 #define CONFFLAG_EXIT_CONTEXT (1 << 12)	/* If set, the MeetMe will exit to the specified context */
 #define CONFFLAG_MARKEDUSER (1 << 13)	/* If set, the user will be marked */
 #define CONFFLAG_INTROUSER (1 << 14)	/* If set, user will be ask record name on entry of conference */
+#define CONFFLAG_RECORDCONF (1<< 15)	/* If set, the MeetMe will be recorded */
 
 static int careful_write(int fd, unsigned char *data, int len)
 {
@@ -244,7 +259,7 @@
 			/* Setup a new zap conference */
 			ztc.chan = 0;
 			ztc.confno = -1;
-			ztc.confmode = ZT_CONF_CONFANN;
+			ztc.confmode = ZT_CONF_CONFANN | ZT_CONF_CONFANNMON;
 			if (ioctl(cnf->fd, ZT_SETCONF, &ztc)) {
 				ast_log(LOG_WARNING, "Error setting conference\n");
 				if (cnf->chan)
@@ -528,6 +543,7 @@
 	char *agifiledefault = "conf-background.agi";
 	char meetmesecs[30] = "";
 	char exitcontext[AST_MAX_EXTENSION] = "";
+	char recordingtmp[AST_MAX_EXTENSION] = "";
 	int dtmf;
 
 	ZT_BUFFERINFO bi;
@@ -540,6 +556,23 @@
 	}
 	memset(user, 0, sizeof(struct ast_conf_user));
 
+	if (confflags & CONFFLAG_RECORDCONF && conf->recording !=MEETME_RECORD_ACTIVE) {
+		conf->recordingfilename = pbx_builtin_getvar_helper(chan,"MEETME_RECORDINGFILE");
+		if (!conf->recordingfilename) {
+			snprintf(recordingtmp,sizeof(recordingtmp),"meetme-conf-rec-%s-%s",conf->confno,chan->uniqueid);
+			conf->recordingfilename = ast_strdupa(recordingtmp);
+		}
+		conf->recordingformat = pbx_builtin_getvar_helper(chan, "MEETME_RECORDINGFORMAT");
+		if (!conf->recordingformat) {
+			snprintf(recordingtmp,sizeof(recordingtmp), "wav");
+			conf->recordingformat = ast_strdupa(recordingtmp);
+		}
+		pthread_attr_init(&conf->attr);
+		pthread_attr_setdetachstate(&conf->attr, PTHREAD_CREATE_DETACHED);
+		ast_verbose(VERBOSE_PREFIX_4 "Starting recording of MeetMe Conference %s into file %s.%s.\n", conf->confno, conf->recordingfilename, conf->recordingformat);
+		ast_pthread_create(&conf->recordthread, &conf->attr, recordthread, conf);
+	}
+
 	user->user_no = 0; /* User number 0 means starting up user! (dead - not in the list!) */
 
 	time(&user->jointime);
@@ -1070,6 +1103,16 @@
 			}
 			if (!cur) 
 				ast_log(LOG_WARNING, "Conference not found\n");
+			if (conf->recording == MEETME_RECORD_ACTIVE) {
+				conf->recording = MEETME_RECORD_TERMINATE;
+				ast_mutex_unlock(&conflock);
+				while (1) {
+					ast_mutex_lock(&conflock);
+					if (conf->recording == MEETME_RECORD_OFF)
+						break;
+					ast_mutex_unlock(&conflock);
+				}
+			}
 			if (conf->chan)
 				ast_hangup(conf->chan);
 			else
@@ -1287,6 +1330,8 @@
 			confflags |= CONFFLAG_AGI;
 		if (strchr(inflags, 'w'))
 			confflags |= CONFFLAG_WAITMARKED;
+		if (strchr(inflags, 'r'))
+			confflags |= CONFFLAG_RECORDCONF;	
 		if (strchr(inflags, 'd'))
 			dynamic = 1;
 		if (strchr(inflags, 'D')) {
@@ -1613,6 +1658,45 @@
 	return 0;
 }
 
+static void *recordthread(void *args)
+{
+	struct ast_conference *cnf;
+	struct ast_frame *f=NULL;
+	int flags;
+	struct ast_filestream *s;
+	int res=0;
+
+	cnf = (struct ast_conference *)args;
+	ast_stopstream(cnf->chan);
+	flags = O_CREAT|O_TRUNC|O_WRONLY;
+	s = ast_writefile(cnf->recordingfilename, cnf->recordingformat, NULL, flags, 0, 0644);
+
+	if (s) {
+		cnf->recording = MEETME_RECORD_ACTIVE;
+		while (ast_waitfor(cnf->chan, -1) > -1) {
+			f = ast_read(cnf->chan);
+			if (!f) {
+				res = -1;
+				break;
+			}
+			if (f->frametype == AST_FRAME_VOICE) {
+				res = ast_writestream(s, f);
+				if (res) 
+					break;
+			}
+			ast_frfree(f);
+			if (cnf->recording == MEETME_RECORD_TERMINATE) {
+				ast_mutex_lock(&conflock);
+				ast_mutex_unlock(&conflock);
+				break;
+			}
+		}
+		cnf->recording = MEETME_RECORD_OFF;
+		ast_closestream(s);
+	}
+	pthread_exit(0);
+}
+
 int unload_module(void)
 {
 	STANDARD_HANGUP_LOCALUSERS;




More information about the svn-commits mailing list