<!--
.. title: ffmpeg tips
.. slug: ffmpeg-tips
.. date: 2021-01-08 13:42:18 UTC+03:00
.. updated: 2024-11-24 23:19:42 UTC+03:00
.. tags: ffmpeg, video
.. category: 
.. link: 
.. description: 
.. type: text
-->

# FFMPEG tips

## выдрать звук и сохранить в mp3 с высшим качеством

```bash
ffmpeg -i inputfile -q:a 0 outputfile.mp3
```

## Масштабирование

Без сохранения aspect ratio

```bash
ffmpeg -i complex.mov -crf 20 -vf scale=640:360 complex-small.mp4
```

С сохранением aspect ratio

```bash
ffmpeg -i input.jpg -vf scale=320:-1 output_320.png
```

Some codecs require the size of width and height to be кратны *n*. 
Для этого в качестве высоты надо установить *-n*.

```bash
ffmpeg -i input.jpg -vf scale=320:-2 output_320.png
```

[Подробней про хитрое масштабирование](https://trac.ffmpeg.org/wiki/Scaling).


## concat files

```bash
ffmpeg -f concat -i mylist.txt -c copy complex.mov
```

mylist.txt:

```ini
file filename1
#comment
file filename2
....
```

## speedup without sound

```bash
ffmpeg -i o1-20.mp4 -an -filter:v "setpts=0.25*PTS" o-fast.mp4

ffmpeg -i complex-small.mp4  -movflags +faststart -pix_fmt yuv420p -crf 20 -an -filter:v "setpts=0.2*PTS" complex-fast.mp4
```

## speedup with sound

```bash
ffmpeg -i complex-small.mp4  -movflags +faststart -pix_fmt yuv420p -crf 20  -filter_complex "[0:v]setpts=0.125*PTS[v];[0:a]atempo=2.0,atempo=2.0,atempo=2.0[a]" -map "[v]" -map "[a]" compex-fast-big.mp4
```

## crop

Use the crop filter:

```bash
ffmpeg -i in.mp4 -filter:v "crop=out_w:out_h:x:y" out.mp4
```

To crop a 80x60 section, starting from position (200, 100):

```bash
ffmpeg -i in.mp4 -filter:v "crop=80:60:200:100" -c:a copy out.mp4
```

The audio is stream copied in this example, so re-encoding is avoided.

To crop the bottom right quarter:

```bash
ffmpeg -i in.mp4 -filter:v "crop=in_w/2:in_h/2:in_w/2:in_h/2" -c:a copy out.mp4
```

This is the same as:

```bash
ffmpeg -i in.mp4 -filter:v "crop=320/2:240/2:320/2:240/2" -c:a copy out.mp4
```

Which is the same as:

```bash
ffmpeg -i in.mp4 -filter:v "crop=240:120:240:120" -c:a copy out.mp4
```

You can refer to the input image size with in_w and in_h as shown in this first example. The output width and height can also be used with out_w and out_h.

Crop 20 pixels from the top, and 20 from the bottom:

```bash
ffmpeg -i in.mp4 -filter:v "crop=in_w:in_h-40" -c:a copy out.mp4
```

The filter will automatically center the crop if x and y are omitted such as in this example.

Preview:

```bash
ffplay -i input -vf "crop=in_w:in_h-40"
```

## Яркость/контраст/гамма/насыщенность

```bash
ffmpeg -i in.mp4 -vf eq=gamma=0.5:saturation=0.3 -crf 5 -y out.mp4
```

## crop и сохранение в animated gif

```bash
ffmpeg -i in.mp4 -filter:v "crop=300:800:200:-400" -pix_fmt rgb24 -r 10 -y tower1.gif
```

## Сохранение в webm для стикеров telegram

Надо constant quality, не constrained, поэтому `-b:v 0`.

```bash
ffmpeg -i input.mp4 -c:v libvpx-vp9 -crf 30 -b:v 0 output.webm
```

Ещё вариант с масштабом жестким без сохранения aspect ratio:


```bash
ffmpeg -i input_file.mp4 -framerate 30 -c:v libvpx-vp9 -an -vf scale=512:512 -pix_fmt yuva420p output_sticker.webm
```

## cut

```bash
ffmpeg -i input.wmv -ss 00:00:30.0 -c copy -t 00:00:10.0 output.wmv
ffmpeg -i input.wmv -ss 30 -c copy -t 10 output.wmv

ffmpeg -i input.mp4 -ss 30 -to 40 output.mp4
```

You can also put -ss before -i !!!

The -t option doesn't work for short videos, but it does for longer videos.
For short videos it seems that -frames:v is better. This is what worked for me.

```bash
ffmpeg -ss 4 -i input.mp4 -frames:v 200 -vcodec copy -acodec copy output.mp4
```

For me -t option didn't work, but -vframes worked.
I prefer using #frames, since I would rather cut at
I-Frames and I found out GOP for video using ffprobe.

The command line that worked for me is:

```bash
ffmpeg -ss 60s -i input.wmv -vframes 1800 -acodec copy -vcodec copy output.wmv
```

By the way, putting -ss in the front of -i makes a big difference in execution time.

**Inaccurate seek**:

```bash
ffmpeg -noaccurate_seek -ss 120 -i input.mp4 -y -vcodec copy -acodec copy -to 8 -avoid_negative_ts make_zero output.mp4
```


# For browser

```bash
ffmpeg -i input_file -q:v 4 -q:a 7 -movflags +faststart -pix_fmt yuv420p -acodec libvorbis -vcodec libtheora output.ogv
```

After that create html file:

```html
<html><body>

<h2>TITLE</h2>

<video width="1024" height="576" controls="controls">
<source src="output.ogv" type='video/ogg; codecs="theora, vorbis"'>
  Тег video не поддерживается вашим браузером.
</video>
<br><br>
</body></html>
```
    
# Генерация сигналов

```bash
ffmpeg -f lavfi -i "sine=frequency=1000:sample_rate=48000:duration=5" -af "volume=-6dB" -c:a pcm_s16le test.wav
```
