sermon-converter/README.md

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 videos
  • SERMON_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:

  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:

[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:

  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

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.