Matthew, Johan, everyone,

I got it to work! :)  (With the help of a guy I hired via freelancer.com)

Time to share something with the community, so here are the pieces you need to create an open conference, where the users will be in the same conference, and at the same time will listen to an individual MP3 stream in the background, depending on which extension a user dials. Also, the volume of the stream is adjustable for each user separately via DTMF 1+2, and the speech in the conference is also adjustable individually via DTMF 4+5 and 7+8 (this is plain ConfBridge, no magic there).

Extensions 01 or 02 is what the user dials. If dialed 01, user will listen to stream 1, if dialed 02, user will listen to stream 2, but both users will be in the same conference and will not hear each others music, but only each others speech.


extensions.conf:

[macro-mohvolumeup]
exten => _.,1,NoOp(Increasing MOH volume...)
exten => _.,n,NoOp(...for extension ${sipexten} )
exten => _.,n,System(/var/lib/asterisk/agi-bin/mohvolume.php ${sipexten} up)

[macro-mohvolumedown]
exten => _.,1,NoOp(Decreasing MOH volume...)
exten => _.,n,NoOp(...for extension ${sipexten} )
exten => _.,n,System(/var/lib/asterisk/agi-bin/mohvolume.php ${sipexten} down)


[radio-chatfire]
exten => go-conference,1,Answer()
exten => go-conference,n,NoOp(MOH class is ${mohclass})
exten => go-conference,n,System(/var/lib/asterisk/agi-bin/playmoh.php ${sipexten} ${mohclass}) exten => go-conference,n,ConfBridge(11*48*79*32,,chatfire-public,chatfire-public-menu)

; chat, stream 1
exten => 01,1,NoOp(Dial)
exten => 01,n,Set(__sipexten=${CHANNEL})
exten => 01,n,Set(__DYNAMIC_FEATURES=mohvolumeup#mohvolumedown)
exten => 01,n,Set(__mohclass=chatfire-1)
exten => 01,n,NoOp(MOH class is ${mohclass})
exten => 01,n,Dial(Local/go-conference@radio-chatfire,,)

; chat, stream 2
exten => 02,1,NoOp(Dial)
exten => 02,n,Set(__sipexten=${CHANNEL})
exten => 02,n,Set(__DYNAMIC_FEATURES=mohvolumeup#mohvolumedown)
exten => 02,n,Set(__mohclass=chatfire-2)
exten => 02,n,NoOp(MOH class is ${mohclass})
exten => 02,n,Dial(Local/go-conference@radio-chatfire,,)

exten => 55555,1,Answer()
exten => 55555,n,Set(VOLUME(TX,p)=-3)
exten => 55555,n,NoOp(MOH class final is ${mohclass_final})
exten => 55555,n,MusicOnHold(${mohclass_final})


[whisper-chatfire]
exten => do_chanspy,1,NoOp()
exten => do_chanspy,n,Set(DB(moh_${sipexten}/channel)=${CHANNEL})
exten => do_chanspy,n,ChanSpy(${sipexten},${chanspyoption})
exten => do_chanspy,n,Hangup()

exten => do_moh,1,NoOp(Dial)
exten => do_moh,n,Set(__mohclass_final=${mohclass_play})
exten => do_moh,n,Dial(Local/55555@radio-chatfire)


manager.conf:

[general]
enabled=yes
port=5038
bindaddr=127.0.0.1

[manager]
secret=kkkkkkkkkk
allow=0.0.0.0/0.0.0.0
read = all,system,call,log,verbose,agent,user,config,dtmf,reporting,cdr,dialplan,originate
write = all,system,call,agent,user,config,command,reporting,originate


features.conf:

[applicationmap]
mohvolumeup => 1,self/caller,Macro,mohvolumeup
mohvolumedown => 2,self/caller,Macro,mohvolumedown


confbridge.conf:

[chatfire-public-menu]
type=menu
4=increase_listening_volume
5=decrease_listening_volume
7=increase_talking_volume
8=decrease_talking_volume

[chatfire-public]
type=user
announce_user_count=yes
dsp_drop_silence=yes


musiconhold.conf:

[chatfire-1]
mode=custom
application=/var/lib/asterisk/mohstream-chatfire-1.sh

[chatfire-2]
mode=custom
application=/var/lib/asterisk/mohstream-chatfire-2.sh



/var/lib/asterisk/agi-bin/playmoh.php:

#!/usr/bin/php -q
<?php

$sipexten = $argv[1];
$mohclass_play = $argv[2];

$wrets = "";
$amiusername = 'manager';
$amisecret   = 'kkkkkkkkkk';

 ob_implicit_flush(true);

$chanspyoption = "qWEws";
// Some of these options dont seem to exist, but whatever, it works :)

 ob_implicit_flush(true);
 $socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);

 $wrets = fread($socket,30);
 fputs($socket, "Action: Login\r\n");
 fputs($socket, "UserName: $amiusername\r\n");
 fputs($socket, "Events: off\r\n");
 fputs($socket, "Secret: $amisecret\r\n\r\n");
 fputs($socket, "Action: Originate\r\n");
 fputs($socket, "Channel: Local/do_chanspy@whisper-chatfire\r\n");
 fputs($socket, "Exten: do_moh\r\n");
 fputs($socket, "Context: whisper-chatfire\r\n");
 fputs($socket, "Priority: 1\r\n");
 fputs($socket, "Variable: chanspyoption=$chanspyoption\r\n");
 fputs($socket, "Variable: sipexten=$sipexten\r\n");
 fputs($socket, "Variable: mohclass_play=$mohclass_play\r\n\r\n");
 fputs($socket, "Action: Logoff\r\n\r\n");
 while (!feof($socket)) {
  $wrets .= fread($socket,8192 );
 }
fclose($socket);

?>


/var/lib/asterisk/agi-bin/mohvolume.php:

#!/usr/bin/php -q
<?php

$sipexten = $argv[1];
$command = $argv[2];

if ($command == "up") {
        $dtmftone = "*";
} elseif ($command == "down") {
        $dtmftone="#";
}

$wrets = "";
$amiusername = 'manager';
$amisecret   = 'kkkkkkkkkk';

 ob_implicit_flush(true);
 $socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);
 $wrets = fread($socket,30);
 //AMI Login
 fputs($socket, "Action: Login\r\n");
 fputs($socket, "UserName: $amiusername\r\n");
 fputs($socket, "Events: off\r\n");
 fputs($socket, "Secret: $amisecret\r\n\r\n");

 //Action: DBGet
 fputs($socket, "Action: DBGet\r\n");
 fputs($socket, "Family: moh_$sipexten\r\n");
 fputs($socket, "Key: channel\r\n\r\n");
 fputs($socket, "Action: Logoff\r\n\r\n");
 while (!feof($socket)) {
  $wrets .= fread($socket,8192 );
 }
