6.1 KiB
Sermon Converter
A Rust-based service that automatically monitors a directory for new sermon video files and converts them to an optimized format for streaming using an event-driven architecture.
Features
- Event-Driven Architecture: Uses filesystem events for instant file detection (no polling)
- Automatic Detection: Monitors a configured directory for new MP4 files
- Efficient Processing: Hardware-accelerated video conversion using FFmpeg
- Quality Preservation: Preserves audio quality while optimizing video for streaming
- Smart File Handling: Ignores temporary sync files (Syncthing-aware)
- Organized Output: Automatic file organization with date-based naming
- Environment Configuration: Uses .env file for easy configuration management
- Service Integration: Runs as a systemd service with automatic restart
Prerequisites
- Rust (latest stable version)
- FFmpeg installed and available in PATH
- Sufficient disk space for video processing
Installation
Building from Source
# Clone the repository
git clone <repository-url>
cd sermon-converter
# Build release binary
cargo build --release
# Binary will be at target/release/sermon_converter
Configuration
Environment Variables (.env file)
Create a .env
file in the project root with the following variables:
SERMON_WATCH_PATH
: Directory to monitor for new sermon videosSERMON_OUTPUT_PATH
: Directory where converted videos will be saved
Example .env
file:
SERMON_WATCH_PATH=/home/user/sermons/input
SERMON_OUTPUT_PATH=/home/user/sermons/output
You can also copy the example:
cp .env.example .env
# Edit .env with your specific paths
Alternative: Environment Variables
If you prefer not to use a .env
file, you can set environment variables directly:
export SERMON_WATCH_PATH="/path/to/watch/directory"
export SERMON_OUTPUT_PATH="/path/to/output/directory"
Usage
Running Manually
# Run directly (uses .env file automatically)
cargo run --release
# Or run the compiled binary
./target/release/sermon_converter
Running as a Service
The service will:
- Process any existing MP4 files in the watch directory
- Continue monitoring for new files using filesystem events
- Automatically convert new MP4 files as they appear
Running as a System Service
Create a systemd service file at /etc/systemd/system/sermon-converter.service
:
[Unit]
Description=Sermon Video Converter Service
After=network.target
[Service]
Type=simple
User=<your-username>
Group=<your-group>
WorkingDirectory=/path/to/sermon-converter
ExecStart=/path/to/sermon-converter/target/release/sermon_converter
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable sermon-converter
sudo systemctl start sermon-converter
Check service status:
sudo systemctl status sermon-converter
sudo journalctl -u sermon-converter -f
How It Works
The application uses an event-driven architecture for efficient monitoring:
- Event Monitoring: Uses filesystem events to detect new files instantly (no CPU-intensive polling)
- File Validation: Waits for files to be completely written before processing
- Smart Processing: Ignores temporary files (e.g., Syncthing .tmp files)
- Quality Conversion: Converts to optimized streaming format while preserving quality
- Organized Output: Saves converted files with systematic naming
Video Conversion Details
The service converts videos using optimized FFmpeg settings:
- Video codec: H.264 (libx264)
- Audio codec: AAC
- Video preset: medium (good balance of speed/quality)
- Constant Rate Factor (CRF): 23 (high quality)
- Pixel format: yuv420p (universal compatibility)
- Audio bitrate: 128k (good quality for speech)
- Audio sample rate: 44100 Hz (standard quality)
FFmpeg Command Example
ffmpeg -i input.mp4 \
-c:v libx264 -preset medium -crf 23 -pix_fmt yuv420p \
-c:a aac -b:a 128k -ar 44100 \
output.mp4
File Naming Convention
Converted files are named based on the original filename's date pattern:
- Input:
YYYY-MM-DD_sermon.mp4
- Output:
YYYY-MM-DD_sermon_converted.mp4
The service maintains the date-based organization for easy file management.
Troubleshooting
Common Issues
Service not starting
- Check logs:
journalctl -u sermon-converter -f
- Verify
.env
file exists and has correct permissions - Ensure all paths exist and have proper permissions
FFmpeg not found
- Ensure FFmpeg is installed:
ffmpeg -version
- Check that FFmpeg is in your system PATH
- On Ubuntu/Debian:
sudo apt install ffmpeg
- On macOS:
brew install ffmpeg
Permission denied
- Check read permissions for watch directory
- Check write permissions for output directory
- Ensure the service user has access to both directories
Files not detected
- Verify the watch directory path in
.env
- Check that files are completely written before processing
- Ensure filesystem supports events (some network filesystems don't)
- Test with debug output:
RUST_LOG=debug cargo run
Conversion failures
- Check available disk space in output directory
- Verify input files are valid MP4 files
- Test FFmpeg manually with the same input file
Development
Running with Debug Output
RUST_LOG=debug cargo run
Running Tests
cargo test
Building for Debug
cargo build
Performance Notes
- Event-driven: Uses filesystem events instead of polling for better performance
- Efficient processing: Processes files as they arrive rather than batch processing
- Memory efficient: Streams video data rather than loading entire files into memory
- Quality focused: Optimizes for streaming while maintaining sermon audio quality
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request or open an issue for discussion.