# 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 ```bash # Clone the repository git clone 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 videos - `SERMON_OUTPUT_PATH`: Directory where converted videos will be saved Example `.env` file: ```bash SERMON_WATCH_PATH=/home/user/sermons/input SERMON_OUTPUT_PATH=/home/user/sermons/output ``` You can also copy the example: ```bash 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: ```bash export SERMON_WATCH_PATH="/path/to/watch/directory" export SERMON_OUTPUT_PATH="/path/to/output/directory" ``` ## Usage ### Running Manually ```bash # 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: 1. Process any existing MP4 files in the watch directory 2. Continue monitoring for new files using filesystem events 3. 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`: ```ini [Unit] Description=Sermon Video Converter Service After=network.target [Service] Type=simple User= 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: ```bash sudo systemctl daemon-reload sudo systemctl enable sermon-converter sudo systemctl start sermon-converter ``` Check service status: ```bash sudo systemctl status sermon-converter sudo journalctl -u sermon-converter -f ``` ## How It Works The application uses an event-driven architecture for efficient monitoring: 1. **Event Monitoring**: Uses filesystem events to detect new files instantly (no CPU-intensive polling) 2. **File Validation**: Waits for files to be completely written before processing 3. **Smart Processing**: Ignores temporary files (e.g., Syncthing .tmp files) 4. **Quality Conversion**: Converts to optimized streaming format while preserving quality 5. **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 ```bash 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 ```bash RUST_LOG=debug cargo run ``` ### Running Tests ```bash cargo test ``` ### Building for Debug ```bash 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](LICENSE) file for details. ## Contributing Contributions are welcome! Please feel free to submit a Pull Request or open an issue for discussion.