2017-08-06 862 views
0

我试着用它来说话。 的是Android SIP客户端和服务器的SIP(FreeSWITCH的) 我mod_conference有它:我该怎么做一键通,对讲机(PTT)使用freeswitch mod_conference

文件conference.conf.xml

<group name="radio"> 
     <control action="mute" digits="0"/> 
     <control action="deaf mute" digits="*"/> 
     <control action="energy up" digits="9"/> 
     <control action="energy equ" digits="8"/> 
     <control action="energy dn" digits="7"/> 
     <control action="vol talk up" digits="3"/> 
     <control action="vol talk zero" digits="2"/> 
     <control action="vol talk dn" digits="1"/> 
     <control action="vol listen up" digits="6"/> 
     <control action="vol listen zero" digits="5"/> 
     <control action="vol listen dn" digits="4"/> 
     <control action="hangup" digits="#"/> 
    </group> 

profile 

    <profile name="radio"> 
    <param name="caller-controls" value="radio"/> 
    </profile> 

my dialplan 

    <include> 
    <extension name="radio_conference"> 
    <condition field="destination_number" expression="^1337$"/> 
    <condition field="source" expression="mod_portaudio" break="never"> 
     <action application="perl" data="$${script_dir}/radio.pl"/> 
     <action application="answer"/> 
     <action application="sleep" data="1000"/> 
     <action application="start_dtmf"/> 
     </condition> 
     <condition> 
     <action application="conference" data="[email protected]"/> 
     </condition> 
    </extension> 
    </include> 

我的脚本radio.pl

use Device::SerialPins; 
    use Getopt::Std; 
    use strict; 
    use FreeSWITCH::Client; 
    use POSIX ':signal_h'; # used for alarm to ensure we get heartbeats 
    use Switch; 
    use Data::Dumper; # used to print out myhash debug info 
    use File::stat; 


    my $password = "1234"; # event socket password 
    my $host  = "192.168.100.228"; # event socket host 
    my $port  = 8021;   # event socket port 
    my $device = undef;  # radio control device (/dev/ttyS0, COM1,  etc) 
    my $baud  = 9600;   # radio control device baud rate 
    my $timeout = 30;   # seconds to expect a heartbeat or  reconnect 
    my $courtesy_tone = "tone_stream://%(150,150,500);%(150,0,400)"; # tone played before releasing PTT 
    my $confname = "radio";  # the name of the conference 
    my $extension = "1337";  # this is the extension that portaudio will call to join 
    my $callsign = undef;  # disable callsign autoID - set to your callsign 
    my $callsign_interval = 600; # 10 minute intervals 


# for TTS anouncements played after CWID - undef to disable 
    my $voice = "Allison"; 
    my $swift = "/opt/swift/bin/swift"; 
    my $filetime = 0; 


# normal users do not need to edit anything below here 
    my %options; 
    my $fs; 
    my $lastheartbeat; 
    my $lastcallsign; 
    my $lasttx; 
    my $releasePTT=0; 
    my $ptt_port; 



    sub pressPTT() 
    { 
    $ptt_port->set_rts(1); 
    } 

    sub releasePTT() 
    { 
    $ptt_port->set_rts(0); 
    } 