fclose($socket);

$channelVal = strpos($wrets,"Val: ");

if ($channelVal){

$Localplaybackchannel=trim(substr($wrets,$channelVal+5,strpos($wrets,"Event: DBGetComplete") - $channelVal-5));

        //Channel found. Play DTMF
                $wrets = "";
                // Send dtmf key

$socket = fsockopen("127.0.0.1","5038", $errno, $errstr, 0);
                 $wrets = fread($socket,30);
                 //LOGIN
                 fputs($socket, "Action: Login\r\n");
                 fputs($socket, "UserName: $amiusername\r\n");
                 fputs($socket, "Events: off\r\n");
                 fputs($socket, "Secret: $amisecret\r\n\r\n");

                 //Action: PlayDTMF
                 fputs($socket, "Action: PlayDTMF\r\n");
                 fputs($socket, "Channel: $Localplaybackchannel\r\n");
                 fputs($socket, "Digit: $dtmftone\r\n\r\n");

                 //LOGOFF
                 fputs($socket, "Action: Logoff\r\n\r\n");
                 while (!feof($socket)) {
                        $wrets .= fread($socket,8192 );
                 }
                fclose($socket);
}

?>


/var/lib/asterisk/mohstream-chatfire-1.sh:

#!/bin/bash
/usr/bin/mpg123 -q -r 8000 -b 0 --mono -s http://s10.pop-stream.de:10380


/var/lib/asterisk/mohstream-chatfire-2.sh:

#!/bin/bash
/usr/bin/mpg123 -q -r 8000 -b 0 --mono -s http://stream.laut.fm/chat-fire


That's it :)

Regards
Markus



Am 27.08.2012 21:29, schrieb Matthew Jordan:

