sermon-converter/README.md

222 lines
6.1 KiB
Markdown

# 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 <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 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=<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:
```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.