Add comprehensive documentation with event-driven architecture details
This commit is contained in:
parent
3f5c9ed02d
commit
9f5d2f4c64
181
README.md
181
README.md
|
@ -1,14 +1,17 @@
|
||||||
# Sermon Converter
|
# 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
|
## Features
|
||||||
|
|
||||||
- Automatic detection of new MP4 files in the watch directory
|
- **Event-Driven Architecture**: Uses filesystem events for instant file detection (no polling)
|
||||||
- Efficient video conversion using FFmpeg
|
- **Automatic Detection**: Monitors a configured directory for new MP4 files
|
||||||
- Preserves audio quality while optimizing video for streaming
|
- **Efficient Processing**: Hardware-accelerated video conversion using FFmpeg
|
||||||
- Automatic file organization with date-based naming
|
- **Quality Preservation**: Preserves audio quality while optimizing video for streaming
|
||||||
- Syncthing-aware (ignores temporary sync files)
|
- **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
|
## Prerequisites
|
||||||
|
|
||||||
|
@ -18,25 +21,44 @@ A Rust-based service that automatically monitors a directory for new sermon vide
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
1. Clone the repository:
|
### Building from Source
|
||||||
```bash
|
|
||||||
git clone <your-repository-url>
|
|
||||||
cd sermon-converter
|
|
||||||
```
|
|
||||||
|
|
||||||
2. Build the project:
|
|
||||||
```bash
|
```bash
|
||||||
|
# Clone the repository
|
||||||
|
git clone <repository-url>
|
||||||
|
cd sermon-converter
|
||||||
|
|
||||||
|
# Build release binary
|
||||||
cargo build --release
|
cargo build --release
|
||||||
|
|
||||||
|
# Binary will be at target/release/sermon_converter
|
||||||
```
|
```
|
||||||
|
|
||||||
## Configuration
|
## 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_WATCH_PATH`: Directory to monitor for new sermon videos
|
||||||
- `SERMON_OUTPUT_PATH`: Directory where converted videos will be saved
|
- `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
|
```bash
|
||||||
export SERMON_WATCH_PATH="/path/to/watch/directory"
|
export SERMON_WATCH_PATH="/path/to/watch/directory"
|
||||||
export SERMON_OUTPUT_PATH="/path/to/output/directory"
|
export SERMON_OUTPUT_PATH="/path/to/output/directory"
|
||||||
|
@ -44,24 +66,26 @@ export SERMON_OUTPUT_PATH="/path/to/output/directory"
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Run the service:
|
### Running Manually
|
||||||
```bash
|
|
||||||
cargo run --release
|
|
||||||
```
|
|
||||||
|
|
||||||
Or run the built binary:
|
|
||||||
```bash
|
```bash
|
||||||
|
# Run directly (uses .env file automatically)
|
||||||
|
cargo run --release
|
||||||
|
|
||||||
|
# Or run the compiled binary
|
||||||
./target/release/sermon_converter
|
./target/release/sermon_converter
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Running as a Service
|
||||||
|
|
||||||
The service will:
|
The service will:
|
||||||
1. Process any existing MP4 files in the watch directory
|
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
|
3. Automatically convert new MP4 files as they appear
|
||||||
|
|
||||||
## Running as a System Service
|
## 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
|
```ini
|
||||||
[Unit]
|
[Unit]
|
||||||
|
@ -71,11 +95,13 @@ After=network.target
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
User=<your-username>
|
User=<your-username>
|
||||||
Environment="SERMON_WATCH_PATH=/path/to/watch/directory"
|
Group=<your-group>
|
||||||
Environment="SERMON_OUTPUT_PATH=/path/to/output/directory"
|
WorkingDirectory=/path/to/sermon-converter
|
||||||
ExecStart=/path/to/sermon_converter
|
ExecStart=/path/to/sermon-converter/target/release/sermon_converter
|
||||||
Restart=always
|
Restart=always
|
||||||
RestartSec=10
|
RestartSec=10
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
@ -83,37 +109,114 @@ WantedBy=multi-user.target
|
||||||
|
|
||||||
Enable and start the service:
|
Enable and start the service:
|
||||||
```bash
|
```bash
|
||||||
|
sudo systemctl daemon-reload
|
||||||
sudo systemctl enable sermon-converter
|
sudo systemctl enable sermon-converter
|
||||||
sudo systemctl start 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
|
## Video Conversion Details
|
||||||
|
|
||||||
The service converts videos using the following FFmpeg settings:
|
The service converts videos using optimized FFmpeg settings:
|
||||||
- Video codec: H.264 (libx264)
|
|
||||||
- Audio codec: AAC
|
- **Video codec**: H.264 (libx264)
|
||||||
- Video preset: medium
|
- **Audio codec**: AAC
|
||||||
- Constant Rate Factor (CRF): 23
|
- **Video preset**: medium (good balance of speed/quality)
|
||||||
- Pixel format: yuv420p
|
- **Constant Rate Factor (CRF)**: 23 (high quality)
|
||||||
- Audio bitrate: 128k
|
- **Pixel format**: yuv420p (universal compatibility)
|
||||||
- Audio sample rate: 44100 Hz
|
- **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
|
## File Naming Convention
|
||||||
|
|
||||||
Converted files are named based on the original filename's date pattern:
|
Converted files are named based on the original filename's date pattern:
|
||||||
- Input: `YYYY-MM-DD_sermon.mp4`
|
- **Input**: `YYYY-MM-DD_sermon.mp4`
|
||||||
- Output: `YYYY-MM-DD_sermon_converted.mp4`
|
- **Output**: `YYYY-MM-DD_sermon_converted.mp4`
|
||||||
|
|
||||||
|
The service maintains the date-based organization for easy file management.
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
|
|
||||||
- **FFmpeg not found**: Ensure FFmpeg is installed and in your system PATH
|
### Common Issues
|
||||||
- **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
|
**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
|
## License
|
||||||
|
|
||||||
See LICENSE file for details.
|
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
||||||
|
|
||||||
## Contributing
|
## 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.
|
Loading…
Reference in a new issue