The Media Processor is built using a Service-Oriented Architecture (SOA) pattern with emphasis on separation of concerns, reusability, and maintainability. This document outlines the architectural decisions and design patterns used.
┌─────────────────────────────────────────┐
│ Program.cs (Entry Point) │
│ ├─ Argument Parsing │
│ └─ Error Handling │
├─────────────────────────────────────────┤
│ MediaProcessorService (Orchestrator)│
│ ├─ Coordinates all services │
│ └─ Executes workflow │
├─────────────────────────────────────────┤
│ Service Layer │
│ ├─ FileValidationService │
│ ├─ TemporaryFolderService │
│ ├─ ImageProcessingService │
│ └─ VideoProcessingService │
├─────────────────────────────────────────┤
│ Model Layer │
│ ├─ MediaType (Enum) │
│ ├─ MediaFile (Domain Model) │
│ └─ OperationResult (Result Pattern) │
└─────────────────────────────────────────┘
Each logical responsibility is encapsulated in its own service:
FileValidationService
- Validates file format
- Checks file integrity
- Manages supported format lists
TemporaryFolderService
- Creates temporary directories
- Manages subfolder creation
- Handles cleanup operations
ImageProcessingService
- Copies images to destination
- Handles image-specific operations
VideoProcessingService
- Extracts video frames
- Gets video metadata
- Manages FFMpeg integration
MediaProcessorService (Orchestrator)
- Coordinates all services
- Executes the main workflow
- Manages service lifecycle
Operations return standardized OperationResult objects instead of throwing exceptions:
public class OperationResult
{
public bool Success { get; set; }
public string Message { get; set; }
public string? OutputPath { get; set; }
}Benefits:
- Explicit error handling
- No hidden exceptions
- Fluent API for result inspection
- Better for error logging and reporting
- MediaType Enum: Ensures type safety for media classification
- MediaFile: Encapsulates file information and validation state
- OperationResult: Standardizes all operation responses
TemporaryFolderService implements IDisposable:
public class TemporaryFolderService : IDisposable
{
public void Dispose() { /* cleanup */ }
}Used with using statement in Program.cs:
using (var processor = new MediaProcessorService())
{
// Processing happens here
} // Automatic cleanup on exitBenefits:
- Guaranteed cleanup of temporary files
- Proper resource disposal
- Finalizer for safety net
Each step validates its inputs before proceeding:
1. File exists? → No → Return error
2. Valid format? → No → Return error
3. Temp folder created? → Yes → Continue
4. Process file → Return result
| Service | Responsibility | Dependencies |
|---|---|---|
| FileValidationService | Format validation | None - Stateless |
| TemporaryFolderService | Folder lifecycle | System.IO, IDisposable |
| ImageProcessingService | Image operations | System.IO |
| VideoProcessingService | Video operations | FFMpegCore |
| MediaProcessorService | Orchestration | All services |
| Program | Application flow | MediaProcessorService |
User Input (file path)
↓
Program.cs validates argument
↓
MediaProcessorService.ProcessMedia()
├─ FileValidationService.ValidateMediaFile()
│ └─ Returns MediaFile with validation status
├─ TemporaryFolderService.CreateTempFolder()
│ └─ Returns temp folder path
└─ Based on media type:
├─ Image: ImageProcessingService.CopyImage()
│ └─ Returns OperationResult
└─ Video: TemporaryFolderService.CreateSubfolder("video-frames")
+ VideoProcessingService.ExtractFrames()
└─ Returns OperationResult
↓
Program.cs displays result
- Service Level: Each service catches exceptions and returns results
- Orchestrator Level: MediaProcessorService coordinates and reports errors
- Program Level: Program.cs is the final error handler
Example from VideoProcessingService:
try
{
FFMpegArguments
.FromFileInput(sourceVideoPath)
.OutputToFile(frameOutputPattern, overwrite: true, options => ...)
.ProcessSynchronously();
}
catch (FFMpegException ex)
{
return OperationResult.CreateFailure($"FFMpeg error: {ex.Message}");
}
catch (Exception ex)
{
return OperationResult.CreateFailure($"Unexpected error: {ex.Message}");
}All error messages are:
- User-friendly: Clear indication of what went wrong
- Actionable: Guides user on what to do
- Technical: Enough detail for debugging
Examples:
✗ Error: File does not exist: C:\nonexistent\video.mp4
✗ Error: Unsupported file format: .txt
✗ Error: Video file is corrupted or not accessible
The architecture allows easy extension for future features:
- Add to
MediaTypeenum - Create new
[Type]ProcessingService - Update
FileValidationServicewith extensions - Add handler in
MediaProcessorService
- Create
BatchProcessorService - Reuse existing services
- Return batch results
- Create
IConfigurationService - Pass to services via constructor
- Modify behavior without code changes
- Implement
ILoggerinterface - Inject into services
- Log at decision points
- .NET 8.0: Latest LTS framework
- C# 12: Latest language features used
- Nullable reference types: Type safety
- FFMpegCore v5.1.0: Video frame extraction
- Wrapper around FFMpeg CLI
- Handles async operations
- Cross-platform support
- System.IO: File and folder operations
- System.Collections.Generic: Collections
- Streams for large file reading (not in current version)
- Lazy initialization of services
- GC-friendly disposal patterns
- FFMpeg native performance (optimized C implementation)
- Frame extraction runs synchronously (blocking)
- Suitable for single files
- Single file processing per execution
- Batch processing requires separate implement
- Video frame extraction uses FFMpeg's native speed
Currently, configuration is hardcoded as safe defaults:
Supported Extensions (FileValidationService.cs):
- Update
SupportedImageExtensionsset - Update
SupportedVideoExtensionsset
Temporary Folder (TemporaryFolderService.cs):
- Uses
Path.GetTempPath()(user's temp folder) - Could be configured for specific location
Frame Output (VideoProcessingService.cs):
- PNG format (lossless)
- Sequential naming:
frame_0001.png,frame_0002.png - Could support format/naming configuration
- XML documentation on all public members
- Clear comments for complex logic
- README and architecture guides
- PascalCase for classes and methods
- camelCase for private fields
- Descriptive names explaining purpose
- No swallowing exceptions
- All operations return results
- Meaningful error messages
- Service classes are testable
- Dependencies can be injected
- No static dependencies (except for now)
- Configuration file support
- Advanced image processing
- Command-line options for frame extraction
- Dependency injection container
- Logging framework integration
- Unit tests structure
- Batch processing service
- REST API wrapper
- Plugin architecture
- Cloud storage support
- Performance metrics/monitoring
The Media Processor is designed with maintainability, extensibility, and reliability as core principles. The service-oriented architecture makes it easy to understand, test, and extend, while solid error handling ensures robustness in production environments.
The foundation is flexible enough to support significant feature additions while maintaining code quality and architecture integrity.