Complete one recording first
Have 7101 dial 7815, which bridges to 7102. After answer, each person says a distinct phrase in turn. Hang up, find the UUID-named WAV and inspect its two channels separately. Delay answering by a few seconds so the start of recorded audio can be compared with call progress.
Reuse the working directory domain and training-internal listener with normal media processing through FreeSWITCH. Restore normal mode after episode 12's proxy or bypass tests. This isolated route attaches recording to 7101's caller channel. Directory extensions, queue agents and tiers retain their separate roles. The example was checked against v1.11.2 source and current documentation and has not been run on an instance.
Prepare the destination directory
In fs_cli, run eval {conf_dir} and eval {recordings_dir} to inspect the directories. Confirm the service's actual OS user. Create fs-lab-14 below the recording root with the correct owner and group. Operations can use install -d with owner, group and mode 0750, substituting the actual path. Check traversal rights on parent directories and mount permissions.
As the service identity, create a temporary test file and remove it after verifying access. Check free space, inodes and read-only mounts. For a container, map its path to the host volume. Restrict access to services that need the call audio.
Save the XML below as dialplan/default/00_training_record_14.xml. Verify the include chain, the authenticated context for 7101 and any earlier matches for 7815. Use the established include location for another controlled context.
<include>
<extension name="fs_record_lab_14">
<condition field="destination_number" expression="^7815$">
<!-- 保持普通媒体路径,服务器能够处理音频 -->
<action application="set" data="bypass_media=false"/>
<action application="set" data="proxy_media=false"/>
<!-- 文件按当前通道UUID命名,父目录提前准备好 -->
<action application="set"
data="lab_record_file=$${recordings_dir}/fs-lab-14/${uuid}.wav"/>
<!-- 读写两路分别保存为两个声道 -->
<action application="set" data="RECORD_STEREO=true"/>
<!-- 只在当前通道已接听并进入桥接后采集音频 -->
<action application="set" data="RECORD_ANSWER_REQ=true"/>
<action application="set" data="RECORD_BRIDGE_REQ=true"/>
<!-- 在主叫腿挂载录音,随后再呼叫7102 -->
<action application="record_session" data="${lab_record_file}"/>
<action application="set" data="hangup_after_bridge=true"/>
<!-- 使用已经验证的目录域定位7102 -->
<action application="bridge" data="user/7102@${domain_name}"/>
</condition>
</extension>
</include>
lab_record_file combines the expanded recording root with the current channel UUID. The .wav extension selects the loaded file-format handler. A UUID avoids collisions between calls. Date subdirectories need their own creation and permissions. Store the relationship between the business call ID and channel UUID for later retrieval.
Reuse the verified domain_name directory lookup, or the deployment's existing multi-domain lookup. A business call can create several channels. Record which leg owns the UUID used in the filename.
Identify the channels by listening
RECORD_STEREO=true saves read and write audio separately. On this caller channel, read is audio arriving from 7101. Write is audio FreeSWITCH sends toward 7101, usually 7102 during the bridge, potentially including server playback. Confirm the mapping by alternating speakers before assigning business roles to channels.
A recorder on the called leg needs its own direction mapping. RECORD_STEREO_SWAP reverses the order. RECORD_READ_ONLY and RECORD_WRITE_ONLY restrict capture to one side. Check inherited settings if a channel is empty. This baseline captures both directions.
Two file channels describe the saved audio. Inspect SIP leg codecs separately using episode 11's method. Phones do not need stereo audio support for FreeSWITCH to save the read and write streams in a stereo file.
Attaching a recorder and capturing conversation
record_session attaches a background recorder to the current channel while the dialplan continues to bridge. RECORD_ANSWER_REQ gates capture on answer. RECORD_BRIDGE_REQ also gates it on bridging. Both are enabled here to capture answered, bridged conversation. File creation can precede captured conversation, so verify the waveform and audio.
If the route answers before bridge and plays a greeting, the caller channel is already answered. An answer-only condition may include that greeting. To record an answered IVR, review the bridge condition. Recording ringback or early media requires a different start policy and verification of the audio actually received. Define the required phases before changing conditions.
Hold and attended transfer can change bridge state or channels. Verify the recorder's attachment and required segments at each phase. Extend the direct-call test to queues and transfers only after the baseline works, with business-level segment correlation.
Load, inspect and listen
Run reloadxml in fs_cli and place a new 7101 call to 7815. A dialplan-only change needs no profile restart. Have 7102 wait before answering. Alternate the phrases “7101 start” and “7102 start”, then converse. Hang up, wait for the file to close and locate it by the caller channel UUID.
On an acceptance machine with FFmpeg installed, inspect the finished file with ffprobe. The expected fields are checks, rather than fabricated execution output.
# 在已安装FFmpeg的验收机器上检查已完成的测试文件
# 替换为实际文件路径,双声道应看到channels为2
ffprobe -v error -select_streams a:0 \
-show_entries stream=codec_name,sample_rate,channels:format=duration \
-of json /path/to/completed-test.wav
Expect channels=2. sample_rate is the saved sample rate in Hz and duration is container duration in seconds. Listen to channels independently in an editor or suitable player. Compare audio with waiting, answer, bridge and hangup times. Mixed playback can hide a missing side.
record_sample_rate can specify the output sample rate. Keep the existing processing for this baseline, then choose an explicit rate when adapting to ASR or archival requirements. Saving narrowband audio at a higher rate does not recover absent frequency content. Inspect completed files because headers may still be unfinished during writing.
Troubleshoot and roll back
- No file appears. Verify the route and expanded lab_record_file, service write access, file module and logs. Also check whether a profile, ESL application or another route already starts recording.
- The file is unexpectedly short. Compare answer and bridge conditions with channel end and recorder stop. Check whether RECORD_MIN_SEC removes short recordings.
- Both channels contain the same mix. Confirm RECORD_STEREO, the attachment leg and any post-processing that mixes channels. Inspect the original completed file.
- Audio has gaps. Align pause, mask, hold and transfer times. Pause discards captured audio for that interval. Mask replaces it with silence. Stopping and restarting introduces file or segment handling. Use the exact recording path for controls.
stop_record_session must use the original path. RECORD_APPEND appends to a file and needs a concurrency and naming policy. This baseline uses one file per call, and channel hangup ends its recording.
Wait for lab calls to finish, move the XML outside the include path and reloadxml. Restore changed recording variables and the existing business entry. Retain acceptance audio and results for review, then handle them under the project's retention policy. Repeat the original extension calls and recording workflow.