Skip to content

Commit 9817768

Browse files
Copilotpelikhan
andauthored
Import ffmpeg shared workflow from github/gh-aw (#215)
* Initial plan * Import ffmpeg shared workflow from github/gh-aw Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
1 parent 0a49b25 commit 9817768

1 file changed

Lines changed: 161 additions & 0 deletions

File tree

workflows/shared/ffmpeg.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
---
2+
# FFmpeg Setup
3+
# Shared configuration for installing and using ffmpeg in workflows
4+
#
5+
# Usage:
6+
# imports:
7+
# - shared/ffmpeg.md
8+
#
9+
# This import provides:
10+
# - Automatic ffmpeg installation via setup steps
11+
# - Instructions on how to use ffmpeg
12+
# - Best practices for video/audio processing
13+
#
14+
# Note: FFmpeg operations can be time-intensive. Ensure your workflow has
15+
# adequate timeout-minutes (recommended: 15+ minutes for video processing).
16+
# Individual bash commands using ffmpeg have a 5-minute timeout by default.
17+
18+
tools:
19+
bash:
20+
- "ffmpeg *"
21+
- "ffprobe *"
22+
23+
steps:
24+
- name: Setup FFmpeg
25+
id: setup-ffmpeg
26+
run: |
27+
sudo apt-get update && sudo apt-get install -y ffmpeg
28+
version=$(ffmpeg -version | head -n1)
29+
echo "version=$version" >> "$GITHUB_OUTPUT"
30+
mkdir -p /tmp/gh-aw/ffmpeg
31+
---
32+
33+
# FFmpeg Usage Guide
34+
35+
FFmpeg and ffprobe have been installed and are available in your PATH. A temporary folder `/tmp/gh-aw/ffmpeg` is available for caching intermediate results.
36+
37+
**Note**: FFmpeg operations can take several minutes for large video files. Bash commands have a 5-minute timeout. For longer operations, break them into smaller steps or increase workflow timeout-minutes.
38+
39+
## Common FFmpeg Operations
40+
41+
### Extract Audio from Video
42+
43+
```bash
44+
# Extract audio as MP3 with high quality
45+
ffmpeg -i input.mp4 -vn -acodec libmp3lame -ab 192k output.mp3
46+
47+
# Extract audio for transcription (optimized for speech-to-text)
48+
# Uses Opus codec with mono channel and low bitrate for optimal transcription
49+
ffmpeg -i input.mp4 -vn -acodec libopus -ac 1 -ab 12k -application voip -map_metadata -1 -f ogg output.ogg
50+
```
51+
52+
**Key flags:**
53+
- `-vn`: No video output
54+
- `-acodec`: Audio codec (libmp3lame, pcm_s16le, aac, libopus)
55+
- `-ab`: Audio bitrate (128k, 192k, 256k, 320k, or 12k for transcription)
56+
- `-ac`: Audio channels (1 for mono, 2 for stereo)
57+
- `-application voip`: Optimize Opus for voice (for transcription)
58+
- `-map_metadata -1`: Remove metadata
59+
60+
**For transcription:**
61+
- Use `libopus` codec with OGG format
62+
- Mono channel (`-ac 1`) is sufficient for speech
63+
- Low bitrate (12k) keeps file size small
64+
- `-application voip` optimizes for voice
65+
66+
### Extract Video Frames
67+
68+
```bash
69+
# Extract all keyframes (I-frames)
70+
ffmpeg -i input.mp4 -vf "select='eq(pict_type,I)'" -fps_mode vfr -frame_pts 1 keyframe_%06d.jpg
71+
72+
# Extract frames at specific interval (e.g., 1 frame per second)
73+
ffmpeg -i input.mp4 -vf "fps=1" frame_%06d.jpg
74+
75+
# Extract single frame at specific timestamp
76+
ffmpeg -i input.mp4 -ss 00:00:05 -frames:v 1 frame.jpg
77+
```
78+
79+
**Key flags:**
80+
- `-vf`: Video filter
81+
- `-fps_mode vfr`: Variable frame rate (for keyframes)
82+
- `-frame_pts 1`: Include frame presentation timestamp
83+
- `-ss`: Seek to timestamp (HH:MM:SS or seconds)
84+
- `-frames:v`: Number of video frames to extract
85+
86+
### Scene Detection
87+
88+
```bash
89+
# Detect scene changes with threshold (0.0-1.0, default 0.4)
90+
# Lower threshold = more sensitive to changes
91+
ffmpeg -i input.mp4 -vf "select='gt(scene,0.3)',showinfo" -fps_mode passthrough -frame_pts 1 scene_%06d.jpg
92+
93+
# Common threshold values:
94+
# 0.1-0.2: Very sensitive (minor changes trigger detection)
95+
# 0.3-0.4: Moderate sensitivity (good for most videos)
96+
# 0.5-0.6: Less sensitive (only major scene changes)
97+
```
98+
99+
**Scene detection tips:**
100+
- Start with threshold 0.4 and adjust based on results
101+
- Use `showinfo` filter to see timestamps in logs
102+
- Lower threshold detects more scenes but may include false positives
103+
- Higher threshold misses gradual transitions
104+
105+
### Resize and Convert
106+
107+
```bash
108+
# Resize video to specific dimensions (maintains aspect ratio)
109+
ffmpeg -i input.mp4 -vf "scale=1280:720" output.mp4
110+
111+
# Resize with padding to maintain aspect ratio
112+
ffmpeg -i input.mp4 -vf "scale=1280:720:force_original_aspect_ratio=decrease,pad=1280:720:(ow-iw)/2:(oh-ih)/2" output.mp4
113+
114+
# Convert to different format with quality control
115+
ffmpeg -i input.mp4 -c:v libx264 -crf 23 -c:a aac -b:a 128k output.mp4
116+
```
117+
118+
**Quality flags:**
119+
- `-crf`: Constant Rate Factor (0-51, lower=better quality, 23 is default)
120+
- `18`: Visually lossless
121+
- `23`: High quality (default)
122+
- `28`: Medium quality
123+
124+
### Get Video Information
125+
126+
```bash
127+
# Get detailed video information
128+
ffprobe -v quiet -print_format json -show_format -show_streams input.mp4
129+
130+
# Get video duration
131+
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 input.mp4
132+
133+
# Get video dimensions
134+
ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 input.mp4
135+
```
136+
137+
### Compute Stable Hash for Video Encoding Task
138+
139+
Compute a SHA-256 hash that uniquely identifies an ffmpeg command and all input files it references. This is useful for caching and detecting when re-processing is needed.
140+
141+
**Steps:**
142+
1. Capture the full ffmpeg command line (exact text with all arguments)
143+
2. Concatenate the command string with the binary contents of each input file in the same order
144+
3. Pipe the combined data into `sha256sum` (or `shasum -a 256` on macOS)
145+
146+
**Example Bash:**
147+
148+
```bash
149+
cmd='ffmpeg -i input1.mp4 -i input2.wav -filter_complex "..." -c:v libx264 output.mp4'
150+
(
151+
echo "$cmd"
152+
cat input1.mp4 input2.wav
153+
) | sha256sum | awk '{print $1}'
154+
```
155+
156+
This hash changes only when:
157+
- The ffmpeg command arguments change
158+
- Any input file content changes
159+
160+
Use this hash as a cache key in `/tmp/gh-aw/ffmpeg/` to avoid reprocessing identical operations.
161+

0 commit comments

Comments
 (0)