Asterisk使用MixMonitor录音后调用AGI上传wav文件未就绪如何解决
问题原因
Asterisk的h扩展名优先级执行时,MixMonitor的录音文件写入是异步操作,通话挂断触发h流程时,录音数据还没有完全落盘,文件处于未完成状态,因此直接执行上传会失败。
解决方案
方案1:使用MixMonitor内置的后置执行钩子(最推荐)
MixMonitor指令原生支持第三个参数,指定录音完全写入完成后要执行的命令,优先级高于h扩展的异步逻辑,不会出现文件未生成的问题。
修改extensions.conf配置如下:
exten => 0123456,1,MixMonitor(${UNIQUEID}.wav49,,/usr/bin/php /var/lib/asterisk/agi-bin/curl_post.php ${UNIQUEID}.wav49) exten => 0123456,n,Dial(SIP/xxxxxxxx@0123456,60) ; 可以删除原h扩展中的AGI调用逻辑
该方案会直接把录音文件名作为参数传递给PHP脚本,无需额外获取录音标识,稳定性最高。
方案2:在AGI脚本中增加文件写入完成校验
如果必须保留h扩展调用AGI的逻辑,可以在PHP脚本中增加轮询校验逻辑,确认文件写入完成后再执行上传:
<?php // 替换为你的录音文件存储目录 $monitor_dir = '/var/spool/asterisk/monitor/'; // 从AGI变量中获取UNIQUEID,或通过参数传入 $uniqueid = $argv[1]; $record_file = $monitor_dir . $uniqueid . '.wav49'; $max_wait = 30; // 最长等待30秒,可根据通话最长时长调整 $wait_count = 0; $last_size = 0; while ($wait_count < $max_wait) { clearstatcache(true, $record_file); // 文件不存在则继续等待 if (!file_exists($record_file)) { sleep(1); $wait_count++; continue; } $current_size = filesize($record_file); // 连续两次检测文件大小无变化,确认写入完成 if ($current_size == $last_size && $current_size > 0) { break; } $last_size = $current_size; sleep(1); $wait_count++; } // 此处添加CURL上传逻辑 ?>
注意事项
- 确保Asterisk运行用户(通常为
asterisk)拥有PHP脚本执行权限、录音目录读取权限 - 方案1中需填写PHP和脚本的绝对路径,避免Asterisk环境变量缺失导致命令执行失败
内容的提问来源于stack exchange,提问作者Kazu
相关产品推荐
相关产品推荐

