Initial commit: v0.1.0 - stable baseline
This commit is contained in:
commit
55382180a5
37
Makefile
Normal file
37
Makefile
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
# VideoTools Makefile
|
||||||
|
# Cross-platform installer for Linux and Windows (Git Bash/WSL)
|
||||||
|
|
||||||
|
PREFIX ?= /usr/local
|
||||||
|
INSTALL_DIR = $(PREFIX)/bin
|
||||||
|
DOC_DIR = $(PREFIX)/share/doc/videotools
|
||||||
|
|
||||||
|
SCRIPT = video-tools.sh
|
||||||
|
DOCS = docs
|
||||||
|
|
||||||
|
install:
|
||||||
|
@echo "Installing VideoTools..."
|
||||||
|
mkdir -p "$(INSTALL_DIR)"
|
||||||
|
cp "$(SCRIPT)" "$(INSTALL_DIR)/video-tools"
|
||||||
|
chmod +x "$(INSTALL_DIR)/video-tools"
|
||||||
|
@echo "Copied script to $(INSTALL_DIR)/video-tools"
|
||||||
|
|
||||||
|
mkdir -p "$(DOC_DIR)"
|
||||||
|
cp -r "$(DOCS)"/* "$(DOC_DIR)/"
|
||||||
|
@echo "Documentation installed to $(DOC_DIR)"
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
@echo "Removing VideoTools..."
|
||||||
|
rm -f "$(INSTALL_DIR)/video-tools"
|
||||||
|
rm -rf "$(DOC_DIR)"
|
||||||
|
@echo "VideoTools uninstalled."
|
||||||
|
|
||||||
|
docs:
|
||||||
|
@echo "Opening documentation..."
|
||||||
|
@ls -1 $(DOCS)
|
||||||
|
|
||||||
|
help:
|
||||||
|
@echo "Available targets:"
|
||||||
|
@echo " make install Install the toolkit system-wide"
|
||||||
|
@echo " make uninstall Remove the toolkit"
|
||||||
|
@echo " make docs List documentation files"
|
||||||
|
@echo " make help Show this message"
|
||||||
13
config/config.json
Normal file
13
config/config.json
Normal file
|
|
@ -0,0 +1,13 @@
|
||||||
|
{
|
||||||
|
"version": "0.1.0",
|
||||||
|
"output_dir": "~/Videos",
|
||||||
|
"video_codec": "libx264",
|
||||||
|
"audio_codec": "aac",
|
||||||
|
"crf": 18,
|
||||||
|
"preset": "slow",
|
||||||
|
"audio_bitrate": "192k",
|
||||||
|
"default_filter": "lanczos",
|
||||||
|
"enable_faststart": true,
|
||||||
|
"auto_timestamp_fix": true,
|
||||||
|
"allow_overwrite": false
|
||||||
|
}
|
||||||
140
docs/CLI_Functions.md
Normal file
140
docs/CLI_Functions.md
Normal file
|
|
@ -0,0 +1,140 @@
|
||||||
|
# CLI Function Reference
|
||||||
|
|
||||||
|
This document describes the available commands in `video-tools.sh`.
|
||||||
|
Each command can be run from any terminal once the tool is installed.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
| Command | Syntax | Description |
|
||||||
|
|----------|---------|-------------|
|
||||||
|
| `convert-single` | `video-tools convert-single <input> <output.mp4>` | Converts a single video to MP4. |
|
||||||
|
| `convert-multiple` | `video-tools convert-multiple <input1> <input2> ... <output.mp4>` | Combines multiple video files into one MP4. |
|
||||||
|
|
||||||
|
All outputs are saved in your default `~/Videos` folder.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Command Details
|
||||||
|
|
||||||
|
### 1. convert-single
|
||||||
|
|
||||||
|
**Purpose**
|
||||||
|
Convert a single input video file into an MP4 with modern compression and audio standards.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
```bash
|
||||||
|
video-tools convert-single <input> <output.mp4>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
```bash
|
||||||
|
video-tools convert-single \
|
||||||
|
"/run/media/user/Linux/MyData/Videos/Example Collection/Example Movie Part1.avi" \
|
||||||
|
"Example Movie.mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output**
|
||||||
|
```
|
||||||
|
/home/user/Videos/Example Movie.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
**Behavior**
|
||||||
|
- Converts older formats (AVI, MPG, MOV, MKV, etc.) into MP4.
|
||||||
|
- Ensures output uses the H.264 codec (libx264) and AAC audio.
|
||||||
|
- Rebuilds timestamps to avoid sync issues.
|
||||||
|
- Adds `+faststart` flag for quicker playback when streamed or loaded in players.
|
||||||
|
|
||||||
|
**When to use**
|
||||||
|
- When you want to upgrade old videos to a more efficient format.
|
||||||
|
- When a single video won’t play on mobile or modern devices.
|
||||||
|
- To reduce file size without losing visible quality.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2. convert-multiple
|
||||||
|
|
||||||
|
**Purpose**
|
||||||
|
Combine several clips or discs into one MP4 output file.
|
||||||
|
|
||||||
|
**Usage**
|
||||||
|
```bash
|
||||||
|
video-tools convert-multiple <input1> <input2> ... <output.mp4>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example**
|
||||||
|
```bash
|
||||||
|
video-tools convert-multiple \
|
||||||
|
"/run/media/user/Linux/MyData/Videos/Example Collection/Example Movie Part1.avi" \
|
||||||
|
"/run/media/user/Linux/MyData/Videos/Example Collection/Example Movie Part2.avi" \
|
||||||
|
"/run/media/user/Linux/MyData/Videos/Example Collection/Example Movie Part3.avi" \
|
||||||
|
"Example Movie Combined.mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Output**
|
||||||
|
```
|
||||||
|
/home/user/Videos/Example Movie Combined.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
**Behavior**
|
||||||
|
- Reads all listed files in order and merges them seamlessly.
|
||||||
|
- Each input is re-encoded using the same H.264/AAC settings.
|
||||||
|
- Temporary file list is automatically created and deleted.
|
||||||
|
- Logs detailed FFmpeg progress to the terminal.
|
||||||
|
|
||||||
|
**When to use**
|
||||||
|
- When combining multi-part video discs, episodes, or scene splits.
|
||||||
|
- When creating a single playable MP4 from segmented source material.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Return Codes
|
||||||
|
|
||||||
|
| Code | Meaning |
|
||||||
|
|------|----------|
|
||||||
|
| 0 | Success |
|
||||||
|
| 1 | Invalid syntax or missing arguments |
|
||||||
|
| 2 | FFmpeg execution error |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Common Issues
|
||||||
|
|
||||||
|
| Symptom | Cause | Fix |
|
||||||
|
|----------|--------|----|
|
||||||
|
| Conversion fails immediately | Input path invalid | Ensure file path is correct and quoted |
|
||||||
|
| Merge creates sync issues | Source files differ in resolution or frame rate | Convert each to MP4 first, then merge |
|
||||||
|
| Output not found | FFmpeg failed silently | Check terminal logs for permission or codec errors |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Planned Additions
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `convert-batch` | Convert every video in a folder automatically |
|
||||||
|
| `upscale-video` | Upscale videos to 1080p or 4K using `lanczos` or ML filters |
|
||||||
|
| `compress-video` | Recompress MP4s using HEVC or AV1 for smaller storage |
|
||||||
|
| `video-info` | Quick summary of resolution, codec, and bitrate |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technical Summary
|
||||||
|
|
||||||
|
### Conversion Logic
|
||||||
|
- Uses FFmpeg with explicit input and output flags:
|
||||||
|
```
|
||||||
|
ffmpeg -fflags +genpts -i "input" -c:v libx264 -crf 18 -preset slow -c:a aac -b:a 192k -movflags +faststart "output"
|
||||||
|
```
|
||||||
|
- `-fflags +genpts` regenerates presentation timestamps (avoids "Non-monotonic DTS" errors).
|
||||||
|
- Re-encoding ensures compatibility and stable playback.
|
||||||
|
|
||||||
|
### File Safety
|
||||||
|
- Original files are untouched.
|
||||||
|
- All intermediate list files are removed automatically.
|
||||||
|
- FFmpeg handles SIGINT (Ctrl+C) gracefully—partially written files are still playable.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
End of File
|
||||||
99
docs/Conversion_Settings.md
Normal file
99
docs/Conversion_Settings.md
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Conversion Settings
|
||||||
|
|
||||||
|
This file documents the default FFmpeg parameters used in `video-tools.sh` and explains why they are chosen.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
All conversions produce:
|
||||||
|
```
|
||||||
|
Format: MP4
|
||||||
|
Container: MPEG-4 Part 14
|
||||||
|
Video Codec: H.264 (libx264)
|
||||||
|
Audio Codec: AAC
|
||||||
|
```
|
||||||
|
|
||||||
|
MP4 was chosen because:
|
||||||
|
- It’s universally supported across modern devices.
|
||||||
|
- It balances size and compatibility well.
|
||||||
|
- H.264 encoding provides excellent quality at smaller bitrates.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Default Parameters
|
||||||
|
|
||||||
|
| Parameter | Value | Purpose |
|
||||||
|
|------------|--------|----------|
|
||||||
|
| `-c:v libx264` | H.264 video encoding | Modern, efficient codec with wide hardware support |
|
||||||
|
| `-crf 18` | Constant Rate Factor | Maintains near-lossless visual quality; lower = better |
|
||||||
|
| `-preset slow` | Encoding preset | Improves compression efficiency; trades some speed |
|
||||||
|
| `-c:a aac` | Audio codec | Standard high-quality stereo audio |
|
||||||
|
| `-b:a 192k` | Audio bitrate | Balances fidelity and file size |
|
||||||
|
| `-movflags +faststart` | MP4 optimization | Enables faster playback start in players or web streams |
|
||||||
|
| `-fflags +genpts` | Timestamp repair | Regenerates timestamps on older AVI/MPEG inputs |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quality vs. File Size
|
||||||
|
|
||||||
|
The CRF scale (used by FFmpeg) defines quality and compression balance:
|
||||||
|
|
||||||
|
| CRF | Description | Typical Use |
|
||||||
|
|------|-------------|--------------|
|
||||||
|
| 14–16 | Near lossless | Archival or professional mastering |
|
||||||
|
| 18–20 | High quality | Everyday use, visually lossless |
|
||||||
|
| 21–24 | Medium quality | Small file sizes, light compression |
|
||||||
|
| 25+ | Low quality | Fast compression, heavy size reduction |
|
||||||
|
|
||||||
|
The default of **CRF 18** keeps visual clarity virtually identical to the original while cutting most AVI or MPG files to **40–60% smaller** sizes.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Why Preset "slow"
|
||||||
|
|
||||||
|
The preset defines encoding effort vs. compression efficiency.
|
||||||
|
Options range from `ultrafast` → `veryslow`.
|
||||||
|
|
||||||
|
- **slow** provides strong compression without extreme CPU time.
|
||||||
|
- Encoding speed is roughly 2–3× real-time on a midrange CPU.
|
||||||
|
- File sizes are typically 10–20% smaller than `medium` preset at the same quality.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Audio Strategy
|
||||||
|
|
||||||
|
AAC at 192k is chosen for:
|
||||||
|
- Wide playback compatibility (phones, TVs, players).
|
||||||
|
- Transparent stereo sound for most sources.
|
||||||
|
- Reasonable storage size (~2MB/minute of stereo audio).
|
||||||
|
|
||||||
|
If future needs arise, the tool can later support:
|
||||||
|
- `-c:a copy` for untouched audio streams.
|
||||||
|
- `-b:a 320k` for high-fidelity preservation.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Color Space & Scaling
|
||||||
|
|
||||||
|
No scaling is applied by default.
|
||||||
|
The video retains original resolution and color profile.
|
||||||
|
|
||||||
|
Upscaling and filtering will be handled in a separate command (`upscale-video`) in future versions, with support for:
|
||||||
|
- FFmpeg’s `scale` and `zscale` filters.
|
||||||
|
- `lanczos` resampling (for sharp, clean upscale).
|
||||||
|
- Optional integration with ML-based models (Real-ESRGAN, waifu2x).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Future Additions
|
||||||
|
|
||||||
|
| Planned Setting | Description |
|
||||||
|
|------------------|-------------|
|
||||||
|
| `upscale-mode` | Default scaling filter for upscaling tasks |
|
||||||
|
| `hevc-mode` | Switch to H.265 (libx265) for smaller files |
|
||||||
|
| `audio-pass` | Option to skip audio re-encoding |
|
||||||
|
| `config.json` | User-editable file to override default values |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
End of File
|
||||||
137
docs/README.md
Normal file
137
docs/README.md
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
# Video Tools CLI
|
||||||
|
|
||||||
|
A simple command-line utility for video conversion and merging using FFmpeg.
|
||||||
|
Designed for personal use and sharing with friends.
|
||||||
|
Works on both Linux and Windows (via Git Bash or WSL).
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This tool provides two main commands:
|
||||||
|
|
||||||
|
| Command | Description |
|
||||||
|
|----------|-------------|
|
||||||
|
| `convert-single` | Converts a single video file to MP4 using modern compression. |
|
||||||
|
| `convert-multiple` | Combines multiple video files into one high-quality MP4. |
|
||||||
|
|
||||||
|
All output files are saved in your `~/Videos` directory by default.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
Install FFmpeg with your package manager:
|
||||||
|
```bash
|
||||||
|
sudo pacman -S ffmpeg # For Arch or Garuda
|
||||||
|
sudo apt install ffmpeg # For Debian or Ubuntu
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows
|
||||||
|
1. Install FFmpeg from https://ffmpeg.org/download.html
|
||||||
|
2. Use **Git Bash** or **WSL** to run the script.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Clone or copy the repository:
|
||||||
|
```bash
|
||||||
|
git clone https://github.com/YourName/VideoTools.git
|
||||||
|
cd VideoTools
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Make the script executable:
|
||||||
|
```bash
|
||||||
|
chmod +x video-tools.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
3. (Optional) Add it to PATH:
|
||||||
|
```bash
|
||||||
|
sudo ln -s ~/VideoTools/video-tools.sh /usr/local/bin/video-tools
|
||||||
|
```
|
||||||
|
|
||||||
|
You can now run it globally:
|
||||||
|
```bash
|
||||||
|
video-tools convert-single "input.avi" "output.mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Default Settings
|
||||||
|
|
||||||
|
| Setting | Value | Description |
|
||||||
|
|----------|--------|-------------|
|
||||||
|
| Output directory | `~/Videos` | All results are stored here |
|
||||||
|
| Video codec | `libx264` | High-quality H.264 encoding |
|
||||||
|
| Audio codec | `aac` | High-quality AAC stereo audio |
|
||||||
|
| Quality (CRF) | 18 | Visually lossless quality |
|
||||||
|
| Preset | slow | Balances speed and compression |
|
||||||
|
| Audio bitrate | 192k | High-quality stereo output |
|
||||||
|
|
||||||
|
These defaults prioritize quality while still reducing file sizes compared to older formats such as AVI or MPG.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Example Conversions
|
||||||
|
|
||||||
|
### Convert a single AVI file
|
||||||
|
|
||||||
|
```bash
|
||||||
|
video-tools convert-single \
|
||||||
|
"/run/media/stu/Linux/MyData/Videos/Example Collection/Example Movie Part1.avi" \
|
||||||
|
"Example Movie.mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
/home/stu/Videos/Example Movie.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Combine multiple AVI parts into one MP4
|
||||||
|
|
||||||
|
```bash
|
||||||
|
video-tools convert-multiple \
|
||||||
|
"/run/media/stu/Linux/MyData/Videos/Example Collection/Example Movie Part1.avi" \
|
||||||
|
"/run/media/stu/Linux/MyData/Videos/Example Collection/Example Movie Part2.avi" \
|
||||||
|
"/run/media/stu/Linux/MyData/Videos/Example Collection/Example Movie Part3.avi" \
|
||||||
|
"Example Movie Combined.mp4"
|
||||||
|
```
|
||||||
|
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
/home/stu/Videos/Example Movie Combined.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
| Issue | Cause | Solution |
|
||||||
|
|--------|--------|----------|
|
||||||
|
| `command not found` | Script not in PATH | Use full path or add symlink to `/usr/local/bin` |
|
||||||
|
| `ffmpeg not found` | FFmpeg not installed | Install FFmpeg using your package manager |
|
||||||
|
| `Permission denied` | Script not executable | Run `chmod +x video-tools.sh` |
|
||||||
|
| Merge fails | Input files have mismatched codecs | Convert each input to MP4 first, then merge |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
| Feature | Status |
|
||||||
|
|----------|--------|
|
||||||
|
| convert-single | ✅ Done |
|
||||||
|
| convert-multiple | ✅ Done |
|
||||||
|
| upscale-video | 🔜 Planned |
|
||||||
|
| batch conversion | 🔜 Planned |
|
||||||
|
| automatic format detection | 🔜 Planned |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
Free for personal use.
|
||||||
|
You can modify or share this tool with anyone.
|
||||||
71
docs/Upscale.md
Normal file
71
docs/Upscale.md
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
# Upscale Module (Planned)
|
||||||
|
|
||||||
|
The `upscale-video` command will provide loss-minimized video upscaling.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This module will allow upscaling of existing videos to higher resolutions such as:
|
||||||
|
- 720p (HD)
|
||||||
|
- 1080p (Full HD)
|
||||||
|
- 2160p (4K)
|
||||||
|
|
||||||
|
It will use FFmpeg’s native scaling filters first and optionally integrate machine learning tools later.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Planned Syntax
|
||||||
|
|
||||||
|
```bash
|
||||||
|
video-tools upscale-video <input> <output.mp4> --scale 1920x1080
|
||||||
|
```
|
||||||
|
|
||||||
|
Optional parameters:
|
||||||
|
```
|
||||||
|
--scale <WxH> Set explicit resolution
|
||||||
|
--filter <name> Choose scaling filter (lanczos, bicubic, spline36)
|
||||||
|
--hevc Encode using H.265 for smaller output
|
||||||
|
--keep-audio Copy original audio stream without re-encoding
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Default Behavior
|
||||||
|
|
||||||
|
If no resolution is provided, the tool will upscale intelligently to the nearest standard resolution above the input video.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
- Input: 960×540 → Output: 1280×720
|
||||||
|
- Input: 1280×720 → Output: 1920×1080
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Technical Notes
|
||||||
|
|
||||||
|
### FFmpeg Filter Example
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ffmpeg -i input.mp4 -vf scale=1920:1080:flags=lanczos \
|
||||||
|
-c:v libx264 -crf 18 -preset slow -c:a aac -b:a 192k output_1080p.mp4
|
||||||
|
```
|
||||||
|
|
||||||
|
- `scale=1920:1080:flags=lanczos` → high-quality resampling
|
||||||
|
- `lanczos` offers sharp, low-artifact upscale
|
||||||
|
- Later versions may support `zscale` or ML-based filters
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Planned Features
|
||||||
|
|
||||||
|
| Feature | Status |
|
||||||
|
|----------|--------|
|
||||||
|
| FFmpeg scaler (lanczos) | 🔜 Planned |
|
||||||
|
| ML-based upscaling (Real-ESRGAN / waifu2x) | 🚧 Research |
|
||||||
|
| Auto resolution detection | 🔜 Planned |
|
||||||
|
| GPU acceleration support | 🔜 Planned |
|
||||||
|
| Configurable presets | 🔜 Planned |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
End of File
|
||||||
169
video-tools.sh
Executable file
169
video-tools.sh
Executable file
|
|
@ -0,0 +1,169 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Simple FFmpeg CLI Toolset
|
||||||
|
# -------------------------
|
||||||
|
# Provides easy commands for single or multi-file video conversion.
|
||||||
|
# Works on Linux and Windows (Git Bash / WSL) as long as ffmpeg is installed.
|
||||||
|
#
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Configuration system
|
||||||
|
# ==========================================================
|
||||||
|
CONFIG_FILE="$(dirname "$0")/config/config.json"
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Default configuration
|
||||||
|
# -------------------------
|
||||||
|
OUTPUT_DIR="$HOME/Videos"
|
||||||
|
VIDEO_CODEC="libx264"
|
||||||
|
AUDIO_CODEC="aac"
|
||||||
|
CRF="18" # lower = higher quality
|
||||||
|
PRESET="slow" # slower = better compression
|
||||||
|
AUDIO_BITRATE="192k"
|
||||||
|
VERSION="0.1.0"
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Utility: Colour logging
|
||||||
|
# ==========================================================
|
||||||
|
RED="\033[31m"
|
||||||
|
YELLOW="\033[33m"
|
||||||
|
GREEN="\033[32m"
|
||||||
|
BLUE="\033[34m"
|
||||||
|
NC="\033[0m" # reset
|
||||||
|
|
||||||
|
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
||||||
|
success() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||||
|
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||||
|
error() { echo -e "${RED}[ERROR]${NC} $*" >&2; }
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Check dependencies early
|
||||||
|
# ==========================================================
|
||||||
|
if ! command -v ffmpeg >/dev/null 2>&1; then
|
||||||
|
error "ffmpeg is not installed or not in PATH."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -f "$CONFIG_FILE" ]] && command -v jq >/dev/null 2>&1; then
|
||||||
|
info "Loading configuration from: $CONFIG_FILE"
|
||||||
|
OUTPUT_DIR="$(eval echo "$(jq -r '.output_dir // empty' "$CONFIG_FILE")")" || true
|
||||||
|
VIDEO_CODEC="$(jq -r '.video_codec // empty' "$CONFIG_FILE" 2>/dev/null || echo "$VIDEO_CODEC")"
|
||||||
|
AUDIO_CODEC="$(jq -r '.audio_codec // empty' "$CONFIG_FILE" 2>/dev/null || echo "$AUDIO_CODEC")"
|
||||||
|
CRF="$(jq -r '.crf // empty' "$CONFIG_FILE" 2>/dev/null || echo "$CRF")"
|
||||||
|
PRESET="$(jq -r '.preset // empty' "$CONFIG_FILE" 2>/dev/null || echo "$PRESET")"
|
||||||
|
AUDIO_BITRATE="$(jq -r '.audio_bitrate // empty' "$CONFIG_FILE" 2>/dev/null || echo "$AUDIO_BITRATE")"
|
||||||
|
VERSION="$(jq -r '.version // empty' "$CONFIG_FILE" 2>/dev/null || echo "$VERSION")"
|
||||||
|
elif [[ ! -f "$CONFIG_FILE" ]]; then
|
||||||
|
warn "No config.json found — using internal defaults."
|
||||||
|
else
|
||||||
|
warn "jq not found — skipping config.json parsing."
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$OUTPUT_DIR" || { error "Failed to create output directory $OUTPUT_DIR"; exit 1; }
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Header output
|
||||||
|
# ==========================================================
|
||||||
|
print_header() {
|
||||||
|
echo "----------------------------------------------"
|
||||||
|
echo "Video Tools v$VERSION"
|
||||||
|
echo "Output directory: $OUTPUT_DIR"
|
||||||
|
echo "Video codec : $VIDEO_CODEC"
|
||||||
|
echo "Audio codec : $AUDIO_CODEC"
|
||||||
|
echo "CRF : $CRF"
|
||||||
|
echo "Preset : $PRESET"
|
||||||
|
echo "Audio rate : $AUDIO_BITRATE"
|
||||||
|
echo "----------------------------------------------"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Convert one file
|
||||||
|
# ==========================================================
|
||||||
|
convert_single() {
|
||||||
|
local input="$1"
|
||||||
|
local output_name="$2"
|
||||||
|
local output_path="$OUTPUT_DIR/$output_name"
|
||||||
|
|
||||||
|
print_header
|
||||||
|
info "Converting single video..."
|
||||||
|
info "Input : $input"
|
||||||
|
info "Output: $output_path"
|
||||||
|
|
||||||
|
if [[ ! -f "$input" ]]; then
|
||||||
|
error "Input file not found: $input"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
ffmpeg -hide_banner -loglevel info -fflags +genpts \
|
||||||
|
-i "$input" \
|
||||||
|
-c:v "$VIDEO_CODEC" -crf "$CRF" -preset "$PRESET" \
|
||||||
|
-c:a "$AUDIO_CODEC" -b:a "$AUDIO_BITRATE" -movflags +faststart \
|
||||||
|
"$output_path" || { error "Conversion failed."; exit 1; }
|
||||||
|
|
||||||
|
success "Conversion complete: $output_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Combine multiple files
|
||||||
|
# ==========================================================
|
||||||
|
convert_multiple() {
|
||||||
|
local args=("$@")
|
||||||
|
local output_name="${args[-1]}"
|
||||||
|
unset 'args[-1]'
|
||||||
|
local list_file
|
||||||
|
list_file=$(mktemp)
|
||||||
|
local output_path="$OUTPUT_DIR/$output_name"
|
||||||
|
|
||||||
|
print_header
|
||||||
|
info "Combining multiple videos..."
|
||||||
|
for input in "${args[@]}"; do
|
||||||
|
if [[ ! -f "$input" ]]; then
|
||||||
|
error "Missing input file: $input"
|
||||||
|
rm -f "$list_file"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
echo "file '$input'" >> "$list_file"
|
||||||
|
info " + Added: $input"
|
||||||
|
done
|
||||||
|
echo "----------------------------------------------"
|
||||||
|
|
||||||
|
ffmpeg -hide_banner -loglevel info -f concat -safe 0 -i "$list_file" \
|
||||||
|
-c:v "$VIDEO_CODEC" -crf "$CRF" -preset "$PRESET" \
|
||||||
|
-c:a "$AUDIO_CODEC" -b:a "$AUDIO_BITRATE" -movflags +faststart \
|
||||||
|
"$output_path" || { error "Merge failed."; rm -f "$list_file"; exit 1; }
|
||||||
|
|
||||||
|
rm -f "$list_file"
|
||||||
|
success "Combined video created: $output_path"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ==========================================================
|
||||||
|
# Dispatcher
|
||||||
|
# ==========================================================
|
||||||
|
case "${1:-}" in
|
||||||
|
convert-single)
|
||||||
|
shift
|
||||||
|
if [[ $# -ne 2 ]]; then
|
||||||
|
error "Usage: $0 convert-single <input> <output.mp4>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
convert_single "$@"
|
||||||
|
;;
|
||||||
|
convert-multiple)
|
||||||
|
shift
|
||||||
|
if [[ $# -lt 3 ]]; then
|
||||||
|
error "Usage: $0 convert-multiple <input1> <input2> ... <output.mp4>"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
convert_multiple "$@"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Video Tools v$VERSION"
|
||||||
|
echo "Usage:"
|
||||||
|
echo " $0 convert-single <input> <output.mp4>"
|
||||||
|
echo " $0 convert-multiple <input1> <input2> ... <output.mp4>"
|
||||||
|
echo ""
|
||||||
|
echo "All outputs will be saved in: $OUTPUT_DIR"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Loading…
Reference in New Issue
Block a user