{"id":29121569,"url":"https://github.com/dampdigits/hexafalls2k25","last_synced_at":"2025-06-29T17:00:33.484Z","repository":{"id":301826354,"uuid":"1010412797","full_name":"dampdigits/hexafalls2k25","owner":"dampdigits","description":"A robust video processing pipeline for downloading, concatenating, transcribing, and uploading video and audio chunks from Cloudflare R2 storage.","archived":false,"fork":false,"pushed_at":"2025-06-29T03:23:42.000Z","size":16,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-06-29T04:26:30.526Z","etag":null,"topics":["boto3","cloudflare-r2","ffmpeg","flask","python","whisper"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dampdigits.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-29T02:38:37.000Z","updated_at":"2025-06-29T03:25:56.000Z","dependencies_parsed_at":"2025-06-29T04:26:34.853Z","dependency_job_id":"cfd98325-015f-4f43-bc8e-10e67771055c","html_url":"https://github.com/dampdigits/hexafalls2k25","commit_stats":null,"previous_names":["dampdigits/hexafalls2k25"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dampdigits/hexafalls2k25","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dampdigits%2Fhexafalls2k25","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dampdigits%2Fhexafalls2k25/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dampdigits%2Fhexafalls2k25/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dampdigits%2Fhexafalls2k25/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dampdigits","download_url":"https://codeload.github.com/dampdigits/hexafalls2k25/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dampdigits%2Fhexafalls2k25/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262632277,"owners_count":23340208,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["boto3","cloudflare-r2","ffmpeg","flask","python","whisper"],"created_at":"2025-06-29T17:00:27.209Z","updated_at":"2025-06-29T17:00:33.457Z","avatar_url":"https://github.com/dampdigits.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hexafalls 2K25 🎬\n\nA modern, scalable video processing pipeline built with Flask that downloads, processes, transcribes, and uploads video chunks from Cloudflare R2 storage. Designed for real-time video conference recording processing with AI-powered transcription.\n\n## 🚀 Overview\n\nHexafalls 2K25 is a production-ready Flask web service that processes video and audio chunks into professional-quality media files with embedded transcriptions. The system features a RESTful API for seamless integration with video conferencing platforms and real-time processing capabilities.\n\n### Key Features\n\n- 🎥 **Professional Video Processing**: Converts WebM chunks to high-quality MP4 with H.264 encoding\n- 🎤 **AI-Powered Transcription**: OpenAI Whisper integration with multiple model sizes\n- 🌐 **RESTful API**: Easy integration with existing systems\n- ☁️ **Cloud Storage**: Seamless Cloudflare R2 integration\n- 🔄 **Asynchronous Processing**: Non-blocking pipeline execution\n- 📱 **Soft Subtitles**: Embedded captions in MP4 containers\n- 🛡️ **Error Handling**: Robust error recovery and logging\n\n## 🏗️ Architecture\n\n```\n├── Flask Web Service\n│   ├── RESTful API Endpoints\n│   ├── Asynchronous Processing\n│   └── Configuration Management\n├── Video Processing Pipeline\n│   ├── Chunk Download \u0026 Validation\n│   ├── FFmpeg-based Processing\n│   ├── Whisper AI Transcription\n│   └── Cloud Upload\n└── Storage Layer\n    ├── Cloudflare R2 (Primary)\n    └── Local Temporary Storage\n```\n\n## 🔧 Tech Stack\n\n- **Flask 3.1+**: Modern Python web framework\n- **Python 3.12+**: Core programming language\n- **FFmpeg**: Professional video/audio processing\n- **OpenAI Whisper**: State-of-the-art speech recognition\n- **Cloudflare R2**: S3-compatible object storage\n- **boto3**: AWS SDK for Python (R2 integration)\n- **Threading**: Asynchronous task processing\n\n## ⚙️ Installation\n\n### Prerequisites\n\n- Python 3.12 or higher\n- FFmpeg installed and accessible in PATH\n- Cloudflare R2 account and credentials\n\n### Setup\n\n1. **Clone the repository:**\n   ```bash\n   git clone https://github.com/yourusername/hexafalls2k25.git\n   cd hexafalls2k25\n   ```\n\n2. **Create and activate virtual environment:**\n   ```bash\n   python -m venv venv\n   source venv/bin/activate  # On Windows: venv\\Scripts\\activate\n   ```\n\n3. **Install dependencies:**\n   ```bash\n   pip install -r requirements.txt\n   ```\n\n4. **Install FFmpeg:**\n   ```bash\n   # Ubuntu/Debian\n   sudo apt update \u0026\u0026 sudo apt install ffmpeg\n   \n   # macOS\n   brew install ffmpeg\n   \n   # Windows (using chocolatey)\n   choco install ffmpeg\n   ```\n\n5. **Configure environment variables:**\n   Create a `.env` file in the project root:\n   ```env\n   S3_ACCESS_KEY_ID=your_r2_access_key\n   S3_SECRET_ACCESS_KEY=your_r2_secret_key\n   ACCOUNT_ID=your_cloudflare_account_id\n   S3_BUCKET_NAME=your_r2_bucket_name\n   ```\n\n## 🚀 Quick Start\n\n### Start the Flask Service\n\n```bash\n# Development mode\nflask run\n\n# Production mode with custom host/port\nflask run --host=0.0.0.0 --port=5000\n\n# Using Python directly\npython run.py\n```\n\n### API Usage\n\n#### Submit Processing Job\n\n```bash\ncurl -X POST http://localhost:5000/submit \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"meeting_id\": \"meeting_123\",\n    \"take\": \"1\",\n    \"user_id\": \"user_456\",\n    \"whisper_model\": \"base\",\n    \"cleanup\": true,\n    \"skip_transcription\": false\n  }'\n```\n\n#### Check Service Status\n\n```bash\ncurl http://localhost:5000/status\n```\n\n## 📡 API Reference\n\n### POST `/submit`\n\nInitiates video processing pipeline for specified meeting chunks.\n\n**Request Body:**\n```json\n{\n  \"meeting_id\": \"string (required)\",\n  \"take\": \"string (required)\", \n  \"user_id\": \"string (required)\",\n  \"whisper_model\": \"string (optional, default: 'base')\",\n  \"cleanup\": \"boolean (optional, default: true)\",\n  \"skip_transcription\": \"boolean (optional, default: false)\"\n}\n```\n\n**Response:**\n```json\n{\n  \"status\": \"success\",\n  \"message\": \"Video processing pipeline started\",\n  \"meeting_id\": \"meeting_123\",\n  \"take\": \"1\",\n  \"user_id\": \"user_456\",\n  \"config\": {\n    \"REMOTE_DIR\": \"recordings/meeting_123/1/user_456\",\n    \"LOCAL_DIR\": \"../chunks/meeting_123/1/user_456\",\n    \"OUTPUT_DIR\": \"../recordings/meeting_123/1/user_456\",\n    \"UPLOAD_DIR\": \"recordings/meeting_123/1\"\n  },\n  \"options\": {\n    \"whisper_model\": \"base\",\n    \"cleanup\": true,\n    \"skip_transcription\": false\n  }\n}\n```\n\n### GET `/status`\n\nReturns service health status.\n\n**Response:**\n```json\n{\n  \"status\": \"running\",\n  \"message\": \"Video processing service is running\"\n}\n```\n\n## 🔄 Processing Pipeline\n\n### 1. **Initialization \u0026 Configuration**\n   - Validate API request parameters\n   - Configure directory structures\n   - Initialize processing components\n\n### 2. **Chunk Download**\n   - Connect to Cloudflare R2 storage\n   - Download video/audio chunks by prefix\n   - Organize files by type (video/audio)\n\n### 3. **Video Processing**\n   - Concatenate WebM video chunks\n   - Fix timestamp inconsistencies\n   - Convert to H.264 MP4 format\n\n### 4. **Audio Processing**\n   - Concatenate WebM audio chunks\n   - Extract to WAV format for transcription\n   - Encode to AAC for final output\n\n### 5. **AI Transcription** (Optional)\n   - Load Whisper model (tiny/base/small/medium/large)\n   - Generate timestamped transcription\n   - Create SRT subtitle files\n   - Export JSON metadata\n\n### 6. **Final Assembly**\n   - Mux video, audio, and subtitles\n   - Embed soft captions in MP4 container\n   - Optimize for web delivery\n\n### 7. **Upload \u0026 Cleanup**\n   - Upload processed files to R2\n   - Standardized naming convention\n   - Clean temporary files (optional)\n\n## 🎛️ Configuration Options\n\n### Whisper Models\n- `tiny`: Fastest, lowest accuracy (~1GB VRAM)\n- `base`: Balanced performance (default, ~1GB VRAM)\n- `small`: Better accuracy (~2GB VRAM)\n- `medium`: High accuracy (~5GB VRAM)\n- `large`: Best accuracy (~10GB VRAM)\n\n### Processing Options\n- `cleanup`: Remove temporary files after processing\n- `skip_transcription`: Skip AI transcription step\n- Custom output directories and naming\n\n## 📁 Project Structure\n\n```\nhexafalls2k25/\n├── app/                    # Flask application package\n│   ├── __init__.py        # Flask app initialization\n│   ├── routes.py          # API endpoint definitions\n│   ├── worker.py          # Core processing pipeline\n│   ├── driver.py          # Configuration management\n│   └── chunksToVideo.py   # Standalone video processor\n├── run.py                 # Flask application entry point\n├── config.py              # Application configuration\n├── requirements.txt       # Python dependencies\n├── .env                   # Environment variables (not tracked)\n├── README.md              # This file\n└── .gitignore            # Git ignore rules\n```\n\n## 🐳 Docker Deployment\n\n```dockerfile\nFROM python:3.12-slim\n\n# Install FFmpeg\nRUN apt-get update \u0026\u0026 apt-get install -y ffmpeg\n\n# Set working directory\nWORKDIR /app\n\n# Copy requirements and install dependencies\nCOPY requirements.txt .\nRUN pip install --no-cache-dir -r requirements.txt\n\n# Copy application code\nCOPY . .\n\n# Expose port\nEXPOSE 5000\n\n# Run Flask application\nCMD [\"flask\", \"run\", \"--host=0.0.0.0\"]\n```\n\n## 🔧 Development\n\n### Local Development Setup\n\n```bash\n# Install development dependencies\npip install -r requirements.txt\n\n# Run with debug mode\nexport FLASK_ENV=development\nflask run --debug\n\n# Run tests (if available)\npython -m pytest\n```\n\n### Standalone Processing\n\nFor local testing without the Flask API:\n\n```bash\n# Process local chunks directly\npython app/chunksToVideo.py\n\n# Test R2 connectivity\npython accessR2.py\n```\n\n## 🚨 Troubleshooting\n\n### Common Issues\n\n1. **FFmpeg not found**: Ensure FFmpeg is installed and in PATH\n2. **R2 connection failed**: Verify credentials in `.env` file\n3. **Whisper model loading**: Check available VRAM for larger models\n4. **Chunk not found**: Verify correct meeting_id/take/user_id combination\n\n### Debug Mode\n\nEnable detailed logging:\n```bash\nexport FLASK_ENV=development\nflask run --debug\n```\n\n## 📊 Performance\n\n### Processing Times (Approximate)\n- **10 minutes of video**: ~2-5 minutes processing\n- **Whisper transcription**: +30-60 seconds per minute of audio\n- **Upload speed**: Depends on bandwidth and file size\n\n### Resource Requirements\n- **CPU**: Multi-core recommended for FFmpeg\n- **RAM**: 2-4GB base + Whisper model size\n- **Storage**: 3x source file size during processing\n- **Network**: Stable connection for R2 operations\n\n## 🛡️ Security\n\n- Environment variables for sensitive credentials\n- Input validation on all API endpoints\n- Secure temporary file handling\n- Automatic cleanup of processed files\n\n## 👥 Contributors\n\n**Team Bolts**\n- [Sk Sameer Salam](https://github.com/dampdigits) - Lead Developer\n- [Tushar Daiya](https://github.com/tushar-daiya/) - Backend Engineer\n- [Sougata Mandal](https://github.com/SougataXdev) - DevOps Engineer\n- [Aquib Alam](https://github.com/aquib399) - Frontend Integration\n\n## 📄 License\n\nThis project is licensed under the MIT License - see the LICENSE file for details.\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n---\n\nFor support, feature requests, or bug reports, please open an issue on GitHub.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdampdigits%2Fhexafalls2k25","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdampdigits%2Fhexafalls2k25","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdampdigits%2Fhexafalls2k25/lists"}