----- Original Message -----
From: "Markus" <[email protected]>
To: "Asterisk Users Mailing List - Non-Commercial Discussion" 
<[email protected]>
Cc: "Matthew Jordan" <[email protected]>
Sent: Monday, August 27, 2012 1:55:08 PM
Subject: Re: [asterisk-users] One leg in a conference and adjusting stream 
volume of other leg

Hi Matthew,

Am 27.08.2012 20:08, schrieb Matthew Jordan:
You can use ConfBridge's DTMF menus to allow a participant to
change
their listening volume.  This should only affect the audio that
the
participant hears, and not the other participants in the
conference
-
regardless of whether or not the audio originates from the same
source.

thanks! I wasn't clear enough in my original mail. What I meant
is:
the
volume of the stream that a user is listening to is adjusted, but
the
volume of the conference itself is not changed! That means, a
conference
is going on, and everyone is listening to the same music at the
same
time, but when the music becomes too loud or annoying, a user can
individually adjust the volume of his music, while the volume of
the
speech of each user, basically the conference itself, remains the
same.

Yes, I know.  That's what the DTMF menus in ConfBridge let you do.

thanks again. If I understand correctly, you are saying that there is
a
switch that allows a user to adjust the volume of the "background"
music
only, but the incoming speech that is coming in to him from other
users
will not get adjusted? That's awesome, but I can't find anything like
that in the docs.

No - what you stated was "the volume of the stream that a user is
listening to is adjusted, but the volume of the conference is not changed!"

I interpreted that as being the volume of the audio sent to the conference
participant.  That can be manipulated directly in ConfBridge.  However,
that affects all audio sent to that participant, which isn't apparently
what you want.

ConfBridge works by mixing the audio for all channels in the conference
and playing the resulting audio to each participant.  You can affect
each participant, but you can't change that all of the audio is mixed
together first.  If you want to play audio separately to each participant,
than you have to do something outside of the actual conference bridge itself.

Will your example

[bridge_user_menu]
*1=increase_listening_volume
1=increase_listening_volume
*2=decrease_listening_volume
2=decrease_listening_volume

not just decrease/increase the audio of *everything* that is coming
in
to the user, i.e. both music and speech? At least that it's how it's
explained in the documentation, isn't it?

Yes.

"Decreases the caller's listening volume. *Everything* they hear will
sound quieter."

What I'm looking for is to adjust the incoming music only, not the
incoming speech. How is ConfBridge able to separate between these two
if
they are going on at the same time?

It doesn't; they are mixed together.

Done that couple of times, but I still don't see that "feature".

I think there is still some sort of misunderstanding here. Maybe I'm
not
explaining it right...

Yup, that was a misunderstanding.

You could probably use ChanSpy to whisper the music to each individual
participant.  Something like this:

[conference]

exten => s,1,NoOp()
same => n,Set(GLOBAL(CONF_CHANNEL_NAME=${CHANNEL}))
same => n,Originate(Local/start_music@conference,exten,conference,moh,1)
same => n,ConfBridge(1)

exten => moh,1,NoOp()
same => n,MusicOnHold()

exten => start_music,1,NoOp()
same => n,Answer()
same => n,ChanSpy(${CONF_CHANNEL_NAME},w)
same => n,Hangup()

You may not want to use something more elegant than a global variable to
cache the name of the channel going into the conference or at least provide
some synchronization around it so that two channels entering the conference
don't step on each other, but this should point you in the correct direction.

As Johan mentioned, the trick to manipulating the volume on the Local channel
streaming the music is best handled externally through AMI.  You can use
the Redirect AMI command to manipulate the channel into other dialplan
extensions that change the volume, then Redirect them back into the moh
extension.  You could trigger that by using dialplan_exec menu actions
from the ConfBridge participant, and raise UserEvents that signal what
action the user wants to take.




--
Matthew Jordan
Digium, Inc. | Engineering Manager
445 Jan Davis Drive NW - Huntsville, AL 35806 - USA
Check us out at: http://digium.com & http://asterisk.org

--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --
New to Asterisk? Join us for a live introductory webinar every Thurs:
                http://www.asterisk.org/hello

asterisk-users mailing list
To UNSUBSCRIBE or update options visit:
    http://lists.digium.com/mailman/listinfo/asterisk-users



--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --
New to Asterisk? Join us for a live introductory webinar every Thurs:
              http://www.asterisk.org/hello

asterisk-users mailing list
To UNSUBSCRIBE or update options visit:
  http://lists.digium.com/mailman/listinfo/asterisk-users

Reply via email to