Early media или музыка вместо гудков в Asterisk

Иногда хочется, чтобы во время звонка вместо длинных гудков проигрывалась мелодия. Как в рекламе говорится, “надоели гудки”? Такое возможно сделать с помощью Asterisk. Эта технология называется Early Media описанное в RFC3960.

В официальных источниках по Asterisk есть две статьи (один, два) описывающих одну и ту же ситуацию: на поступивший звонок играет мелодия, вызов отбивается. В этот момент вызов не считается отвеченным.

Нам же необходимо сделать именно вызов абонента с мелодией. Для этого создаем свой MoH класс, в котором прописываем необходимую мелодию. В директории mymusicнаходится один файл, поэтому проигрываться всегда будет он. Пример musiconhold.conf:

  1. [mymusic]
  2. mode=files
  3. directory=mymusic
  4. sort=alpha

Не забыть перезапустить(!) Asterisk, т.к. он не умеет “на лету” считывать новые мелодии в директории, указанной в классе.

Далее в extensions.conf создаем макрос (но можно просто в диалплан на каждого, кому эту мелодию на вызов ставить):

  1. [macro-music]
  2. exten => s,1,SetMusicOnHold(mymusic)
  3. exten => s,n,Progress()
  4. exten => s,n,Dial(SIP/${ARG1},40,m)
  5. exten => s,n,Hangup()

Сначала назначаем специальный класс MoH, потом запускаем Progress и запускаем вызов с ключом m. Без этого ключа в команде Dial не сработает мелодия. Этот ключ проигрывает мелодию MoH, пока абонент не ответит.

И наконец ставим абоненту/пользователю на вызов эту мелодию всё в том жеextensions.conf:

  1. exten => 444,1,Macro(music,${EXTEN})

Теперь при звонке на номер 444 будет проигрываться мелодия, которая указана для MoH класса mymusic. Проще простого.

UPD(27.10.2015): Коллега столкнулся с похожей задачей, но была необходимость не в мелодии вместо гудка, а в проигрывании сообщения-уведомления. Полученный результат более гибок в сравнении с установкой проигрываемого файла через MoH и позволяет воспроизводить любые файлы без перезагрузки сервера Asterisk PBX. И теперь само решение:

Для SIP-пира выставляется ключ progressinband в значение yes, что позволяет обойти обычные ТфОП сети (отправка 180 Ringing, если не был отправлен 183 Session Progress с последующей установкой аудио-канала):

  1. ...
  2. progressinband=yes
  3. ...

А далее в extensions.conf такие строки, чтобы вызвать соответствующего SIP-пира:

  1. exten => _X.,1,NoOp()
  2. exten => _X.,n,Ringing()
  3. exten => _X.,n,Progress()
  4. exten => _X.,n,Wait(1)
  5. exten => _X.,n,Playback(mediafile,noanswer)
  6. exten => _X.,n,Dial(SIP/${EXTEN})
  7. exten => _X.,n,HangUp()

С помощью Ringing() отправляем сигнал о том, что у нас пошел вызов абонента (для обхода обычных ТфОП сетей(привет ростелекомовским АТС)). Далее сообщаем с помощьюProgress(), что у нас всё таки будет канал с аудио. Даем 1 секунду для установления канала и воспроизводим медиафайл. Для Playback обязательно надо указать ключnoanswer, чтобы эта команда самостоятельно не послала сигнал о том, что на вызов ответили.

 

 

 


Many dialplan applications within Asterisk support a common VOIP feature known as early media. Early Media is most frequently associated with the SIP channel, but it is also a feature of other channel drivers such as H323. In simple situations, any call in Asterisk that is going to involve audio should invoke either Progress() or Answer().

By making use of the progress application, a phone call can be made to play audio before answering a call or even without ever even intending to answer the full call.

Simple Example involving playback:

exten => 500,1,Progress()
exten => 500,n,Wait(1)
exten => 500,n,Playback(WeAreClosedGoAway,noanswer)
exten => 500,n,Hangup()

In the example above, we start an early media call which waits for a second and then plays a rather rudely named message indicating that the requested service has closed for whatever reason before hanging up. It is worth observing that the Playback application is called with the ‘noanswer’ argument. Without that argument, Playback would automatically answer the call and then we would no longer be in early media mode.

Strictly speaking, Asterisk will send audio via RTP to any device that calls in regardless of whether Asterisk ever answers or progresses the call. It is possible to make early media calls to some devices without ever sending the progress message, however this is improper and can lead to a myriad of nasty issues that vary from device to device. For instance, in internal testing, there was a problem reported against the Queue application involving the following extension:

exten => 500,1,Queue(queuename)

This is certainly a brief example. The queue application does not perform any sort of automatic answering, so at this point Asterisk will be sending the phone audio packets, but it will not have formally answered the call or have sent a progress indication. At this point, different phones will behave differently. In the case of the internal test, our Polycom Soundpoint IP 330 phone played nothing while our SNOM360 phone played audio until approximately one minute into the call before it started ceaselessly generating a ring-back indication. There is nothing wrong with either of these phones… they are simply reacting to an oddly formed SIP dialog. Obviously though, neither of these is ideal for a queue and the problem wouldn’t have existed had Queue been started after using the Progress application like below:

exten => 500,1,Progress()
exten => 500,n,Queue(queuename)

Getting the hang of when to use Progress and Answer can be a little tricky, and it varies greatly from application to application. If you want to be safe, you can always just answer the calls and keep things simple, but there are a number of use cases where it is more appropriate to use early media, and most people who actually need this feature will probably be aware of when it is necessary.

Applications which can use early media and do not automatically answer (incomplete list, please contribute):
SayAlpha/SayDigits/SayNumber/etc
Playback (conditionally)
MP3
MixMonitor
MorseCode
Echo
Queue
MusicOnHold

Leave a Comment