Asterisk не проигрывает звуковые файлы
Есть сервер на операционной системе Debian GNU/Linux Wheezy.
На нем установлен Asterisk и xl2tpd.
Подключение sip клиента к Asterisk происходит через l2tp соединение.
Asterisk недоступен для интерфейсов которые выходят во внешнюю сеть.
В соединении l2tp у сервера адрес 192.168.68.1 у клиента 192.168.68.10.
Соединяюсь с Asterisk sip клиентом linphone. Предварительно конечно соединившись с сервером через l2tp.
При звонке на любой номер (внешний, не подключенный к этому серверу), абонент меня отлично слышит, а я его совсем не слышу.
tcpdump со стороны клиента во время звонка выдает такое:
Со стороны сервера тоже самое.
Если в программе linphone установить настройку: За NAT, внешний адрес: 192.168.68.10
То все работает отлично. Меня слышно, и я слышу абонента. В этом случае tcpdump выдает вот такое:
Как можно заметить теперь пакеты ходят в обе стороны.
В чем тут дело? Если нужны какие-то другие данные, могу без проблем предоставить.
Спасибо большое Владимир.
Обратил внимание на SDP в пакетах. Как вы и говорили в случае когда настройка За NAT, внешний адрес: 192.168.68.10 не включена.
В SDP в заголовках Owner Adress и Connection Adress стоит 192.168.0.2 - адрес другого интерфейса.
Если настройку За NAT, внешний адрес: 192.168.68.10 включить то там нормальный адрес 192.168.68.10 - как мне нужно.
Самое смешное что в sip клиенте Ekiga нет возможности настроить внешний адрес как в linphone, и временами звук просто переставал работать. Видимо Ekiga выставляет ip адрес первого найденного интерфейса в SDP. Теперь ясно откуда у проблемы растут ноги.
В Asterisk добавил в настройки пира в sip.conf параметр nat=yes.
Теперь все отлично работает, даже без настройки За NAT, внешний адрес: 192.168.68.10 в linphone.
Кстати чтобы прояснить и никому не казалось что это некая магия. Почему же теперь все работает, когда в заголовках SDP все равно неверный ip адрес?
Все конечно знают что такое NAT. Но что же конкретно делает опция nat=yes в Asterisk?
Вот её описание:
Для параметра nat может быть задано значение yes, no или never. Ес-
ли задано yes, Asterisk игнорирует IP-адрес в заголовках SIP и SDP
и отвечает на адрес и порт, указанные в IP-заголовке. Опция never
предназначена для устройств, которые не могут обрабатывать поле
rport в SIP-заголовке.
Как можно заметить, на моем примере, она необходима не только когда клиент находится за NAT. В моем случае до сервера есть прямое vpn соединение, где NAT не используется. Но тем не менее в заголовки SIP и SPD попадает ip адрес другого интерфейса. Эта опция говорит Asterisk игнорировать ip адрес из заголовков этих протоколов, поэтому теперь все работает.
Начинает проигрывать заданный звуковой файл и сразу же возвращает управление, проигрывая звуковой файл в фоновом режиме, пока исполняются следующие команды (если они есть). (Сравните с командой Playback, которая также проигрывает звуковой файл, но ожидает, пока не закончится проигрыш звукового файла, перед тем как возвратить управление.)
Если Вы повторно вызовете команду Background, пока проигрывается предыдущий звуковой файл, второй звуковой файл будет просто помещен в очередь и начнет проигрываться после окончания первого файла.
Если, после выполнения этой команды, нет больше команд, которые надо выполнить для данного вызова, но соединение все еще остается в установленном состоянии (абонент не хочет положить трубку), тогда Asterisk закончит проигрывание фонового звукового файла перед тем, как будет запущен таймер, установленный командой ResponseTimeout.
Одно из применений команды Background() - это проигрывание интерактивного выбора пунктов меню ("Нажмите 1, для соединения с отделом продаж, нажмите 2, для соединения с отделом поддержки, и т.д."), без дальнейших команд, определенных для данного екстеншена. Следовательно, Asterisk не имеет команд, которые нужно выполнить, и просто ждет любую DTMF последовательность, которые введет пользователь, пока проигрывается файл. Если пользователь набрал номер, который является правильным в данном контексте, проигрывание звукового файла заканчивается и Asterisk перейдет на номер набранного екстеншена. Если пользователь ничего не набрал, тогда Asterisk закончит проигрывание звукового файла, и в тишине будет ждать, определенное в ResponseTimeout время, ввода пользователя. Если и в течении этого времени пользователь ничего не набрал, управление будет передано на стандартный екстеншен "t" (если он определен в контексте, иначе соединение будет закончено). Если пользователь набрал номер, который является неправильным, в текущем контексте, управление будет передано на стандартный екстеншен "i" (если он определен в контексте, иначе соединение будет закончено).
3 ответа
Вы должны открыть порты rtp (по умолчанию 10000-20000) в вашем брандмауэре.
Также необходимо убедиться, что у вас есть правильные настройки nat для вашего типа сети.
Я открыл порты rtp, но звук по-прежнему не воспроизводится. Я выполнил iptables -I INPUT -m state --state NEW -m udp -p udp --dport 10000: 20000 -j ACCEPT Есть другие предложения? Спасибо
Отключите SIPALG на роутере. Проверьте настройки nat на звездочке и убедитесь, что он правильно настроен.
Похоже, вы неправильно используете функцию чтения, это должно быть примерно так.
Пожалуйста, проверьте ссылку для получения дополнительной информации
Спасибо за ответ. Я тестировал, но звездочка по-прежнему ничего не воспроизводит. Я могу подключиться к расширению, но он не воспроизводит звук. Я подозреваю, что это может быть проблема с iptables. Я попытался отбросить правила iptables и принять все соединения, но все равно не работает. Любое предложение? Спасибо
Использование определенно похоже на то, что я упоминал ранее, мое предложение может заключаться в том, чтобы проверить путь к звуковому файлу (по умолчанию должен быть как / var / lib / asterisks / Sounds / en / ваша папка с файлами), файл проверки совместим с звездочкой, можно воспроизводить или использовать asterisk -r на cli, чтобы увидеть, что случилось, когда дойдет до чтения шага. Я надеюсь это работает
Вы должны запустить pcap на своем клиенте и на сервере asterisk. Используйте wirehark для выполнения захвата. Вы должны увидеть сигнализацию для установки вызова, а затем соответствующий RTP. Если вы видите RTP, отправленный звездочкой, но не полученный на вашем клиенте, значит, у вас проблема с брандмауэром. Вы должны увидеть SDP в сигнализации SIP, чтобы определить, какие порты запрашиваются клиентом и звездочкой. Сравните это с настройками вашего брандмауэра. Вообще говоря, если ваш клиент находится за NAT, вам нужно убедиться, что комедия включена в звездочке (настройки nat). Вы также захотите отключить SIP ALG на клиентском брандмауэре.
Я пытаюсь организовать конференцию и воспроизвести звуковой файл на фоне конференции. Как я могу сделать это возможным?
это явно не сработает, потому что звуковой файл будет воспроизводиться перед входом в конференцию.
Хотел добавить сюда свое решение на случай, если оно кому-нибудь понадобится.
сначала создайте контекст для моста conf в файле extensions.conf:
где 01 - номер моста
Затем через командную строку вы можете сделать:
Это действительно так просто.
Это должен быть принятый ответ. asterisk -rx 'channel originate local/[email protected] application Playback hello-world'
Вы создали новый вызов, простой метод с использованием файлов вызовов.
После этого вы должны разместить одну из веток вызова для вашей конференции следующим образом
Где конференция - это контекст, чтобы попасть в ваш конференц-зал. Не нужно шпионить или что-то в этом роде, это пустая трата времени / процессора
Я не получил его должным образом, если я позвонил с внутреннего номера xxx, где канал - zzz, то как он узнал, на каком канале он должен играть?
Не извиняйтесь, я сделал это сам, спасибо за ваше предложение, я ценю. Но мне нужно, чтобы вы помогли мне с другой вещью, которая меня в нем болтает, мне нужно обнаруживать разговор на обоих концах, но звездочка позволяет мне обнаруживать его на канале, который набрал внутренний номер, а не на том, кто его получил, возможно ли обнаружить разговор на обоих концах заканчивается?
Да, с помощью приложения c / c ++ или путем создания нового канала и присоединения одного конца этого канала через chanspy к необходимому направлению исходного канала. Нет принципиальной разницы между двумя ногами, когда вы работаете в ядре asterisk (приложение c / c ++, см., Например, app_monitor.c)
Я пробовал, как вы мне сказали, но я все еще не могу получить события обнаружения разговора на принимающем канале, даже я пытался получить все каналы, реализовав цикл, но мне не удалось, пожалуйста, подведите меня к чему-нибудь, с помощью которого я могу обнаружить разговор обнаруживает события на принимающем канале.
Пример
Пример
[incoming]
exten => s,1,Answer
exten => s,2,ResponseTimeout(5)
exten => s,3,Background(mymenu)
exten => s,4,Background(chooseSomething)
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(s,2)
В данном примере, вызов поступает в контекст incoming и сразу же соединение переводится Asterisk в установленное состояние (шаг s,1). Устанавливается таймер ожидания ввода пользователя (ResponseTimeout) в значение 10 секунд (шаг s,2). Потом мы начинаем проигрывать звук из файла "mymenu.gsm" (шаг s,3). Потом мы помещаем в очередь еще один звук (из файла "chooseSomething.gsm"), который будет проигрываться в фоне, когда первый файл закончится (шаг s,4). Так как у нас нет команды с приоритетом s,5, то Asterisk будет продолжать проигрывать файл "mymenu.gsm" пока он не закончиться, а потом и звуковой файл "chooseSomething.gsm" до его окончания, а потом будет ждать ввода пользователя еще 5 секунд. Если в течении всего этого времени (пока проигрываются эти звуковые файлы и в течении заданного времени ожидания) пользователь наберет номер екстеншена, тогда Asterisk прекратит проигрывать звуковые файлы и перейдет к обработке набранного екстеншена. Если пользователь набрал "1", "2" или "3", тогда Asterisk совершит переход на соответствующий екстеншен. А если пользователь наберет любой другой номер, тогда Asterisk перейдет на екстеншен "i" и будет проигран звуковой файл "pbx-invalid.gsm", и будет совершен переход на команду проигрывания первого файла. Если пользователь ничего не ввел, после 5 секунд ожидания ввода, тогда будет совершен переход на екстеншен "t", а уже оттуда вся операция повториться заново, т.к. отсюда совершается переход на проигрывание первого файла.
Обратите внимание, что если Вы используете команду Background в макроопределении, то она всегда будет вызывать набранный екстеншен, вне вызываемого контекста. Смотри описание команды Macro.
Проигрывает заданный звуковой файл (Вам не нужно указывать расширение файла). Звуковые файлы, по умолчанию, находятся в директории /var/lib/asterisk/sounds (Этот путь может быть изменен в файле asterisk.conf).
Команда Playback совместима с многоязыковой поддержкой в Asterisk. Она будет искать подходящий файл в поддиректории, которая соответствует выбранному языковому коду (который назначен командой SetLanguage или, используя языковой код заданный по умолчанию для канала. Если файл не найден, тогда будет проигрываться файл, который не связан ни с каким из языков (из базовой директории).
Команда Playback будет проигрывать звуковой файл и, по окончании, возвратит управление. Сравните с командой Background, которая начинает проигрывать файл и сразу же возвращает управление, позволяя выполнять дальнейшие команды для канала Asterisk, проигрывая в фоне музыку из заданного файла.
Ссылки по теме:
- Команда ControlPlayback: Проигрывает звуковой файл с возможностью перемотки вперед, назад и останова
- Команда Background: Проигрывает звуковой файл, в это время могут исполняться другие команды
- Команда Playtones: Проигрывает список тонов, в это время могут исполняться другие команды
- Команда MP3Player: Проигрывает MP3 файл или поток
- Команда MusicOnHold
- Звуковые файлы
- Asterisk tips answer-before-playback: Что Вам нужно сделать, перед тем как проигрывать звуковые файлы на канале
Я установил Asterisk 13 на Debian 9 и попробовал несколькими способами воспроизвести аудиофайл, и я вызываю звездочку, но она не воспроизводит файл. Вот мой файл extensions.conf:
Я пробовал с 2 разными SIP-клиентами, и звуки не воспроизводятся. Я пробовал использовать разные кодеки, но все равно не играет.
Есть идеи, в чем может быть проблема?
Попытайтесь сначала понять, что происходит с сигнализацией и обменом медиа. Захватите активность на сетевом интерфейсе (ах) во время звонков. Подойдут такие инструменты, как tcpdump или ngrep. Посмотрите, создается ли носитель Asterisk (должны быть пакеты RTP, исходящие от Asterisk к клиентам). Убедитесь, что Asterisk также принимает мультимедийные данные от клиентов, с каких IP-адресов поступают мультимедийные данные и отправляет ли Asterisk звук на правильный IP-адрес или, возможно, на недоступный natted IP-адрес, который клиент публикует в своем SDP.
Пример
[incoming]
exten => s,1,Answer
exten => s,2,ResponseTimeout(5)
exten => s,3,Background(mymenu)
exten => s,4,Background(chooseSomething)
exten => i,1,Playback(pbx-invalid)
exten => i,2,Goto(s,2)
В данном примере, вызов поступает в контекст incoming и сразу же соединение переводится Asterisk в установленное состояние (шаг s,1). Устанавливается таймер ожидания ввода пользователя (ResponseTimeout) в значение 10 секунд (шаг s,2). Потом мы начинаем проигрывать звук из файла "mymenu.gsm" (шаг s,3). Потом мы помещаем в очередь еще один звук (из файла "chooseSomething.gsm"), который будет проигрываться в фоне, когда первый файл закончится (шаг s,4). Так как у нас нет команды с приоритетом s,5, то Asterisk будет продолжать проигрывать файл "mymenu.gsm" пока он не закончиться, а потом и звуковой файл "chooseSomething.gsm" до его окончания, а потом будет ждать ввода пользователя еще 5 секунд. Если в течении всего этого времени (пока проигрываются эти звуковые файлы и в течении заданного времени ожидания) пользователь наберет номер екстеншена, тогда Asterisk прекратит проигрывать звуковые файлы и перейдет к обработке набранного екстеншена. Если пользователь набрал "1", "2" или "3", тогда Asterisk совершит переход на соответствующий екстеншен. А если пользователь наберет любой другой номер, тогда Asterisk перейдет на екстеншен "i" и будет проигран звуковой файл "pbx-invalid.gsm", и будет совершен переход на команду проигрывания первого файла. Если пользователь ничего не ввел, после 5 секунд ожидания ввода, тогда будет совершен переход на екстеншен "t", а уже оттуда вся операция повториться заново, т.к. отсюда совершается переход на проигрывание первого файла.
Обратите внимание, что если Вы используете команду Background в макроопределении, то она всегда будет вызывать набранный екстеншен, вне вызываемого контекста. Смотри описание команды Macro.
Проигрывает заданный звуковой файл (Вам не нужно указывать расширение файла). Звуковые файлы, по умолчанию, находятся в директории /var/lib/asterisk/sounds (Этот путь может быть изменен в файле asterisk.conf).
Команда Playback совместима с многоязыковой поддержкой в Asterisk. Она будет искать подходящий файл в поддиректории, которая соответствует выбранному языковому коду (который назначен командой SetLanguage или, используя языковой код заданный по умолчанию для канала. Если файл не найден, тогда будет проигрываться файл, который не связан ни с каким из языков (из базовой директории).
Команда Playback будет проигрывать звуковой файл и, по окончании, возвратит управление. Сравните с командой Background, которая начинает проигрывать файл и сразу же возвращает управление, позволяя выполнять дальнейшие команды для канала Asterisk, проигрывая в фоне музыку из заданного файла.
Опции
skip: Задает проигрывать звуковой файл, если только канал уже в отвеченном состоянии. Если на канале еще не установлено соединение, команда Playback сразу же закончит работу без проигрывания файла.
Если не заданы опции skip и noanswer, тогда команда Playback сначала переведет канал в отвеченное состояние (если он еще находится в неотвеченном состоянии) и после этого начнет проигрывать звуковой файл.
Обратите внимание: Опции не будут работать, если у вас, при задании аргументов, есть пробелы между именем файла и запятой, а так же между запятой и параметрами.
Коды возврата:
Возвращает -1, если соединение было прервано на канале или не найден заданный файл. Иначе, возвращает 0.
Читайте также: