Add comprehensive documentation with event-driven architecture details

This commit is contained in:
Benjamin Slingo 2025-09-08 13:06:34 -04:00
parent 3f5c9ed02d
commit 9f5d2f4c64

181
README.md
View file

@ -1,14 +1,17 @@
# 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.
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
- Automatic detection of new MP4 files in the watch directory
- Efficient video conversion using FFmpeg
- Preserves audio quality while optimizing video for streaming
- Automatic file organization with date-based naming
- Syncthing-aware (ignores temporary sync files)
- **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
@ -18,25 +21,44 @@ A Rust-based service that automatically monitors a directory for new sermon vide
## Installation
1. Clone the repository:
```bash
git clone <your-repository-url>
cd sermon-converter
```
### Building from Source
2. Build the project:
```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
The service uses environment variables for 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:
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"
@ -44,24 +66,26 @@ export SERMON_OUTPUT_PATH="/path/to/output/directory"
## Usage
Run the service:
```bash
cargo run --release
```
### Running Manually
Or run the built binary:
```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
2. Continue monitoring for new files using filesystem events
3. Automatically convert new MP4 files as they appear
## Running as a System Service
To run as a systemd service, create a service file at `/etc/systemd/system/sermon-converter.service`:
Create a systemd service file at `/etc/systemd/system/sermon-converter.service`:
```ini
[Unit]
@ -71,11 +95,13 @@ After=network.target
[Service]
Type=simple
User=<your-username>
Environment="SERMON_WATCH_PATH=/path/to/watch/directory"
Environment="SERMON_OUTPUT_PATH=/path/to/output/directory"
ExecStart=/path/to/sermon_converter
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
@ -83,37 +109,114 @@ 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 the following FFmpeg settings:
- Video codec: H.264 (libx264)
- Audio codec: AAC
- Video preset: medium
- Constant Rate Factor (CRF): 23
- Pixel format: yuv420p
- Audio bitrate: 128k
- Audio sample rate: 44100 Hz
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`
- **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
- **FFmpeg not found**: Ensure FFmpeg is installed and in your system PATH
- **Permission denied**: Check that the service has read/write permissions for both watch and output directories
- **Files not detected**: Verify the watch directory path and that files are complete before processing
### 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
See LICENSE file for details.
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
## Contributing
Contributions are welcome! Please submit pull requests or issues through the repository.
Contributions are welcome! Please feel free to submit a Pull Request or open an issue for discussion.