# this connects to the event socket 
    sub es_connect() 
    { 
    print "Connecting to $host:$port\n"; 
    eval { 
     $fs = init FreeSWITCH::Client {-password => $password, -host => $host, -port => $port}; 
     if(defined $fs) { 
      $fs->sendmsg({'command' => 'event plain heartbeat CUSTOM conference::maintenance'}); 
      $lastheartbeat = time; 
     } 
    } or do { 
     print "Error connecting - waiting for retry\n"; 
     sleep(10); 
    } 
    } 


    sigaction SIGALRM, new POSIX::SigAction sub { 
     if ($lastheartbeat < (time - $timeout)) { 
     print "Did not receive a heartbeat in the specified timeout\n"; 
     if (defined $fs) { 
      $fs->disconnect(); 
      undef $fs; 
     } 
     es_connect(); 
    } 

    if(defined $callsign && $lastcallsign < (time - $callsign_interval) && $lasttx > $lastcallsign) { 
     pressPTT(); 
     $fs->command("jsapi morse.js conference radio ".$callsign); 
     $lastcallsign = time; 
     $releasePTT++; 


     if (-f "announcement.txt") { 
      if(stat("announcement.txt")->mtime > $filetime && defined  $voice $$ defined $swift) { 
       system("$swift -p audio/deadair=2000,audio/sampling- rate=8000,audio/channels=1,audio/encoding=pcm16,audio/output-format=raw -o /tmp/announcement.raw -f announcement.txt -n $voice"); 
        $fs->command("conference ".$confname." play /tmp/announcement.raw"); 
      } 
     } 
     } 

    # reset the alarm 
     alarm $timeout; 
    } or die "Error setting SIGALRM handler: $!\n"; 

    sub usage() 
    { 
     print "Usage: $0 [-p pass] [-P port] [-H host] [-d device] [-b baud]\n"; 
    print "example: $0 -p password -P 8021 -H localhost -d /dev/ttyS0 -b  38400\n"; 
    exit; 
    } 


    sub checkArgs() 
     { 
     getopts("p:P:H:d:b:h",\%options); 
     usage() if defined $options{h}; 
     $password = $options{p} if defined $options{p}; 
     $host = $options{H} if defined $options{H}; 
     $port = $options{P} if defined $options{P}; 
     $device = $options{d} if defined $options{d}; 
     $baud = $options{b} if defined $options{b}; 

     if(! defined $device || ! defined $password || 
     ! defined $host || ! defined $port) { 
     usage(); 
     exit; 
     } 
     } 


     checkArgs(); 
     $ptt_port = Device::SerialPins->new($device); 
     releasePTT(); 
     es_connect(); 
     alarm $timeout; 



     $SIG{INT} = "byebye";  # traps keyboard interrupt (^C) 

     sub byebye { 
     if(defined $fs) { 
     $fs->command("pa hangup"); 
     } 
     exit(); 
     } 


     if(defined $fs) { 
     $fs->command("pa call ".$extension); 
     } else { 
     print "Unable to start portaudio channel\n"; 
     } 

     $lastcallsign = time; 

    while (1) { 
    if(defined $fs) { 
     my $reply = $fs->readhash(undef); 
     if ($reply->{socketerror}) { 
      es_connect(); 
     } 

     if($reply->{body}) { 
      my $myhash = $reply->{event}; 

      if ($myhash->{'event-name'} eq "HEARTBEAT") { 
       $lastheartbeat = time; 
      } elsif ($myhash->{'event-subclass'} eq "conference::maintenance") { 
       if($myhash->{'conference-name'} eq $confname) { 
        if($myhash->{'caller-channel-name'} =~ m/^portaudio/)  { 
         # this is from the radio 
         if($myhash->{'action'} eq 'dtmf') { 
          switch($myhash->{'dtmf-key'}) { 
           # I will be adding some "dial"  instructions for autopatch 
           # and maybe some other settings here 
          } 
         } 
        } else { 
         # this is from everyone else 
         if ($myhash->{'action'} eq 'start-talking') { 
          print "The port is talking! keying mic\n"; 
          $lasttx = time; 
          pressPTT(); 
         } elsif ($myhash->{'action'} eq 'stop-talking') { 
          print "The port stopped talking! releasing mic\n"; 
          if(defined $courtesy_tone) { 
           $fs->command("conference ".$confname." play ".$courtesy_tone); 
           $releasePTT++; 
          } 
         } 
        } 

        if($myhash->{'action'} eq 'dtmf') { 
         print "conf: $myhash->{'conference-name'}\tmember:  $myhash->{'member-id'}\tDTMF: $myhash->{'dtmf-key'}\n"; 
        } elsif ($myhash->{'action'} eq 'play-file') { 
         print "conf: $myhash->{'conference-name'}\taction: $myhash->{'action'}\tfile: $myhash->{'file'}\n"; 
        } elsif ($myhash->{'action'} eq 'play-file-done') { 
         print "conf: $myhash->{'conference-name'}\taction: $myhash->{'action'}\tfile: $myhash->{'file'}\n"; 
         if($releasePTT>0) { 
          $releasePTT--; 
         } 
    print "release PTT: $releasePTT\n"; 
         if($releasePTT==0) { 
          releasePTT(); 
         } 
        } else { 
         print "conf: $myhash->{'conference-name'}\tmemid:  $myhash->{'member-id'}\taction: $myhash->{'action'}\tCLID: $myhash->  {'caller-caller-id-number'}\n"; 
        } 
       } else { 
        print "conf: $myhash->{'conference-name'}\tmemid:  $myhash->{'member-id'}\taction: $myhash->{'action'}\tCLID: $myhash->  {'caller-caller-id-number'}\n"; 
       } 
      } else { 
       print Dumper $myhash; 
      } 
     } 
     } else { 
     es_connect(); 
     } 
     } 

现在我不在这一刻,我知道使用这个文件radio.pl我尝试了一个使用android sip的sip客户端,并且都在会议中成功了,但是现在我想配置一个会话并且每个人都在听,在这一刻所有人都在谈论和听取,请我需要帮助

感谢的

回答

0

我目前正试图完成相同的任务。我所做的一件事就是使用会议成员标志将静音的所有会员输入会议。当按下ptt按钮时,它将向会议发送dtmf“unmute”事件。

这样做的唯一问题是,当前正在参加会议的其他成员没有停止同时按下ptt按钮,因为另一个成员因此有两个会议同时在说话,是你不想要的

+0

是的这就是问题所在,但我认为解决方法是尝试从客户端sip中完成,在我的情况下为Android Sip,将播放纯旗,例如,如果我正在说话,然后我有一个Incomming Call不听。或者你怎么看? –

+0

但是我不知道如何制作它,实际上我使用的是Android的图书​​馆SIP,我正在使用这个库,这正是她的页面示例。我研究它,如果您发现任何关于在我说话时如何停止来电请帮助我。 –

+1

Bravo,在你的perl esl脚本里,你想要定义一个变量,每次人们按下特定会议中的即按即说按钮,例如$ conf_talkers ++;在此脚本中,您希望使用freeswitch conference api使用您从会议事件中获得的成员标识为该成员发送取消静音事件。如果您的$ conf_talkers变量等于1,只允许发生取消静音事件。 – ToyeO