Freeswitch中session.streamFile()执行seek:-500无法回退始终从头播放问题
问题原因排查及解决方案
- 音频文件格式不符合要求
Freeswitch的session.streamFile()的seek功能仅支持未压缩的PCM编码WAV文件,如果你的音频是压缩编码(如ADPCM、MP3封装改后缀为WAV)、WAV头信息损坏,或音频采样率/位深与当前通话通道的编码参数不匹配,会导致seek偏移量计算错误。负偏移量会被判定为小于0的非法值,直接重置为0,表现为从头播放。 - Freeswitch版本存在已知bug
1.8.x及更早的稳定版、1.10.0~1.10.6版本的JavaScript模块存在负seek值解析bug,会忽略返回值中的负号,将seek:-500解析为正数值,当解析后的数值超过音频总时长时,会自动回退到音频起始位置。该问题在1.10.7及以上的稳定版本中已修复。 - 媒体缓存配置不足
Freeswitch默认的播放缓存大小可能不足以存储已播放的音频数据,往回seek时找不到对应位置的缓存数据,就会直接从头加载音频。 - 音频时长过短
如果你的测试音频总时长小于500ms,触发seek:-500时偏移后的位置小于音频起始点,自然会重置到0位置播放。
验证修复步骤
- 优先使用Freeswitch自带的标准PCM测试音频测试,排除文件本身的问题。
- 开启Freeswitch debug日志,按DTMF 1时查看日志中seek值的解析结果,确认是否正确识别了负号。
- 在调用
session.streamFile()前添加缓存配置,放大播放缓存:
var exit = false; function onInput( session, type, data, arg ) { if ( type == "dtmf" ) { console_log( "info", "Got digit " + data.digit + "\n" ); if ( data.digit == "*" ) { exit = true; return( false ); } else if ( data.digit == "0" ) { return( "seek:0" ); } else if ( data.digit == "1" ) { return( "seek:-500" ); } else if ( data.digit == "2" ) { return( "pause" ); } else if ( data.digit == "3" ) { return( "seek:+500" ); } return( true ); } } if ( session.ready( ) ) { session.answer( ); // 新增配置:设置播放缓存为20秒,单位为毫秒 session.setVariable("playback_buffer_size", "20000"); while ( session.ready( ) && ! exit ) { session.streamFile( "<path to WAV>", onInput ); } if ( session.ready( ) ) { session.hangup( ); } }
- 若确认是版本bug,升级到1.10.7及以上的稳定版Freeswitch即可解决。
内容的提问来源于stack exchange,提问作者Niklas Droste
相关产品推荐
相关产品推荐

