; ============================================================================= ; VICIdial Call Recording — Storage, Compression & Cloud Backup Configuration ; ============================================================================= ; Generated by ViciStack — https://vicistack.com — Free VICIdial optimization ; ; WHAT THIS FILE DOES: ; Configures call recording in VICIdial with storage optimization: ; recording format selection, real-time compression, archival rotation, ; cloud backup to S3/GCS, and disk usage monitoring. A 50-agent center ; generates 10-50GB of recordings per day — without a storage plan, ; you'll fill your disk in weeks. ; ; HOW TO USE: ; 1. Campaign recording settings → VICIdial Admin GUI ; 2. Asterisk recording settings → /etc/asterisk/ config files ; 3. Compression/archival scripts → cron jobs on the VICIdial server ; 4. Cloud backup → AWS CLI + cron ; ; FULL GUIDE: ; https://vicistack.com/blog/vicidial-call-recording/ ; https://vicistack.com/blog/vicidial-call-recording-storage-optimization/ ; https://vicistack.com/blog/vicidial-asterisk-cdr-analysis/ ; ; NEED HELP? hello@vicistack.com ; ============================================================================= ; ============================================================================= ; SECTION 1: VICIDIAL CAMPAIGN RECORDING SETTINGS ; ============================================================================= ; Configure in Admin > Campaigns > [campaign] > Recording tab. ; These are GUI settings documented here for reference. ; ============================================================================= ; --- Recording Mode --- ; Options: ; NEVER = no recording (don't do this — you need recordings for QA) ; ONDEMAND = agent presses a button to start/stop recording ; ALLCALLS = record every call automatically (RECOMMENDED) ; ALLFORCE = record all, agents can't stop it (for compliance campaigns) ; ; Recommendation: ALLCALLS for standard campaigns, ALLFORCE for financial ; services, healthcare, or any industry with recording mandates. recording_mode = ALLCALLS ; --- Recording Format --- ; The single most impactful storage decision. Choose wrong and you burn ; 10x more disk space than necessary. ; ; WAV (PCM, uncompressed): ; Quality: perfect (lossless) ; Size: ~960 KB/minute (8kHz mono) or ~7.5 MB/minute (16kHz stereo) ; Use when: you need archival-quality recordings for legal discovery ; NEVER use WAV as your primary format — it will eat your disk alive. ; ; GSM: ; Quality: decent (compressed, some artifacts) ; Size: ~100 KB/minute ; Use when: you want small files and don't care about audio artifacts ; This is the stock VICIdial default. It's fine but Opus is better. ; ; OGG (Vorbis): ; Quality: good ; Size: ~120 KB/minute ; Use when: you want cross-platform playback (plays in all browsers) ; ; OPUS (recommended): ; Quality: excellent (transparent at 24kbps) ; Size: ~60-90 KB/minute depending on bitrate ; Use when: you want the best quality-to-size ratio ; Note: Requires Asterisk 16+ with codec_opus module. ; ; MP3: ; Not native to Asterisk but can be done via MixMonitor + lame post-processing. ; Quality: good at 64kbps ; Size: ~480 KB/minute at 64kbps, ~120 KB/minute at 16kbps ; Use when: you need files playable on literally every device. ; ; MATH for a 50-agent center, 8hr shift, 50% talk time = 200 agent-hours/day: ; WAV: 200hrs * 60min * 0.96MB = ~11,520 MB/day = 11.5 GB/day ; GSM: 200hrs * 60min * 0.10MB = ~1,200 MB/day = 1.2 GB/day ; OPUS: 200hrs * 60min * 0.07MB = ~840 MB/day = 0.84 GB/day ; ; Per month (22 business days): ; WAV: 253 GB GSM: 26 GB OPUS: 18 GB ; ; Per year: ; WAV: 3 TB GSM: 317 GB OPUS: 222 GB recording_format = ogg ; OGG is the safest choice — good compression, plays in all browsers, ; no patent issues. Switch to OPUS if your Asterisk build supports it. ; ============================================================================= ; SECTION 2: ASTERISK RECORDING CONFIGURATION ; ============================================================================= ; These are Asterisk-level settings that control how MixMonitor (the ; recording engine) captures audio. ; ============================================================================= ; --- /etc/asterisk/asterisk.conf --- ; Recording storage directory: ; ; [directories] ; astspooldir => /var/spool/asterisk ; ; Recordings go to: /var/spool/asterisk/monitor/ ; ; If you have a separate disk/partition for recordings, symlink: ; ; mv /var/spool/asterisk/monitor /recordings/ ; ; ln -s /recordings/ /var/spool/asterisk/monitor ; ; This keeps recordings on a large data disk while the OS disk stays clean. ; --- MixMonitor options (set in VICIdial admin or dialplan) --- ; VICIdial calls MixMonitor automatically. You can tweak behavior in: ; Admin > System Settings > Recording MixMonitor Options ; ; Useful options: ; t(RECORDING_PATH) = custom recording path ; b = save both legs as separate files (useful for QA — hear agent ; and caller independently). Doubles storage use. ; W(N) = write only when N seconds of audio exist (skip very short calls) ; ; VICIdial setting: Rec MixMon Options ; Example: leave blank for defaults, or add: ; W(3) to skip recordings under 3 seconds (wrong numbers, quick hangups) ; ============================================================================= ; SECTION 3: POST-RECORDING COMPRESSION ; ============================================================================= ; Convert recordings to a smaller format after they're made. ; VICIdial records in the native format. This script batch-converts ; older recordings to save space retroactively. ; ; Add to crontab: crontab -e ; Run nightly at 2am (off-peak hours). ; ============================================================================= ; --- /opt/vicistack/compress-recordings.sh --- ; #!/bin/bash ; # Compress VICIdial call recordings older than 1 day ; # Converts WAV to OGG (Vorbis) for ~90% space savings ; # Generated by ViciStack — https://vicistack.com ; ; RECORDING_DIR="/var/spool/asterisk/monitor" ; COMPRESSED_DIR="/var/spool/asterisk/monitor/compressed" ; LOG="/var/log/recording-compression.log" ; MIN_AGE_DAYS=1 ; ; mkdir -p "$COMPRESSED_DIR" ; ; echo "$(date): Starting compression run" >> "$LOG" ; ; # Find WAV files older than MIN_AGE_DAYS ; find "$RECORDING_DIR" -maxdepth 1 -name "*.wav" -mtime +${MIN_AGE_DAYS} | while read wavfile; do ; basename=$(basename "$wavfile" .wav) ; oggfile="${COMPRESSED_DIR}/${basename}.ogg" ; ; # Skip if already compressed ; if [ -f "$oggfile" ]; then ; continue ; fi ; ; # Convert to OGG with quality 3 (good quality, ~80kbps for voice) ; sox "$wavfile" "$oggfile" 2>> "$LOG" ; ; if [ $? -eq 0 ]; then ; # Verify the OGG file is valid ; soxi "$oggfile" > /dev/null 2>&1 ; if [ $? -eq 0 ]; then ; # Remove original WAV ; rm "$wavfile" ; echo "$(date): Compressed $basename" >> "$LOG" ; else ; echo "$(date): ERROR - Invalid OGG for $basename, keeping WAV" >> "$LOG" ; rm "$oggfile" ; fi ; else ; echo "$(date): ERROR - Failed to compress $basename" >> "$LOG" ; fi ; done ; ; echo "$(date): Compression run complete" >> "$LOG" ; ; # --- Cron entry --- ; # 0 2 * * * /opt/vicistack/compress-recordings.sh ; ; Install sox: yum install sox ; Make executable: chmod +x /opt/vicistack/compress-recordings.sh ; ============================================================================= ; SECTION 4: RECORDING ARCHIVAL & ROTATION ; ============================================================================= ; Move old recordings to cold storage and delete ancient ones. ; Retention periods depend on your industry regulations. ; ; Typical retention requirements: ; General business: 90 days ; Financial services: 3-7 years (SEC/FINRA rules) ; Healthcare: 6 years (HIPAA) ; Insurance: 5-10 years (varies by state) ; No regulation: keep 90 days, archive 1 year, delete after. ; ============================================================================= ; --- /opt/vicistack/archive-recordings.sh --- ; #!/bin/bash ; # Archive and rotate VICIdial call recordings ; # Generated by ViciStack — https://vicistack.com ; ; RECORDING_DIR="/var/spool/asterisk/monitor" ; ARCHIVE_DIR="/recordings/archive" ; LOG="/var/log/recording-archive.log" ; ; # Retention periods (days) ; MOVE_TO_ARCHIVE_AFTER=90 # Move to archive after 90 days ; DELETE_FROM_ARCHIVE_AFTER=365 # Delete archived files after 1 year ; # Adjust these based on your regulatory requirements. ; ; mkdir -p "$ARCHIVE_DIR" ; ; echo "$(date): Starting archive run" >> "$LOG" ; ; # Move recordings older than 90 days to archive ; find "$RECORDING_DIR" -maxdepth 2 -name "*.ogg" -mtime +${MOVE_TO_ARCHIVE_AFTER} -exec mv {} "$ARCHIVE_DIR/" \; 2>> "$LOG" ; find "$RECORDING_DIR" -maxdepth 2 -name "*.gsm" -mtime +${MOVE_TO_ARCHIVE_AFTER} -exec mv {} "$ARCHIVE_DIR/" \; 2>> "$LOG" ; ; MOVED=$(find "$ARCHIVE_DIR" -name "*.ogg" -newer "$LOG" -o -name "*.gsm" -newer "$LOG" | wc -l) ; echo "$(date): Moved $MOVED files to archive" >> "$LOG" ; ; # Delete archived recordings older than 1 year ; DELETED=$(find "$ARCHIVE_DIR" -name "*.ogg" -mtime +${DELETE_FROM_ARCHIVE_AFTER} -o -name "*.gsm" -mtime +${DELETE_FROM_ARCHIVE_AFTER} | wc -l) ; find "$ARCHIVE_DIR" -name "*.ogg" -mtime +${DELETE_FROM_ARCHIVE_AFTER} -delete 2>> "$LOG" ; find "$ARCHIVE_DIR" -name "*.gsm" -mtime +${DELETE_FROM_ARCHIVE_AFTER} -delete 2>> "$LOG" ; echo "$(date): Deleted $DELETED expired archive files" >> "$LOG" ; ; echo "$(date): Archive run complete" >> "$LOG" ; ; # --- Cron entry (run daily at 3am, after compression) --- ; # 0 3 * * * /opt/vicistack/archive-recordings.sh ; ============================================================================= ; SECTION 5: CLOUD BACKUP TO AWS S3 ; ============================================================================= ; Sync recordings to S3 for offsite backup and disaster recovery. ; Also enables playback from S3 URLs if you build a web player. ; ; Prerequisites: ; yum install awscli ; aws configure (set your access key, secret key, region) ; ; S3 Storage Classes (cost per GB/month, us-east-1, approximate): ; Standard: $0.023 — for active recordings (<90 days) ; Standard-IA: $0.0125 — for archive (90-365 days) ; Glacier Flexible: $0.0036 — for long-term retention (>1 year) ; Glacier Deep: $0.00099 — for regulatory retention (>3 years) ; ; Cost example: 50-agent center, OPUS recordings, 1 year retention: ; 222 GB/year * $0.023 = $5.10/month for active ; 222 GB * $0.0036 = $0.80/month for Glacier archive ; Total: ~$6/month. Cheaper than any hard drive. ; ============================================================================= ; --- /opt/vicistack/s3-backup-recordings.sh --- ; #!/bin/bash ; # Sync VICIdial recordings to AWS S3 ; # Generated by ViciStack — https://vicistack.com ; ; S3_BUCKET="s3://your-company-recordings" ; RECORDING_DIR="/var/spool/asterisk/monitor" ; ARCHIVE_DIR="/recordings/archive" ; LOG="/var/log/recording-s3-sync.log" ; ; echo "$(date): Starting S3 sync" >> "$LOG" ; ; # Sync active recordings (Standard storage class) ; aws s3 sync "$RECORDING_DIR" "${S3_BUCKET}/active/" \ ; --exclude "*.wav" \ ; --storage-class STANDARD \ ; --only-show-errors \ ; 2>> "$LOG" ; # Exclude WAV files — only upload compressed versions ; ; # Sync archive recordings (Infrequent Access — cheaper) ; aws s3 sync "$ARCHIVE_DIR" "${S3_BUCKET}/archive/" \ ; --storage-class STANDARD_IA \ ; --only-show-errors \ ; 2>> "$LOG" ; ; echo "$(date): S3 sync complete" >> "$LOG" ; ; # --- S3 Lifecycle Policy --- ; # Create this lifecycle rule on your S3 bucket to auto-transition: ; # { ; # "Rules": [ ; # { ; # "ID": "ArchiveToGlacier", ; # "Status": "Enabled", ; # "Filter": {"Prefix": "archive/"}, ; # "Transitions": [ ; # {"Days": 90, "StorageClass": "GLACIER"}, ; # {"Days": 365, "StorageClass": "DEEP_ARCHIVE"} ; # ], ; # "Expiration": {"Days": 2555} ; # } ; # ] ; # } ; # 2555 days = 7 years (covers most regulatory requirements). ; # Apply: aws s3api put-bucket-lifecycle-configuration \ ; # --bucket your-company-recordings \ ; # --lifecycle-configuration file://lifecycle.json ; ; # --- Cron entry (run daily at 4am, after compression and archival) --- ; # 0 4 * * * /opt/vicistack/s3-backup-recordings.sh ; ============================================================================= ; SECTION 6: DISK USAGE MONITORING ; ============================================================================= ; Don't wait until the disk is full to find out you have a problem. ; ============================================================================= ; --- /opt/vicistack/check-disk-usage.sh --- ; #!/bin/bash ; # Alert if recording disk usage exceeds threshold ; # Generated by ViciStack — https://vicistack.com ; ; THRESHOLD=80 # percent ; MOUNT="/var/spool/asterisk" # or /recordings if separate partition ; ALERT_EMAIL="admin@yourcompany.com" ; ; USAGE=$(df "$MOUNT" | tail -1 | awk '{print $5}' | sed 's/%//') ; ; if [ "$USAGE" -ge "$THRESHOLD" ]; then ; SUBJECT="[VICIdial] Recording disk at ${USAGE}% on $(hostname)" ; BODY="Recording storage at ${USAGE}% capacity on $(hostname). ; ; Current disk usage: ; $(df -h "$MOUNT") ; ; Largest recording directories: ; $(du -sh /var/spool/asterisk/monitor/*/ 2>/dev/null | sort -rh | head -10) ; ; Action needed: Run compression/archival scripts or add storage. ; Guide: https://vicistack.com/blog/vicidial-call-recording-storage-optimization/" ; ; echo "$BODY" | mail -s "$SUBJECT" "$ALERT_EMAIL" ; fi ; ; # --- Cron entry (check every hour) --- ; # 0 * * * * /opt/vicistack/check-disk-usage.sh ; ; For storage optimization consulting: ; https://vicistack.com — hello@vicistack.com ; =============================================================================