diff --git a/README-ru.md b/README-ru.md
new file mode 100644
index 0000000..d59a654
--- /dev/null
+++ b/README-ru.md
@@ -0,0 +1,979 @@
+[π¨π³](/README-cn.md "Simplified Chinese")
+[π°π·](/README-ko.md "Korean")
+[πͺπΈ](/README-es.md "Spanish")
+[π»π³](/README-vn.md "Vietnamese")
+[π§π·](/README-pt.md "Portuguese")
+
+[](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)
+
+Π― ΠΈΡΠΊΠ°Π» ΡΡΡΠΎΡΠΈΠ°Π»/ΠΊΠ½ΠΈΠ³Ρ, ΠΊΠΎΡΠΎΡΠ°Ρ Π½Π°ΡΡΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ [FFmpeg](https://www.ffmpeg.org/) Ρ ΠΏΠΎΠΌΠΎΡΡΡ libav, ΠΈ Π½Π°ΡΠΊΠ½ΡΠ»ΡΡ Π½Π° ΡΡΠΊΠΎΠ²ΠΎΠ΄ΡΡΠ²ΠΎ ["How to write a video player in less than 1k lines"](http://dranger.com/ffmpeg/).
+Π ΡΠΎΠΆΠ°Π»Π΅Π½ΠΈΡ, ΠΎΠ½ΠΎ ΡΡΡΠ°ΡΠ΅Π»ΠΎ, ΠΏΠΎΡΡΠΎΠΌΡ Ρ ΡΠ΅ΡΠΈΠ» Π½Π°ΠΏΠΈΡΠ°ΡΡ ΡΡΠΎΡ Π³Π°ΠΉΠ΄.
+
+ΠΠΎΠ»ΡΡΠ°Ρ ΡΠ°ΡΡΡ ΠΊΠΎΠ΄Π° Π·Π΄Π΅ΡΡ Π½Π° C, **Π½ΠΎ Π½Π΅ ΠΏΡΠ³Π°ΠΉΡΠ΅ΡΡ**: ΠΏΠΎΠ½ΡΡΡ ΠΈ ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡΠΈ ΠΈΠ΄Π΅ΠΈ Π½Π° Π»ΡΠ±ΠΈΠΌΡΠΉ ΡΠ·ΡΠΊ Π½Π΅ΡΠ»ΠΎΠΆΠ½ΠΎ.
+ΠΠ»Ρ FFmpeg/libav Π΅ΡΡΡ Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΈ ΠΊΠΎ ΠΌΠ½ΠΎΠ³ΠΈΠΌ ΡΠ·ΡΠΊΠ°ΠΌ β Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, [python](https://pyav.org/), [go](https://github.com/imkira/go-libav); Π΄Π°ΠΆΠ΅ Π΅ΡΠ»ΠΈ Π΄Π»Ρ Π²Π°ΡΠ΅Π³ΠΎ ΡΠ·ΡΠΊΠ° Π±ΠΈΠ½Π΄ΠΈΠ½Π³ΠΎΠ² Π½Π΅Ρ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡΡΡ ΡΠ΅ΡΠ΅Π· `ffi` (Π²ΠΎΡ ΠΏΡΠΈΠΌΠ΅Ρ Ρ [Lua](https://github.com/daurnimator/ffmpeg-lua-ffi/blob/master/init.lua)).
+
+ΠΡ Π½Π°ΡΠ½ΡΠΌ Ρ ΠΊΡΠ°ΡΠΊΠΎΠ³ΠΎ Π»ΠΈΠΊΠ±Π΅Π·Π°: ΡΡΠΎ ΡΠ°ΠΊΠΎΠ΅ Π²ΠΈΠ΄Π΅ΠΎ, Π°ΡΠ΄ΠΈΠΎ, ΠΊΠΎΠ΄Π΅ΠΊ ΠΈ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ, Π·Π°ΡΠ΅ΠΌ Π²ΠΊΡΠ°ΡΡΠ΅ ΠΏΡΠΎΠΉΠ΄Π΅ΠΌΡΡ ΠΏΠΎ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠ΅ `FFmpeg`, ΠΈ, Π½Π°ΠΊΠΎΠ½Π΅Ρ, ΠΏΠ΅ΡΠ΅ΠΉΠ΄ΡΠΌ ΠΊ ΠΊΠΎΠ΄Ρ. ΠΡΠ»ΠΈ Π²Π°ΠΌ ΡΡΠΎ Π½Π΅ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΠΎ, ΡΠΌΠ΅Π»ΠΎ ΠΏΡΠΎΠ»ΠΈΡΡΡΠ²Π°ΠΉΡΠ΅ ΠΏΡΡΠΌΠΎ ΠΊ ΡΠ°Π·Π΄Π΅Π»Ρ [Learning FFmpeg libav the hard way](#learn-ffmpeg-libav-the-hard-way) (Π΄Π°, ΡΡΡΠ»ΠΊΠ° Ρ ΠΊΠ°ΡΡΠΈΠ½ΠΊΠΎΠΉ ΠΏΠΎΡΡΠ΅Π΄ΠΈ ΡΡΠ°Π·Ρ β ΡΡΠΎ ΠΎΡΡΡΠ»ΠΊΠ° ΠΊ ΠΌΠ΅ΠΌΠ°ΠΌ, Π½Π΅ Π±Π°Π³).
+
+ΠΡΠΎ-ΡΠΎ Π³ΠΎΠ²ΠΎΡΠΈΡ, ΡΡΠΎ Π²ΠΈΠ΄Π΅ΠΎΡΡΡΠΈΠΌΠΈΠ½Π³ Π² ΠΠ½ΡΠ΅ΡΠ½Π΅ΡΠ΅ β Π±ΡΠ΄ΡΡΠ΅Π΅ ΡΡΠ°Π΄ΠΈΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ Π’Π. Π Π»ΡΠ±ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, FFmpeg β Π²Π΅ΡΡ, ΠΊΠΎΡΠΎΡΡΡ ΡΡΠΎΠΈΡ ΠΈΠ·ΡΡΠΈΡΡ.
+
+**ΠΠ³Π»Π°Π²Π»Π΅Π½ΠΈΠ΅**
+
+* [ΠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅](#intro)
+
+ * [Π²ΠΈΠ΄Π΅ΠΎ β ΡΠΎ, ΡΡΠΎ ΡΡ Π²ΠΈΠ΄ΠΈΡΡ!](#video---what-you-see)
+ * [Π°ΡΠ΄ΠΈΠΎ β ΡΠΎ, ΡΡΠΎ ΡΡ ΡΠ»ΡΡΠΈΡΡ!](#audio---what-you-listen)
+ * [ΠΊΠΎΠ΄Π΅ΠΊ β ΡΠΆΠ°ΡΠΈΠ΅ Π΄Π°Π½Π½ΡΡ
](#codec---shrinking-data)
+ * [ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ β Π΄ΠΎΠΌ Π΄Π»Ρ Π°ΡΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ](#container---a-comfy-place-for-audio-and-video)
+* [FFmpeg β ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°Ρ ΡΡΡΠΎΠΊΠ°](#ffmpeg---command-line)
+
+ * [FFmpeg CLI 101](#ffmpeg-command-line-tool-101)
+* [Π’ΠΈΠΏΠΎΠ²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Ρ Π²ΠΈΠ΄Π΅ΠΎ](#common-video-operations)
+
+ * [Transcoding (ΠΏΠ΅ΡΠ΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅)](#transcoding)
+ * [Transmuxing (ΠΏΠ΅ΡΠ΅ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅)](#transmuxing)
+ * [Transrating (ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π±ΠΈΡΡΠ΅ΠΉΡΠ°)](#transrating)
+ * [Transsizing (ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ)](#transsizing)
+ * [ΠΠΎΠ½ΡΡ: Π°Π΄Π°ΠΏΡΠΈΠ²Π½ΡΠΉ ΡΡΡΠΈΠΌΠΈΠ½Π³](#bonus-round-adaptive-streaming)
+ * [ΠΠ°Π»ΡΡΠ΅ β Π±ΠΎΠ»ΡΡΠ΅](#going-beyond)
+* [Learning FFmpeg libav the hard way](#learn-ffmpeg-libav-the-hard-way)
+
+ * [ΠΠ»Π°Π²Π° 0 β ΠΏΠ΅ΡΠ°Π»ΡΠ½ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠΉ Β«hello worldΒ»](#chapter-0---the-infamous-hello-world)
+
+ * [ΠΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° FFmpeg libav](#ffmpeg-libav-architecture)
+ * [ΠΠ»Π°Π²Π° 1 β ΡΠ°ΠΉΠΌΠΈΠ½Π³ΠΈ/ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ](#chapter-1---syncing-audio-and-video)
+ * [ΠΠ»Π°Π²Π° 2 β remuxing](#chapter-2---remuxing)
+ * [ΠΠ»Π°Π²Π° 3 β ΡΡΠ°Π½ΡΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅](#chapter-3---transcoding)
+
+# ΠΠ²Π΅Π΄Π΅Π½ΠΈΠ΅
+
+## Π²ΠΈΠ΄Π΅ΠΎ β ΡΠΎ, ΡΡΠΎ ΡΡ Π²ΠΈΠ΄ΠΈΡΡ
+
+ΠΡΠ»ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ ΡΠ΅ΡΠΈΡ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Ρ Π·Π°Π΄Π°Π½Π½ΠΎΠΉ ΡΠ°ΡΡΠΎΡΠΎΠΉ (ΡΠΊΠ°ΠΆΠ΅ΠΌ, [24 ΠΊΠ°Π΄ΡΠ° Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ](https://www.filmindependent.org/blog/hacking-film-24-frames-per-second/)), Π²ΠΎΠ·Π½ΠΈΠΊΠ½Π΅Ρ [ΠΈΠ»Π»ΡΠ·ΠΈΡ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΡ](https://en.wikipedia.org/wiki/Persistence_of_vision).
+Π ΠΈΡΠΎΠ³Π΅ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΡΡ ΠΈΠ΄Π΅Ρ, ΡΡΠΎΡΡΡΡΡ Π·Π° Π²ΠΈΠ΄Π΅ΠΎ: **ΡΡΠ΄ ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ/ΠΊΠ°Π΄ΡΠΎΠ², ΠΈΠ΄ΡΡΠΈΡ
Ρ Π·Π°Π΄Π°Π½Π½ΠΎΠΉ ΡΠ°ΡΡΠΎΡΠΎΠΉ**.
+
+
+
+ZeitgenΓΆssische Illustration (1886)
+
+## Π°ΡΠ΄ΠΈΠΎ β ΡΠΎ, ΡΡΠΎ ΡΡ ΡΠ»ΡΡΠΈΡΡ!
+
+ΠΠΎΠ»ΡΠ°Π»ΠΈΠ²ΠΎΠ΅ Π²ΠΈΠ΄Π΅ΠΎ ΠΌΠΎΠΆΠ΅Ρ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ, Π½ΠΎ Π±Π΅Π· Π·Π²ΡΠΊΠ° ΡΡΠΎ Π±ΡΠ΄Π΅Ρ ΡΠΎΠ²ΡΠ΅ΠΌ Π½Π΅ ΡΠΎ.
+
+ΠΠ²ΡΠΊ β ΡΡΠΎ Π²ΠΈΠ±ΡΠ°ΡΠΈΡ, ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΡΡΠ°ΡΡΡ ΠΊΠ°ΠΊ Π²ΠΎΠ»Π½Π° Π΄Π°Π²Π»Π΅Π½ΠΈΡ ΡΠ΅ΡΠ΅Π· Π²ΠΎΠ·Π΄ΡΡ
ΠΈΠ»ΠΈ Π»ΡΠ±ΡΡ Π΄ΡΡΠ³ΡΡ ΡΡΠ΅Π΄Ρ β Π³Π°Π·, ΠΆΠΈΠ΄ΠΊΠΎΡΡΡ, ΡΠ²ΡΡΠ΄ΠΎΠ΅ ΡΠ΅Π»ΠΎ.
+
+> Π ΡΠΈΡΡΠΎΠ²ΠΎΠΉ Π°ΡΠ΄ΠΈΠΎΡΠΈΡΡΠ΅ΠΌΠ΅ ΠΌΠΈΠΊΡΠΎΡΠΎΠ½ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΡΠ΅Ρ Π·Π²ΡΠΊ Π² Π°Π½Π°Π»ΠΎΠ³ΠΎΠ²ΡΠΉ ΡΠ»Π΅ΠΊΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΠΈΠ³Π½Π°Π», Π·Π°ΡΠ΅ΠΌ ΠΠ¦Π β ΠΎΠ±ΡΡΠ½ΠΎ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ [PCM](https://en.wikipedia.org/wiki/Pulse-code_modulation) β ΠΏΡΠ΅Π²ΡΠ°ΡΠ°Π΅Ρ Π°Π½Π°Π»ΠΎΠ³ Π² ΡΠΈΡΡΠΎΠ²ΠΎΠΉ.
+
+
+
+> [ΠΡΡΠΎΡΠ½ΠΈΠΊ](https://commons.wikimedia.org/wiki/File:CPT-Sound-ADC-DAC.svg)
+
+## ΠΊΠΎΠ΄Π΅ΠΊ β ΡΠΆΠ°ΡΠΈΠ΅ Π΄Π°Π½Π½ΡΡ
+
+> CODEC β ΡΡΠΎ ΡΠ»Π΅ΠΊΡΡΠΎΠ½Π½Π°Ρ ΡΡ
Π΅ΠΌΠ° ΠΈΠ»ΠΈ ΠΠ, ΠΊΠΎΡΠΎΡΠΎΠ΅ **ΡΠΆΠΈΠΌΠ°Π΅Ρ/ΡΠ°ΡΠΏΠ°ΠΊΠΎΠ²ΡΠ²Π°Π΅Ρ ΡΠΈΡΡΠΎΠ²ΠΎΠ΅ Π°ΡΠ΄ΠΈΠΎ/Π²ΠΈΠ΄Π΅ΠΎ.** ΠΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΈΡ ΡΡΡΡΠ΅ (Π½Π΅ΡΠΆΠ°ΡΡΠ΅) Π΄Π°Π½Π½ΡΠ΅ Π² ΡΠΆΠ°ΡΡΠΉ ΡΠΎΡΠΌΠ°Ρ ΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ.
+> [https://en.wikipedia.org/wiki/Video_codec](https://en.wikipedia.org/wiki/Video_codec)
+
+ΠΡΠ»ΠΈ ΠΆΠ΅ ΠΏΡΠΎΡΡΠΎ ΡΠ»ΠΎΠΆΠΈΡΡ ΠΌΠΈΠ»Π»ΠΈΠΎΠ½Ρ ΠΊΠ°ΡΡΠΈΠ½ΠΎΠΊ Π² ΠΎΠ΄ΠΈΠ½ ΡΠ°ΠΉΠ» ΠΈ Π½Π°Π·Π²Π°ΡΡ ΡΡΠΎ ΡΠΈΠ»ΡΠΌΠΎΠΌ, ΡΠ°Π·ΠΌΠ΅Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡΡ ΡΡΠ΄ΠΎΠ²ΠΈΡΠ½ΡΠΌ. ΠΠΎΡΡΠΈΡΠ°Π΅ΠΌ:
+
+ΠΡΡΡΡ Π΅ΡΡΡ Π²ΠΈΠ΄Π΅ΠΎ Ρ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ΠΌ `1080 x 1920` (Π²ΡΡΠΎΡΠ° Γ ΡΠΈΡΠΈΠ½Π°), Π½Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΈΠΊΡΠ΅Π»Ρ ΡΡΠ°ΡΠΈΠΌ `3 Π±Π°ΠΉΡΠ°` (ΡΠ²Π΅Ρ Π² [24 Π±ΠΈΡΠ°Ρ
](https://en.wikipedia.org/wiki/Color_depth#True_color_.2824-bit.29), Ρ.Π΅. 16 777 216 ΡΠ²Π΅ΡΠΎΠ²), ΡΠ°ΡΡΠΎΡΠ° `24 ΠΊΠ°Π΄ΡΠ°/Ρ`, Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ `30 ΠΌΠΈΠ½ΡΡ`.
+
+```c
+toppf = 1080 * 1920 // total_of_pixels_per_frame β Π²ΡΠ΅Π³ΠΎ ΠΏΠΈΠΊΡΠ΅Π»Π΅ΠΉ Π½Π° ΠΊΠ°Π΄Ρ
+cpp = 3 // cost_per_pixel β Π±Π°ΠΉΡ Π½Π° ΠΏΠΈΠΊΡΠ΅Π»Ρ
+tis = 30 * 60 // time_in_seconds β Π²ΡΠ΅ΠΌΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Π°Ρ
+fps = 24 // frames_per_second β ΠΊΠ°Π΄ΡΡ Π² ΡΠ΅ΠΊΡΠ½Π΄Ρ
+
+required_storage = tis * fps * toppf * cpp
+```
+
+Π’Π°ΠΊΠΎΠ΅ Π²ΠΈΠ΄Π΅ΠΎ Π·Π°ΠΉΠΌΡΡ ΠΏΡΠΈΠΌΠ΅ΡΠ½ΠΎ `250.28GB` ΠΈΠ»ΠΈ ΠΏΠΎΡΡΠ΅Π±ΡΠ΅Ρ `1.19 Gbps` ΠΏΡΠΎΠΏΡΡΠΊΠ½ΠΎΠΉ ΡΠΏΠΎΡΠΎΠ±Π½ΠΎΡΡΠΈ! ΠΠΎΡΡΠΎΠΌΡ Π½Π°ΠΌ ΠΈ Π½ΡΠΆΠ΅Π½ [CODEC](https://github.com/leandromoreira/digital_video_introduction#how-does-a-video-codec-work).
+
+## ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ β Π΄ΠΎΠΌ Π΄Π»Ρ Π°ΡΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ
+
+> ΠΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ (wrapper format) β ΡΡΠΎ ΠΌΠ΅ΡΠ°ΡΠ°ΠΉΠ»-ΡΠΎΡΠΌΠ°Ρ, ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ ΠΎΠΏΠΈΡΡΠ²Π°Π΅Ρ, ΠΊΠ°ΠΊ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠΎΠΌΠΏΡΡΡΠ΅ΡΠ½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅ ΡΠΎΡΡΡΠ΅ΡΡΠ²ΡΡΡ ΡΠ°Π·Π½ΡΠ΅ ΡΠ»Π΅ΠΌΠ΅Π½ΡΡ Π΄Π°Π½Π½ΡΡ
ΠΈ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΡ
.
+> [https://en.wikipedia.org/wiki/Digital_container_format](https://en.wikipedia.org/wiki/Digital_container_format)
+
+**ΠΠ΄ΠΈΠ½ ΡΠ°ΠΉΠ», ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ Π²ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΈ** (ΠΎΠ±ΡΡΠ½ΠΎ Π°ΡΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ) ΠΈ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°ΡΡΠΈΠΉ **ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ ΠΈ ΠΎΠ±ΡΠΈΠ΅ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΠ΅** β Π½Π°Π·Π²Π°Π½ΠΈΠ΅, ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ ΠΈ Ρ.ΠΏ.
+
+Π§Π°ΡΡΠΎ ΡΠΎΡΠΌΠ°Ρ ΡΠ°ΠΉΠ»Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ½ΡΡΡ ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ: Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, `video.webm` β ΡΡΠΎ, ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, Π²ΠΈΠ΄Π΅ΠΎ Π² ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅ [`webm`](https://www.webmproject.org/).
+
+
+
+# FFmpeg β ΠΊΠΎΠΌΠ°Π½Π΄Π½Π°Ρ ΡΡΡΠΎΠΊΠ°
+
+> ΠΠΎΠ»Π½ΠΎΡΠ΅Π½Π½ΠΎΠ΅ ΠΊΡΠΎΡΡΠΏΠ»Π°ΡΡΠΎΡΠΌΠ΅Π½Π½ΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Π·Π°ΠΏΠΈΡΠΈ, ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΠΈ ΠΈ ΡΡΡΠΈΠΌΠΈΠ½Π³Π° Π°ΡΠ΄ΠΈΠΎ ΠΈ Π²ΠΈΠ΄Π΅ΠΎ.
+
+ΠΠ»Ρ ΡΠ°Π±ΠΎΡΡ Ρ ΠΌΡΠ»ΡΡΠΈΠΌΠ΅Π΄ΠΈΠ° Π΅ΡΡΡ Π²Π΅Π»ΠΈΠΊΠΎΠ»Π΅ΠΏΠ½ΡΠΉ ΠΈΠ½ΡΡΡΡΠΌΠ΅Π½Ρ/Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° [FFmpeg](https://www.ffmpeg.org/). Π‘ΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, ΡΡ ΡΠΆΠ΅ Π·Π½Π°ΠΊΠΎΠΌ Ρ Π½ΠΈΠΌ Π½Π°ΠΏΡΡΠΌΡΡ ΠΈΠ»ΠΈ ΠΊΠΎΡΠ²Π΅Π½Π½ΠΎ (ΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡΡ [Chrome?](https://www.chromium.org/developers/design-documents/video)).
+
+ΠΡΡΡ CLI-ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ° `ffmpeg` β ΠΏΡΠΎΡΡΠ°Ρ, Π½ΠΎ ΠΌΠΎΡΠ½Π°Ρ.
+ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΡΠΎΠ±Ρ ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ `mp4` Π² `avi`, Π΄ΠΎΡΡΠ°ΡΠΎΡΠ½ΠΎ:
+
+```bash
+$ ffmpeg -i input.mp4 output.avi
+```
+
+ΠΡ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΠΎ ΡΠ΄Π΅Π»Π°Π»ΠΈ **ΡΠ΅ΠΌΠ°ΠΊΡΠΈΠΌ** (remuxing) β ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°Π»ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ Π² Π΄ΡΡΠ³ΠΎΠΉ.
+Π’Π΅Ρ
Π½ΠΈΡΠ΅ΡΠΊΠΈ FFmpeg ΠΌΠΎΠ³ ΠΈ ΠΏΠ΅ΡΠ΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΠΏΠΎΡΠΎΠΊΠΈ, Π½ΠΎ ΠΎΠ± ΡΡΠΎΠΌ ΠΏΠΎΠ·ΠΆΠ΅.
+
+## FFmpeg CLI 101
+
+Π£ FFmpeg Π΅ΡΡΡ [Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ](https://www.ffmpeg.org/ffmpeg.html), ΠΎΡΠ»ΠΈΡΠ½ΠΎ ΠΎΠ±ΡΡΡΠ½ΡΡΡΠ°Ρ, ΠΊΠ°ΠΊ ΠΎΠ½ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ.
+
+```bash
+# Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΌΠΎΡΡΠ΅ΡΡ ΠΈ ΠΈΠ· ΠΊΠΎΠΌΠ°Π½Π΄Π½ΠΎΠΉ ΡΡΡΠΎΠΊΠΈ
+
+ffmpeg -h full | grep -A 10 -B 10 avoid_negative_ts
+```
+
+ΠΡΠ»ΠΈ ΠΊΡΠ°ΡΠΊΠΎ, `ffmpeg` ΠΏΠΎΠ»ΡΡΠ°Π΅Ρ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΡ Π² ΡΠΎΡΠΌΠ°ΡΠ΅ `ffmpeg {1} {2} -i {3} {4} {5}`, Π³Π΄Π΅:
+
+1. Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΎΠΏΡΠΈΠΈ
+2. ΠΎΠΏΡΠΈΠΈ Π²Ρ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
+3. Π²Ρ
ΠΎΠ΄Π½ΠΎΠΉ URL/ΠΏΡΡΡ
+4. ΠΎΠΏΡΠΈΠΈ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°
+5. Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ URL/ΠΏΡΡΡ
+
+ΠΠ»ΠΎΠΊΠΈ 2β5 ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ²ΡΠΎΡΡΡΡ ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ³ΠΎΠ΄Π½ΠΎ.
+ΠΡΠΎΡΠ΅ ΡΠ²ΠΈΠ΄Π΅ΡΡ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅:
+
+```bash
+# ΠΠΠΠΠΠΠΠ: ΡΠ°ΠΉΠ» ΠΎΠΊΠΎΠ»ΠΎ 300 ΠΠ
+$ wget -O bunny_1080p_60fps.mp4 http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_60fps_normal.mp4
+
+$ ffmpeg \
+-y \ # Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ ΠΎΠΏΡΠΈΠΈ
+-c:a libfdk_aac \ # ΠΎΠΏΡΠΈΠΈ Π²Ρ
ΠΎΠ΄Π°
+-i bunny_1080p_60fps.mp4 \ # Π²Ρ
ΠΎΠ΄Π½ΠΎΠΉ url
+-c:v libvpx-vp9 -c:a libvorbis \ # ΠΎΠΏΡΠΈΠΈ Π²ΡΡ
ΠΎΠ΄Π°
+bunny_1080p_60fps_vp9.webm # Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ url
+```
+
+ΠΡΠ° ΠΊΠΎΠΌΠ°Π½Π΄Π° Π±Π΅ΡΡΡ `mp4` Ρ Π΄Π²ΡΠΌΡ ΠΏΠΎΡΠΎΠΊΠ°ΠΌΠΈ (Π°ΡΠ΄ΠΈΠΎ Π² `aac` ΠΈ Π²ΠΈΠ΄Π΅ΠΎ Π² `h264`) ΠΈ Π΄Π΅Π»Π°Π΅Ρ `webm`, ΠΈΠ·ΠΌΠ΅Π½ΡΡ ΠΈ Π°ΡΠ΄ΠΈΠΎ-, ΠΈ Π²ΠΈΠ΄Π΅ΠΎ-ΠΊΠΎΠ΄Π΅ΠΊΠΈ.
+
+ΠΠΎΠΌΠ°Π½Π΄Ρ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΏΡΠΎΡΡΠΈΡΡ, Π½ΠΎ ΡΠΎΠ³Π΄Π° FFmpeg ΠΏΠΎΠ΄ΡΡΠ°Π²ΠΈΡ/ΡΠ³Π°Π΄Π°Π΅Ρ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
+ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π½Π°ΠΏΠΈΡΠ°ΡΡ `ffmpeg -i input.avi output.mp4`, ΡΠΎ ΠΊΠ°ΠΊΠΎΠΉ Π°ΡΠ΄ΠΈΠΎ/Π²ΠΈΠ΄Π΅ΠΎ ΠΊΠΎΠ΄Π΅ΠΊ Π±ΡΠ΄Π΅Ρ Π²ΡΠ±ΡΠ°Π½ Π΄Π»Ρ `output.mp4`?
+
+Π£ ΠΠ΅ΡΠ½Π΅ΡΠ° Π ΠΎΠ±ΠΈΡΡΡ Π΅ΡΡΡ ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠΉ ΠΊ ΠΏΡΠΎΡΡΠ΅Π½ΠΈΡ/Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ [ΠΊΡΡΡ ΠΏΠΎ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΈ ΡΠ΅Π΄Π°ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² FFmpeg](http://slhck.info/ffmpeg-encoding-course/#/).
+
+# Π’ΠΈΠΏΠΎΠ²ΡΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ Ρ Π²ΠΈΠ΄Π΅ΠΎ
+
+Π Π°Π±ΠΎΡΠ°Ρ Ρ Π°ΡΠ΄ΠΈΠΎ/Π²ΠΈΠ΄Π΅ΠΎ, ΠΌΡ ΠΎΠ±ΡΡΠ½ΠΎ ΡΠ΅ΡΠ°Π΅ΠΌ ΡΡΠ΄ ΡΠΈΠΏΠΎΠ²ΡΡ
Π·Π°Π΄Π°Ρ.
+
+## Transcoding (ΠΏΠ΅ΡΠ΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅)
+
+
+
+**Π§ΡΠΎ ΡΡΠΎ?** ΠΏΡΠ΅ΠΎΠ±ΡΠ°Π·ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ² (Π°ΡΠ΄ΠΈΠΎ ΠΈΠ»ΠΈ Π²ΠΈΠ΄Π΅ΠΎ) ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π΅ΠΊΠ° Π² Π΄ΡΡΠ³ΠΎΠΉ.
+
+**ΠΠ°ΡΠ΅ΠΌ?** ΠΈΠ½ΠΎΠ³Π΄Π° ΡΡΡΡΠΎΠΉΡΡΠ²ΠΎ (TV, ΡΠΌΠ°ΡΡΡΠΎΠ½, ΠΊΠΎΠ½ΡΠΎΠ»Ρ ΠΈ Ρ.Π΄.) Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΊΠΎΠ΄Π΅ΠΊ X, Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅Ρ ΠΊΠΎΠ΄Π΅ΠΊ Y; ΡΠ°ΠΊΠΆΠ΅ Π½ΠΎΠ²ΡΠ΅ ΠΊΠΎΠ΄Π΅ΠΊΠΈ Π½Π΅ΡΠ΅Π΄ΠΊΠΎ Π΄Π°ΡΡ Π»ΡΡΡΡΡ ΡΡΠ΅ΠΏΠ΅Π½Ρ ΡΠΆΠ°ΡΠΈΡ.
+
+**ΠΠ°ΠΊ?** ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅ΠΌ Π²ΠΈΠ΄Π΅ΠΎ `H264` (AVC) Π² `H265` (HEVC).
+
+```bash
+$ ffmpeg \
+-i bunny_1080p_60fps.mp4 \
+-c:v libx265 \
+bunny_1080p_60fps_h265.mp4
+```
+
+## Transmuxing (ΠΏΠ΅ΡΠ΅ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅)
+
+
+
+**Π§ΡΠΎ ΡΡΠΎ?** ΠΊΠΎΠ½Π²Π΅ΡΡΠ°ΡΠΈΡ ΠΈΠ· ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠΎΡΠΌΠ°ΡΠ° (ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°) Π² Π΄ΡΡΠ³ΠΎΠΉ.
+
+**ΠΠ°ΡΠ΅ΠΌ?** Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΡΡΠΎΠΉΡΡΠ²Π° Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ X, Π½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ Y; Π½ΠΎΠ²ΡΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΡ ΠΈΠ½ΠΎΠ³Π΄Π° Π΄Π°ΡΡ ΡΠΎΠ²ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΠΈΡΠΈ.
+
+**ΠΠ°ΠΊ?** ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅ΠΌ `mp4` Π² `ts`.
+
+```bash
+$ ffmpeg \
+-i bunny_1080p_60fps.mp4 \
+-c copy \ # ΠΏΡΠΎΡΠΈΠΌ ffmpeg ΠΏΡΠΎΠΏΡΡΡΠΈΡΡ ΠΏΠ΅ΡΠ΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
+bunny_1080p_60fps.ts
+```
+
+## Transrating (ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π±ΠΈΡΡΠ΅ΠΉΡΠ°)
+
+
+
+**Π§ΡΠΎ ΡΡΠΎ?** ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ Π±ΠΈΡΡΠ΅ΠΉΡΠ° ΠΈΠ»ΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠ΅ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΡ
Β«ΡΠ΅Π΄ΠΈΡΠ½ΠΎΠ²Β» (Π²Π΅ΡΡΠΈΠΉ).
+
+**ΠΠ°ΡΠ΅ΠΌ?** ΠΊΡΠΎ-ΡΠΎ Π±ΡΠ΄Π΅Ρ ΡΠΌΠΎΡΡΠ΅ΡΡ ΡΠ΅ΡΠ΅Π· `2G` Π½Π° ΡΠ»Π°Π±ΠΎΠΌ ΡΠΌΠ°ΡΡΡΠΎΠ½Π΅, Π° ΠΊΡΠΎ-ΡΠΎ β ΡΠ΅ΡΠ΅Π· `fiber` Π½Π° 4K-TV; ΡΡΠΎΠΈΡ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠΈΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π²Π΅ΡΡΠΈΠΉ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π²ΠΈΠ΄Π΅ΠΎ ΠΏΠΎΠ΄ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Π·ΡΠΈΡΠ΅Π»Ρ.
+
+**ΠΠ°ΠΊ?** Π΄Π΅Π»Π°Π΅ΠΌ Π²Π΅ΡΡΠΈΡ Ρ Π±ΠΈΡΡΠ΅ΠΉΡΠΎΠΌ ΠΌΠ΅ΠΆΠ΄Ρ 964K ΠΈ 3856K.
+
+```bash
+$ ffmpeg \
+-i bunny_1080p_60fps.mp4 \
+-minrate 964K -maxrate 3856K -bufsize 2000K \
+bunny_1080p_60fps_transrating_964_3856.mp4
+```
+
+ΠΠ±ΡΡΠ½ΠΎ transrating ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡ Π²ΠΌΠ΅ΡΡΠ΅ Ρ transsizing. Π£ ΠΠ΅ΡΠ½Π΅ΡΠ° Π ΠΎΠ±ΠΈΡΡΡ Π΅ΡΡΡ Π΅ΡΡ ΠΎΠ΄Π½Π° ΠΎΡΠ»ΠΈΡΠ½Π°Ρ [ΡΠ΅ΡΠΈΡ ΠΏΠΎΡΡΠΎΠ² ΠΎ ΠΊΠΎΠ½ΡΡΠΎΠ»Π΅ Π±ΠΈΡΡΠ΅ΠΉΡΠ° Π² FFmpeg](http://slhck.info/posts/).
+
+## Transsizing (ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ)
+
+
+
+**Π§ΡΠΎ ΡΡΠΎ?** ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠ΅ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΡ. ΠΠ°ΠΊ ΡΠΆΠ΅ ΡΠΊΠ°Π·Π°Π½ΠΎ, ΡΠ°ΡΡΠΎ ΠΈΠ΄ΡΡ Π² ΠΏΠ°ΡΠ΅ Ρ transrating.
+
+**ΠΠ°ΡΠ΅ΠΌ?** ΠΏΡΠΈΡΠΈΠ½Ρ ΡΠ΅ ΠΆΠ΅, ΡΡΠΎ ΠΈ Π΄Π»Ρ transrating.
+
+**ΠΠ°ΠΊ?** ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅ΠΌ `1080p` Π² `480p`.
+
+```bash
+$ ffmpeg \
+-i bunny_1080p_60fps.mp4 \
+-vf scale=480:-1 \
+bunny_1080p_60fps_transsizing_480.mp4
+```
+
+## Bonus Round: Adaptive Streaming
+
+
+
+**Π§ΡΠΎ ΡΡΠΎ?** ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠΉ (Π±ΠΈΡΡΠ΅ΠΉΡΠΎΠ²), ΡΠ΅ΠΆΠ΅ΠΌ ΠΌΠ΅Π΄ΠΈΠ° Π½Π° ΡΠ°Π½ΠΊΠΈ ΠΈ ΠΎΡΠ΄Π°ΡΠΌ ΠΏΠΎ HTTP.
+
+**ΠΠ°ΡΠ΅ΠΌ?** Π³ΠΈΠ±ΠΊΠΎΡΡΡ β ΠΌΠΎΠΆΠ½ΠΎ ΡΠΌΠΎΡΡΠ΅ΡΡ ΠΈ Π½Π° ΡΠ»Π°Π±ΠΎΠΌ ΡΠΌΠ°ΡΡΡΠΎΠ½Π΅, ΠΈ Π½Π° 4K-TV; Π»Π΅Π³ΠΊΠΎ ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°ΡΡ ΠΈ Π΄Π΅ΠΏΠ»ΠΎΠΈΡΡ, Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π·Π°Π΄Π΅ΡΠΆΠΊΡ.
+
+**ΠΠ°ΠΊ?** ΡΠΎΠ·Π΄Π°ΡΠΌ Π°Π΄Π°ΠΏΡΠΈΠ²Π½ΠΎΠ΅ WebM ΡΠ΅ΡΠ΅Π· DASH.
+
+```bash
+# Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡΠΎΠΊΠΈ
+$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 160x90 -b:v 250k -keyint_min 150 -g 150 -an -f webm -dash 1 video_160x90_250k.webm
+
+$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 320x180 -b:v 500k -keyint_min 150 -g 150 -an -f webm -dash 1 video_320x180_500k.webm
+
+$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 640x360 -b:v 750k -keyint_min 150 -g 150 -an -f webm -dash 1 video_640x360_750k.webm
+
+$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 640x360 -b:v 1000k -keyint_min 150 -g 150 -an -f webm -dash 1 video_640x360_1000k.webm
+
+$ ffmpeg -i bunny_1080p_60fps.mp4 -c:v libvpx-vp9 -s 1280x720 -b:v 1500k -keyint_min 150 -g 150 -an -f webm -dash 1 video_1280x720_1500k.webm
+
+# Π°ΡΠ΄ΠΈΠΎΠΏΠΎΡΠΎΠΊΠΈ
+$ ffmpeg -i bunny_1080p_60fps.mp4 -c:a libvorbis -b:a 128k -vn -f webm -dash 1 audio_128k.webm
+
+# DASH-ΠΌΠ°Π½ΠΈΡΠ΅ΡΡ
+$ ffmpeg \
+ -f webm_dash_manifest -i video_160x90_250k.webm \
+ -f webm_dash_manifest -i video_320x180_500k.webm \
+ -f webm_dash_manifest -i video_640x360_750k.webm \
+ -f webm_dash_manifest -i video_640x360_1000k.webm \
+ -f webm_dash_manifest -i video_1280x720_500k.webm \
+ -f webm_dash_manifest -i audio_128k.webm \
+ -c copy -map 0 -map 1 -map 2 -map 3 -map 4 -map 5 \
+ -f webm_dash_manifest \
+ -adaptation_sets "id=0,streams=0,1,2,3,4 id=1,streams=5" \
+ manifest.mpd
+```
+
+PS: Π― ΠΏΠΎΠ·Π°ΠΈΠΌΡΡΠ²ΠΎΠ²Π°Π» ΠΏΡΠΈΠΌΠ΅Ρ ΠΈΠ· [Instructions to playback Adaptive WebM using DASH](http://wiki.webmproject.org/adaptive-streaming/instructions-to-playback-adaptive-webm-using-dash)
+
+## ΠΠ°Π»ΡΡΠ΅ β Π±ΠΎΠ»ΡΡΠ΅
+
+[ΠΡΠΈΠΌΠ΅Π½Π΅Π½ΠΈΠΉ FFmpeg β ΡΡΠΌΠ°](https://github.com/leandromoreira/digital_video_introduction/blob/master/encoding_pratical_examples.md#split-and-merge-smoothly).
+Π― ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ Π΅Π³ΠΎ Π²ΠΌΠ΅ΡΡΠ΅ Ρ *iMovie* Π΄Π»Ρ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ/ΠΌΠΎΠ½ΡΠ°ΠΆΠ° ΡΠΎΠ»ΠΈΠΊΠΎΠ² Π΄Π»Ρ YouTube β ΠΈ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ Π΅Π³ΠΎ ΠΏΡΠΎΡΠ΅ΡΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎ.
+
+# Learn FFmpeg libav the Hard Way
+
+> Don't you wonder sometimes 'bout sound and vision?
+> **David Robert Jones**
+
+Π Π°Π· ΡΠΆ [FFmpeg](#ffmpeg---command-line) Π½Π°ΡΡΠΎΠ»ΡΠΊΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ Π² CLI Π΄Π»Ρ Π±Π°Π·ΠΎΠ²ΡΡ
ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΉ Ρ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Π°ΠΌΠΈ, ΠΊΠ°ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ Π² ΡΠ²ΠΎΠΈΡ
ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°Ρ
?
+
+FFmpeg β ΡΡΠΎ [Π½Π°Π±ΠΎΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ](https://www.ffmpeg.org/doxygen/trunk/index.html), ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ½ΡΠ΅Π³ΡΠΈΡΠΎΠ²Π°ΡΡ Π² ΡΠ²ΠΎΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
+ΠΠ±ΡΡΠ½ΠΎ ΠΏΡΠΈ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ΅ FFmpeg ΡΡΠ°Π²ΡΡΡΡ ΠΈ ΡΡΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ. Π― Π±ΡΠ΄Ρ Π½Π°Π·ΡΠ²Π°ΡΡ ΠΈΡ
ΡΠΎΠ²ΠΎΠΊΡΠΏΠ½ΠΎ **FFmpeg libav**.
+
+> ΠΡΠΎ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ β Π΄Π°Π½Ρ ΡΠ²Π°ΠΆΠ΅Π½ΠΈΡ ΡΠ΅ΡΠΈΠΈ Zed Shaw [Learn X the Hard Way](https://learncodethehardway.org/), Π² ΡΠ°ΡΡΠ½ΠΎΡΡΠΈ Π΅Π³ΠΎ ΠΊΠ½ΠΈΠ³Π΅ Learn C the Hard Way.
+
+## ΠΠ»Π°Π²Π° 0 β ΠΏΠ΅ΡΠ°Π»ΡΠ½ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΡΠΉ Β«hello worldΒ»
+
+ΠΡΠΎΡ hello world Π½Π΅ Π²ΡΠ²Π΅Π΄Π΅Ρ `"hello world"` Π² ΡΠ΅ΡΠΌΠΈΠ½Π°Π» :tongue:
+ΠΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΠΌΡ **ΡΠ°ΡΠΏΠ΅ΡΠ°ΡΠ°Π΅ΠΌ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ Π²ΠΈΠ΄Π΅ΠΎ** β ΡΠΎΡΠΌΠ°Ρ (ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ), Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ, ΡΠ°Π·ΡΠ΅ΡΠ΅Π½ΠΈΠ΅, ΠΊΠ°Π½Π°Π»Ρ Π°ΡΠ΄ΠΈΠΎ; Π° Π·Π°ΡΠ΅ΠΌ **Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅ΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΊΠ°Π΄ΡΠΎΠ² ΠΈ ΡΠΎΡ
ΡΠ°Π½ΠΈΠΌ ΠΈΡ
ΠΊΠ°ΠΊ ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ**.
+
+### ΠΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° FFmpeg libav
+
+ΠΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ ΠΏΠΈΡΠ°ΡΡ ΠΊΠΎΠ΄, ΡΠ°Π·Π±Π΅ΡΡΠΌΡΡ, **ΠΊΠ°ΠΊ ΡΡΡΡΠΎΠ΅Π½Π° FFmpeg libav** ΠΈ ΠΊΠ°ΠΊ ΡΠ°Π·Π½ΡΠ΅ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ Π²Π·Π°ΠΈΠΌΠΎΠ΄Π΅ΠΉΡΡΠ²ΡΡΡ ΠΌΠ΅ΠΆΠ΄Ρ ΡΠΎΠ±ΠΎΠΉ.
+
+Π‘Ρ
Π΅ΠΌΠ° ΠΏΡΠΎΡΠ΅ΡΡΠ° Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²ΠΈΠ΄Π΅ΠΎ:
+
+
+
+Π‘Π½Π°ΡΠ°Π»Π° Π½ΡΠΆΠ½ΠΎ Π·Π°Π³ΡΡΠ·ΠΈΡΡ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ» Π² ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ [`AVFormatContext`](https://ffmpeg.org/doxygen/trunk/structAVFormatContext.html) (ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅Ρ ΡΠ°ΠΊΠΆΠ΅ Π½Π°Π·ΡΠ²Π°ΡΡ Β«formatΒ»).
+ΠΠ° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΡΠ°ΠΉΠ» Π½Π΅ ΡΠΈΡΠ°Π΅ΡΡΡ: Π·Π°ΡΠ°ΡΡΡΡ ΠΏΠ°ΡΡΠΈΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ.
+
+ΠΠΎΡΠ»Π΅ ΡΡΠ΅Π½ΠΈΡ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΠΎΠ³ΠΎ **Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°** ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ Π΅Π³ΠΎ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ (ΠΏΠΎ ΡΡΡΠΈ β ΡΡΡΠΎΠΉ Π°ΡΠ΄ΠΈΠΎ/Π²ΠΈΠ΄Π΅ΠΎ).
+ΠΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΡΠΎΠΊ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΡΠ΅ΡΠ΅Π· [`AVStream`](https://ffmpeg.org/doxygen/trunk/structAVStream.html).
+
+> Stream β ΠΊΡΠ°ΡΠΈΠ²ΠΎΠ΅ ΡΠ»ΠΎΠ²ΠΎ Π΄Π»Ρ Β«Π½Π΅ΠΏΡΠ΅ΡΡΠ²Π½ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° Π΄Π°Π½Π½ΡΡ
Β».
+
+ΠΠΎΠΏΡΡΡΠΈΠΌ, Ρ Π½Π°ΡΠ΅Π³ΠΎ Π²ΠΈΠ΄Π΅ΠΎ Π΄Π²Π° ΠΏΠΎΡΠΎΠΊΠ°: Π°ΡΠ΄ΠΈΠΎ Π² [AAC](https://en.wikipedia.org/wiki/Advanced_Audio_Coding) ΠΈ Π²ΠΈΠ΄Π΅ΠΎ Π² [H264 (AVC)](https://en.wikipedia.org/wiki/H.264/MPEG-4_AVC). ΠΠ· ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΠΌΡ ΠΈΠ·Π²Π»Π΅ΠΊΠ°Π΅ΠΌ **ΠΊΡΡΠΎΡΠΊΠΈ Π΄Π°Π½Π½ΡΡ
** β ΠΏΠ°ΠΊΠ΅ΡΡ, [`AVPacket`](https://ffmpeg.org/doxygen/trunk/structAVPacket.html).
+
+**ΠΠ°Π½Π½ΡΠ΅ Π² ΠΏΠ°ΠΊΠ΅ΡΠ°Ρ
Π²ΡΡ Π΅ΡΡ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½Ρ** (ΡΠΆΠ°ΡΡ), ΠΈ ΡΡΠΎΠ±Ρ ΠΈΡ
Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ, ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ ΠΈΡ
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅ΠΌΡ [`AVCodec`](https://ffmpeg.org/doxygen/trunk/structAVCodec.html).
+
+`AVCodec` Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅Ρ ΠΈΡ
Π² [`AVFrame`](https://ffmpeg.org/doxygen/trunk/structAVFrame.html), ΠΈ, Π½Π°ΠΊΠΎΠ½Π΅Ρ, ΠΌΡ ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ **Π½Π΅ΡΠΆΠ°ΡΡΠΉ ΠΊΠ°Π΄Ρ**. ΠΠ±ΡΠ°ΡΠΈ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΡΠ΅ΡΠΌΠΈΠ½ΠΎΠ»ΠΎΠ³ΠΈΡ/ΠΏΡΠΎΡΠ΅ΡΡ ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ ΠΈ Π΄Π»Ρ Π°ΡΠ΄ΠΈΠΎ, ΠΈ Π΄Π»Ρ Π²ΠΈΠ΄Π΅ΠΎ.
+
+### Π’ΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ
+
+ΠΠΎΡΠΊΠΎΠ»ΡΠΊΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ ΡΡΠ°Π»ΠΊΠΈΠ²Π°Π»ΠΈΡΡ Ρ [ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ ΠΏΡΠΈ ΡΠ±ΠΎΡΠΊΠ΅/Π·Π°ΠΏΡΡΠΊΠ΅ ΠΏΡΠΈΠΌΠ΅ΡΠΎΠ²](https://github.com/leandromoreira/ffmpeg-libav-tutorial/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+compiling), **ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ [`Docker`](https://docs.docker.com/install/) ΠΊΠ°ΠΊ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ/Π·Π°ΠΏΡΡΠΊΠ°**. Π’Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ ΡΠΎΠ»ΠΈΠΊ big buck bunny; Π΅ΡΠ»ΠΈ Π΅Π³ΠΎ Π½Π΅Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΠΎ, Π²ΡΠΏΠΎΠ»Π½ΠΈΡΠ΅ `make fetch_small_bunny_video`.
+
+### ΠΠ»Π°Π²Π° 0 - ΠΏΡΠΎΠΉΠ΄Π΅ΠΌΡΡ ΠΏΠΎ ΠΊΠΎΠ΄Ρ
+
+> #### TLDR; ΠΏΠΎΠΊΠ°ΠΆΠΈ [ΠΊΠΎΠ΄](/0_hello_world.c) ΠΈ ΠΊΠ°ΠΊ Π΅Π³ΠΎ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ.
+>
+> ```bash
+> $ make run_hello
+> ```
+
+ΠΠΏΡΡΡΠΈΠΌ Π½Π΅ΠΊΠΎΡΠΎΡΡΠ΅ Π΄Π΅ΡΠ°Π»ΠΈ, Π½ΠΎ Π½Π΅ ΠΏΠ΅ΡΠ΅ΠΆΠΈΠ²Π°ΠΉΡΠ΅: [ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ Π½Π° GitHub](/0_hello_world.c).
+
+ΠΡΠ΄Π΅Π»ΠΈΠΌ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ [`AVFormatContext`](http://ffmpeg.org/doxygen/trunk/structAVFormatContext.html), ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Ρ
ΡΠ°Π½ΠΈΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΎ ΡΠΎΡΠΌΠ°ΡΠ΅ (ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ΅).
+
+```c
+AVFormatContext *pFormatContext = avformat_alloc_context();
+```
+
+Π’Π΅ΠΏΠ΅ΡΡ ΠΎΡΠΊΡΠΎΠ΅ΠΌ ΡΠ°ΠΉΠ», ΠΏΡΠΎΡΠΈΡΠ°Π΅ΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ ΠΈ Π·Π°ΠΏΠΎΠ»Π½ΠΈΠΌ `AVFormatContext` ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΠΎΠΉ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠ΅ΠΉ ΠΎ ΡΠΎΡΠΌΠ°ΡΠ΅ (Π·Π°ΠΌΠ΅ΡΡ, ΠΊΠΎΠ΄Π΅ΠΊΠΈ ΠΎΠ±ΡΡΠ½ΠΎ Π½Π΅ ΠΎΡΠΊΡΡΠ²Π°ΡΡΡΡ).
+ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ [`avformat_open_input`](http://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#ga31d601155e9035d5b0e7efedc894ee49). ΠΠ° Π²Ρ
ΠΎΠ΄ β `AVFormatContext`, `filename` ΠΈ Π΄Π²Π° Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΡ
Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°: [`AVInputFormat`](https://ffmpeg.org/doxygen/trunk/structAVInputFormat.html) (Π΅ΡΠ»ΠΈ `NULL`, FFmpeg ΡΠ³Π°Π΄Π°Π΅Ρ ΡΠΎΡΠΌΠ°Ρ) ΠΈ [`AVDictionary`](https://ffmpeg.org/doxygen/trunk/structAVDictionary.html) (ΠΎΠΏΡΠΈΠΈ Π΄Π΅ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΎΡΠ°).
+
+```c
+avformat_open_input(&pFormatContext, filename, NULL, NULL);
+```
+
+ΠΠΎΠΆΠ½ΠΎ Π²ΡΠ²Π΅ΡΡΠΈ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΡΠΎΡΠΌΠ°ΡΠ° ΠΈ Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ:
+
+```c
+printf("Format %s, duration %lld us", pFormatContext->iformat->long_name, pFormatContext->duration);
+```
+
+Π§ΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ `streams`, Π½ΡΠΆΠ½ΠΎ ΠΏΡΠΎΡΠΈΡΠ°ΡΡ Π΄Π°Π½Π½ΡΠ΅ ΠΈΠ· ΠΌΠ΅Π΄ΠΈΠ°. Π€ΡΠ½ΠΊΡΠΈΡ [`avformat_find_stream_info`](https://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#gad42172e27cddafb81096939783b157bb) Π΄Π΅Π»Π°Π΅Ρ ΡΡΠΎ.
+Π’Π΅ΠΏΠ΅ΡΡ `pFormatContext->nb_streams` β ΡΠΈΡΠ»ΠΎ ΠΏΠΎΡΠΎΠΊΠΎΠ², Π° `pFormatContext->streams[i]` β ΡΠ°ΠΌ `i`-ΠΉ ΠΏΠΎΡΠΎΠΊ (`AVStream`).
+
+```c
+avformat_find_stream_info(pFormatContext, NULL);
+```
+
+ΠΡΠΎΠΉΠ΄ΡΠΌΡΡ ΠΏΠΎ Π²ΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ:
+
+```c
+for (int i = 0; i < pFormatContext->nb_streams; i++)
+{
+ //
+}
+```
+
+ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΡΠΎΠΊΠ° ΡΠΎΡ
ΡΠ°Π½ΠΈΠΌ [`AVCodecParameters`](https://ffmpeg.org/doxygen/trunk/structAVCodecParameters.html) β ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠΎΠ΄Π΅ΠΊΠ°, ΠΊΠΎΡΠΎΡΡΠΌ Π·Π°ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ ΠΏΠΎΡΠΎΠΊ `i`.
+
+```c
+AVCodecParameters *pLocalCodecParameters = pFormatContext->streams[i]->codecpar;
+```
+
+ΠΠ½Π°Ρ ΡΠ²ΠΎΠΉΡΡΠ²Π° ΠΊΠΎΠ΄Π΅ΠΊΠ°, ΠΈΡΠ΅ΠΌ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΡΡΠΈΠΉ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ ΡΠ΅ΡΠ΅Π· [`avcodec_find_decoder`](https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga19a0ca553277f019dd5b0fec6e1f9dca) β ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ ΠΏΠΎ `codec_id`, Ρ.Π΅. [`AVCodec`](http://ffmpeg.org/doxygen/trunk/structAVCodec.html) β ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΌΠ΅Π΅Ρ **enCO**de/**DEC**ode ΠΏΠΎΡΠΎΠΊ.
+
+```c
+AVCodec *pLocalCodec = avcodec_find_decoder(pLocalCodecParameters->codec_id);
+```
+
+Π’Π΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ²Π΅ΡΡΠΈ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΊΠΎΠ΄Π΅ΠΊΠ°Ρ
.
+
+```c
+// Π²ΠΈΠ΄Π΅ΠΎ ΠΈ Π°ΡΠ΄ΠΈΠΎ
+if (pLocalCodecParameters->codec_type == AVMEDIA_TYPE_VIDEO) {
+ printf("Video Codec: resolution %d x %d", pLocalCodecParameters->width, pLocalCodecParameters->height);
+} else if (pLocalCodecParameters->codec_type == AVMEDIA_TYPE_AUDIO) {
+ printf("Audio Codec: %d channels, sample rate %d", pLocalCodecParameters->channels, pLocalCodecParameters->sample_rate);
+}
+// ΠΎΠ±ΡΠ΅Π΅
+printf("\tCodec %s ID %d bit_rate %lld", pLocalCodec->long_name, pLocalCodec->id, pLocalCodecParameters->bit_rate);
+```
+
+Π‘ ΠΊΠΎΠ΄Π΅ΠΊΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ΄Π΅Π»ΠΈΡΡ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ [`AVCodecContext`](https://ffmpeg.org/doxygen/trunk/structAVCodecContext.html) β ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π΄Π»Ρ ΠΏΡΠΎΡΠ΅ΡΡΠΎΠ² ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ/Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π·Π°ΡΠ΅ΠΌ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡΡ Π΅Π³ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ ΠΊΠΎΠ΄Π΅ΠΊΠ° ΡΠ΅ΡΠ΅Π· [`avcodec_parameters_to_context`](https://ffmpeg.org/doxygen/trunk/group__lavc__core.html#gac7b282f51540ca7a99416a3ba6ee0d16).
+
+ΠΠΎΡΠ»Π΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° β ΠΎΡΠΊΡΡΡΡ ΠΊΠΎΠ΄Π΅ΠΊ ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ [`avcodec_open2`](https://ffmpeg.org/doxygen/trunk/group__lavc__core.html#ga11f785a188d7d9df71621001465b0f1d).
+
+```c
+AVCodecContext *pCodecContext = avcodec_alloc_context3(pCodec);
+avcodec_parameters_to_context(pCodecContext, pCodecParameters);
+avcodec_open2(pCodecContext, pCodec, NULL);
+```
+
+Π’Π΅ΠΏΠ΅ΡΡ ΠΌΡ Π±ΡΠ΄Π΅ΠΌ ΡΠΈΡΠ°ΡΡ ΠΏΠ°ΠΊΠ΅ΡΡ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠ° ΠΈ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΠΈΡ
Π² ΠΊΠ°Π΄ΡΡ, Π½ΠΎ ΡΠΏΠ΅ΡΠ²Π° Π²ΡΠ΄Π΅Π»ΠΈΠΌ ΠΏΠ°ΠΌΡΡΡ Π΄Π»Ρ [`AVPacket`](https://ffmpeg.org/doxygen/trunk/structAVPacket.html) ΠΈ [`AVFrame`](https://ffmpeg.org/doxygen/trunk/structAVFrame.html).
+
+```c
+AVPacket *pPacket = av_packet_alloc();
+AVFrame *pFrame = av_frame_alloc();
+```
+
+Π‘ΡΠΈΡΡΠ²Π°Π΅ΠΌ ΠΏΠ°ΠΊΠ΅ΡΡ ΠΈΠ· ΠΏΠΎΡΠΎΠΊΠΎΠ² ΡΠ΅ΡΠ΅Π· [`av_read_frame`](https://ffmpeg.org/doxygen/trunk/group__lavf__decoding.html#ga4fdb3084415a82e3810de6ee60e46a61), ΠΏΠΎΠΊΠ° ΠΎΠ½ΠΈ Π΅ΡΡΡ.
+
+```c
+while (av_read_frame(pFormatContext, pPacket) >= 0) {
+ //...
+}
+```
+
+**ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΠΆΠ°ΡΡΠΉ ΠΏΠ°ΠΊΠ΅Ρ** (compressed frame) Π² Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ ΡΠ΅ΡΠ΅Π· ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ ΠΊΠΎΠ΄Π΅ΠΊΠ° β [`avcodec_send_packet`](https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga58bc4bf1e0ac59e27362597e467efff3).
+
+```c
+avcodec_send_packet(pCodecContext, pPacket);
+```
+
+Π **ΠΏΠΎΠ»ΡΡΠ°Π΅ΠΌ Π½Π΅ΡΠΆΠ°ΡΡΠΉ ΠΊΠ°Π΄Ρ** ΠΈΠ· Π΄Π΅ΠΊΠΎΠ΄Π΅ΡΠ° ΡΠ΅ΡΠ΅Π· ΡΠΎΡ ΠΆΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ β [`avcodec_receive_frame`](https://ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c).
+
+```c
+avcodec_receive_frame(pCodecContext, pFrame);
+```
+
+ΠΠΎΠΆΠ½ΠΎ Π²ΡΠ²Π΅ΡΡΠΈ Π½ΠΎΠΌΠ΅Ρ ΠΊΠ°Π΄ΡΠ°, [PTS](https://en.wikipedia.org/wiki/Presentation_timestamp), DTS, [ΡΠΈΠΏ ΠΊΠ°Π΄ΡΠ°](https://en.wikipedia.org/wiki/Video_compression_picture_types) ΠΈ Ρ.Π΄.
+
+```c
+printf(
+ "Frame %c (%d) pts %d dts %d key_frame %d [coded_picture_number %d, display_picture_number %d]",
+ av_get_picture_type_char(pFrame->pict_type),
+ pCodecContext->frame_number,
+ pFrame->pts,
+ pFrame->pkt_dts,
+ pFrame->key_frame,
+ pFrame->coded_picture_number,
+ pFrame->display_picture_number
+);
+```
+
+Π Π½Π°ΠΊΠΎΠ½Π΅Ρ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΎΡ
ΡΠ°Π½ΠΈΡΡ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠ°Π΄Ρ ΠΊΠ°ΠΊ [ΠΏΡΠΎΡΡΠΎΠ΅ Β«ΡΠ΅ΡΠΎΠ΅Β» ΠΈΠ·ΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΠ΅](https://en.wikipedia.org/wiki/Netpbm_format#PGM_example). ΠΡΡ ΠΏΡΠΎΡΡΠΎ: Π±Π΅ΡΡΠΌ `pFrame->data`, Π³Π΄Π΅ ΠΈΠ½Π΄Π΅ΠΊΡΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡ [ΠΏΠ»ΠΎΡΠΊΠΎΡΡΡΠΌ Y, Cb ΠΈ Cr](https://en.wikipedia.org/wiki/YCbCr), ΠΈ Π±Π΅ΡΡΠΌ `0` (Y), ΡΡΠΎΠ±Ρ ΡΠΎΡ
ΡΠ°Π½ΠΈΡΡ Π³ΡΠ°Π΄Π°ΡΠΈΠΈ ΡΠ΅ΡΠΎΠ³ΠΎ.
+
+```c
+save_gray_frame(pFrame->data[0], pFrame->linesize[0], pFrame->width, pFrame->height, frame_filename);
+
+static void save_gray_frame(unsigned char *buf, int wrap, int xsize, int ysize, char *filename)
+{
+ FILE *f;
+ int i;
+ f = fopen(filename,"w");
+ // ΠΏΠΈΡΠ΅ΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Π΄Π»Ρ ΡΠΎΡΠΌΠ°ΡΠ° pgm
+ // portable graymap format -> https://en.wikipedia.org/wiki/Netpbm_format#PGM_example
+ fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
+
+ // ΠΏΠΈΡΠ΅ΠΌ ΠΏΠΎΡΡΡΠΎΡΠ½ΠΎ
+ for (i = 0; i < ysize; i++)
+ fwrite(buf + i * wrap, 1, xsize, f);
+ fclose(f);
+}
+```
+
+VoilΓ ! Π£ Π½Π°Ρ Π΅ΡΡΡ ΠΎΡΡΠ΅Π½ΠΊΠΈ ΡΠ΅ΡΠΎΠ³ΠΎ ~2 ΠΠ:
+
+
+
+## ΠΠ»Π°Π²Π° 1 β ΡΠ°ΠΉΠΌΠΈΠ½Π³ΠΈ/ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·Π°ΡΠΈΡ
+
+> **ΠΡΠ΄Ρ ΠΏΠ»Π΅Π΅ΡΠΎΠΌ** β ΠΌΠΎΠ»ΠΎΠ΄ΠΎΠΉ JS-ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΏΠΈΡΠ΅Ρ Π½ΠΎΠ²ΡΠΉ MSE-Π²ΠΈΠ΄Π΅ΠΎΠΏΠ»Π΅Π΅Ρ.
+
+ΠΡΠ΅ΠΆΠ΄Π΅ ΡΠ΅ΠΌ [ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ ΠΊ ΠΏΡΠΈΠΌΠ΅ΡΡ ΡΡΠ°Π½ΡΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ](#chapter-2---transcoding), ΠΏΠΎΠ³ΠΎΠ²ΠΎΡΠΈΠΌ ΠΏΡΠΎ **ΡΠ°ΠΉΠΌΠΈΠ½Π³** β ΠΊΠ°ΠΊ ΠΏΠ»Π΅Π΅Ρ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΊΠ°Π΄Ρ.
+
+Π ΠΏΡΠΎΡΠ»ΠΎΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΌΡ ΡΠΎΡ
ΡΠ°Π½ΠΈΠ»ΠΈ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΊΠ°Π΄ΡΠΎΠ²:
+
+
+
+
+
+
+
+
+ΠΡΠΈ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠ΅ Π²ΠΈΠ΄Π΅ΠΎΠΏΠ»Π΅Π΅ΡΠ° Π½ΡΠΆΠ½ΠΎ **ΠΏΡΠΎΠΈΠ³ΡΡΠ²Π°ΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΊΠ°Π΄Ρ Π² Π½ΡΠΆΠ½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ** β ΠΈΠ½Π°ΡΠ΅ Π±ΡΠ΄Π΅Ρ Π»ΠΈΠ±ΠΎ ΡΠ»ΠΈΡΠΊΠΎΠΌ Π±ΡΡΡΡΠΎ, Π»ΠΈΠ±ΠΎ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ.
+
+ΠΠ»Ρ ΠΏΠ»Π°Π²Π½ΠΎΠ³ΠΎ Π²ΠΎΡΠΏΡΠΎΠΈΠ·Π²Π΅Π΄Π΅Π½ΠΈΡ Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ°Π΄ΡΠ° Π΅ΡΡΡ **PTS (presentation timestamp)** β Π²ΠΎΠ·ΡΠ°ΡΡΠ°ΡΡΠ΅Π΅ ΡΠΈΡΠ»ΠΎ Π² **timebase** (ΡΠ°ΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΠ΅ ΡΠΈΡΠ»ΠΎ, Π³Π΄Π΅ Π·Π½Π°ΠΌΠ΅Π½Π°ΡΠ΅Π»Ρ β **timescale**), ΠΊΡΠ°ΡΠ½ΠΎΠ΅ **fps**.
+
+ΠΡΠΎΡΠ΅ Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ
.
+
+ΠΠ»Ρ `fps=60/1` ΠΈ `timebase=1/60000` PTS ΡΠ²Π΅Π»ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ Π½Π° `timescale / fps = 1000`, Π·Π½Π°ΡΠΈΡ **ΡΠ΅Π°Π»ΡΠ½ΠΎΠ΅ Π²ΡΠ΅ΠΌΡ PTS** ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΊΠ°Π΄ΡΠ° (Π΅ΡΠ»ΠΈ ΡΡΠ°ΡΡ Ρ 0):
+
+* `frame=0, PTS = 0, PTS_TIME = 0`
+* `frame=1, PTS = 1000, PTS_TIME = PTS * timebase = 0.016`
+* `frame=2, PTS = 2000, PTS_TIME = PTS * timebase = 0.033`
+
+ΠΠΎΡΡΠΈ ΡΠΎΡ ΠΆΠ΅ ΡΡΠ΅Π½Π°ΡΠΈΠΉ Ρ `timebase=1/60`:
+
+* `frame=0, PTS = 0, PTS_TIME = 0`
+* `frame=1, PTS = 1, PTS_TIME = 0.016`
+* `frame=2, PTS = 2, PTS_TIME = 0.033`
+* `frame=3, PTS = 3, PTS_TIME = 0.050`
+
+ΠΠ»Ρ `fps=25/1` ΠΈ `timebase=1/75` PTS ΡΠ°ΡΡΡΡ Π½Π° `3`, Π²ΡΠ΅ΠΌΠ΅Π½Π°:
+
+* `frame=0, PTS = 0, PTS_TIME = 0`
+* `frame=1, PTS = 3, PTS_TIME = 0.04`
+* `frame=2, PTS = 6, PTS_TIME = 0.08`
+* `frame=3, PTS = 9, PTS_TIME = 0.12`
+* ...
+* `frame=24, PTS = 72, PTS_TIME = 0.96`
+* ...
+* `frame=4064, PTS = 12192, PTS_TIME = 162.56`
+
+ΠΠ½Π°Ρ `pts_time`, ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅Π½Π΄Π΅ΡΠΈΡΡ, ΡΠΈΠ½Ρ
ΡΠΎΠ½ΠΈΠ·ΠΈΡΡΡ Ρ Π°ΡΠ΄ΠΈΠΎ `pts_time` ΠΈΠ»ΠΈ ΡΠΈΡΡΠ΅ΠΌΠ½ΡΠΌΠΈ ΡΠ°ΡΠ°ΠΌΠΈ. FFmpeg libav ΠΎΡΠ΄Π°ΡΡ ΡΡΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΠ΅ΡΠ΅Π· API:
+
+* fps = [`AVStream->avg_frame_rate`](https://ffmpeg.org/doxygen/trunk/structAVStream.html#a946e1e9b89eeeae4cab8a833b482c1ad)
+* tbr = [`AVStream->r_frame_rate`](https://ffmpeg.org/doxygen/trunk/structAVStream.html#ad63fb11cc1415e278e09ddc676e8a1ad)
+* tbn = [`AVStream->time_base`](https://ffmpeg.org/doxygen/trunk/structAVStream.html#a9db755451f14e2bf590d4b85d82b32e6)
+
+Π ΡΠ»ΠΎΠ²Ρ: ΠΊΠ°Π΄ΡΡ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΌΡ ΡΠΎΡ
ΡΠ°Π½ΠΈΠ»ΠΈ, ΠΏΡΠΈΡ
ΠΎΠ΄ΠΈΠ»ΠΈ Π² ΠΏΠΎΡΡΠ΄ΠΊΠ΅ DTS (1,6,4,2,3,5), Π½ΠΎ Π²ΠΎΡΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΠ»ΠΈΡΡ ΠΏΠΎ PTS (1,2,3,4,5). Π ΠΎΠ±ΡΠ°ΡΠΈ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Π½Π°ΡΠΊΠΎΠ»ΡΠΊΠΎ Β«Π΄Π΅ΡΠ΅Π²Π»Π΅Β» B-ΠΊΠ°Π΄ΡΡ ΠΏΠΎ ΡΡΠ°Π²Π½Π΅Π½ΠΈΡ Ρ P ΠΈ I.
+
+```
+LOG: AVStream->r_frame_rate 60/1
+LOG: AVStream->time_base 1/60000
+...
+LOG: Frame 1 (type=I, size=153797 bytes) pts 6000 key_frame 1 [DTS 0]
+LOG: Frame 2 (type=B, size=8117 bytes) pts 7000 key_frame 0 [DTS 3]
+LOG: Frame 3 (type=B, size=8226 bytes) pts 8000 key_frame 0 [DTS 4]
+LOG: Frame 4 (type=B, size=17699 bytes) pts 9000 key_frame 0 [DTS 2]
+LOG: Frame 5 (type=B, size=6253 bytes) pts 10000 key_frame 0 [DTS 5]
+LOG: Frame 6 (type=P, size=34992 bytes) pts 11000 key_frame 0 [DTS 1]
+```
+
+## ΠΠ»Π°Π²Π° 2 β remuxing
+
+Remuxing β ΡΠΌΠ΅Π½Π° ΡΠΎΡΠΌΠ°ΡΠ° (ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°). ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠΎΠΆΠ½ΠΎ Π±Π΅Π· Π±ΠΎΠ»ΠΈ ΠΏΠΎΠΌΠ΅Π½ΡΡΡ [MPEG-4](https://en.wikipedia.org/wiki/MPEG-4_Part_14) Π½Π° [MPEG-TS](https://en.wikipedia.org/wiki/MPEG_transport_stream) Ρ FFmpeg:
+
+```bash
+ffmpeg input.mp4 -c copy output.ts
+```
+
+FFmpeg Π΄Π΅ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΡΠ΅Ρ mp4, Π½ΠΎ **Π½Π΅** Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅Ρ/ΠΊΠΎΠ΄ΠΈΡΡΠ΅Ρ (`-c copy`), Π° Π² ΠΊΠΎΠ½ΡΠ΅ ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΡΠ΅Ρ Π² `mpegts`. ΠΡΠ»ΠΈ Π½Π΅ ΡΠΊΠ°Π·Π°ΡΡ ΡΠΎΡΠΌΠ°Ρ ΡΠ΅ΡΠ΅Π· `-f`, FFmpeg ΠΏΠΎΠΏΡΡΠ°Π΅ΡΡΡ ΡΠ³Π°Π΄Π°ΡΡ ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ.
+
+ΠΠ±ΡΠ°Ρ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΠ° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ FFmpeg/libav ΡΠ°ΠΊΠΎΠ²Π°:
+
+* **[protocol layer](https://ffmpeg.org/doxygen/trunk/protocols_8c.html)** β ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ `input` (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, `file`, Π½ΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ `rtmp`/`HTTP`)
+* **[format layer](https://ffmpeg.org/doxygen/trunk/group__libavf.html)** β `demuxes` (Π΄Π΅ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΈΡΡΠ΅Ρ) ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅, ΠΎΡΠ΄Π°ΡΡ ΠΌΠ΅ΡΠ°Π΄Π°Π½Π½ΡΠ΅ ΠΈ ΠΏΠΎΡΠΎΠΊΠΈ
+* **[codec layer](https://ffmpeg.org/doxygen/trunk/group__libavc.html)** β `decodes` (Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅Ρ) ΡΠΆΠ°ΡΡΠ΅ Π΄Π°Π½Π½ΡΠ΅ ΠΏΠΎΡΠΎΠΊΠΎΠ² *Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ*
+* **[pixel layer](https://ffmpeg.org/doxygen/trunk/group__lavfi.html)** β ΠΏΡΠΈΠΌΠ΅Π½ΡΠ΅Ρ `filters` ΠΊ ΡΡΡΡΠΌ ΠΊΠ°Π΄ΡΠ°ΠΌ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠ°ΡΡΡΠ°Π±ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅) *Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ*
+* ΠΏΠΎΡΠΎΠΌ ΠΎΠ±ΡΠ°ΡΠ½ΡΠΉ ΠΏΡΡΡ:
+* **[codec layer](https://ffmpeg.org/doxygen/trunk/group__libavc.html)** β `encodes`/`re-encodes`/`transcodes` ΡΡΡΡΠ΅ ΠΊΠ°Π΄ΡΡ *Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ*
+* **[format layer](https://ffmpeg.org/doxygen/trunk/group__libavf.html)** β `muxes`/`remuxes` ΡΠΆΠ°ΡΡΠ΅ Π΄Π°Π½Π½ΡΠ΅
+* **[protocol layer](https://ffmpeg.org/doxygen/trunk/protocols_8c.html)** β Π²ΡΠ΄Π°ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ Π½Π° `output` (ΡΠ°ΠΉΠ» ΠΈΠ»ΠΈ ΡΠ΅ΡΡ)
+
+
+
+> ΠΡΠ°ΡΠΈΠΊ Π²Π΄ΠΎΡ
Π½ΠΎΠ²Π»ΡΠ½ ΡΠ°Π±ΠΎΡΠ°ΠΌΠΈ [Leixiaohua](http://leixiaohua1020.github.io/#ffmpeg-development-examples) ΠΈ [Slhck](https://slhck.info/ffmpeg-encoding-course/#/9).
+
+Π’Π΅ΠΏΠ΅ΡΡ Π½Π°ΠΏΠΈΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅Ρ Π½Π° libav, ΡΠΊΠ²ΠΈΠ²Π°Π»Π΅Π½ΡΠ½ΡΠΉ `ffmpeg input.mp4 -c copy output.ts`.
+
+ΠΡ ΡΠΈΡΠ°Π΅ΠΌ ΠΈΠ· Π²Ρ
ΠΎΠ΄Π° (`input_format_context`) ΠΈ ΠΏΠΈΡΠ΅ΠΌ Π² Π²ΡΡ
ΠΎΠ΄ (`output_format_context`).
+
+```c
+AVFormatContext *input_format_context = NULL;
+AVFormatContext *output_format_context = NULL;
+```
+
+Π‘Π½Π°ΡΠ°Π»Π° β ΠΎΠ±ΡΡΠ½ΡΠ΅ ΡΠ°Π³ΠΈ: Π²ΡΠ΄Π΅Π»ΠΈΡΡ ΠΏΠ°ΠΌΡΡΡ ΠΈ ΠΎΡΠΊΡΡΡΡ Π²Ρ
ΠΎΠ΄. Π ΡΡΠΎΠΌ ΠΊΠ΅ΠΉΡΠ΅ β ΠΎΡΠΊΡΡΡΡ Π²Ρ
ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ» ΠΈ Π²ΡΠ΄Π΅Π»ΠΈΡΡ ΠΏΠ°ΠΌΡΡΡ ΠΏΠΎΠ΄ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ.
+
+```c
+if ((ret = avformat_open_input(&input_format_context, in_filename, NULL, NULL)) < 0) {
+ fprintf(stderr, "Could not open input file '%s'", in_filename);
+ goto end;
+}
+if ((ret = avformat_find_stream_info(input_format_context, NULL)) < 0) {
+ fprintf(stderr, "Failed to retrieve input stream information");
+ goto end;
+}
+
+avformat_alloc_output_context2(&output_format_context, NULL, NULL, out_filename);
+if (!output_format_context) {
+ fprintf(stderr, "Could not create output context\n");
+ ret = AVERROR_UNKNOWN;
+ goto end;
+}
+```
+
+Π Π΅ΠΌΡΠΊΡΠΈΡΡ Π±ΡΠ΄Π΅ΠΌ ΡΠΎΠ»ΡΠΊΠΎ Π²ΠΈΠ΄Π΅ΠΎ, Π°ΡΠ΄ΠΈΠΎ ΠΈ ΡΡΠ±ΡΠΈΡΡΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π΄Π΅ΡΠΆΠΈΠΌ ΠΈΠ½Π΄Π΅ΠΊΡΡ Π½ΡΠΆΠ½ΡΡ
ΠΏΠΎΡΠΎΠΊΠΎΠ² Π² ΠΌΠ°ΡΡΠΈΠ²Π΅.
+
+```
+number_of_streams = input_format_context->nb_streams;
+streams_list = av_mallocz_array(number_of_streams, sizeof(*streams_list));
+```
+
+ΠΠΎΡΠ»Π΅ Π²ΡΠ΄Π΅Π»Π΅Π½ΠΈΡ ΠΏΠ°ΠΌΡΡΠΈ ΠΏΡΠΎΡ
ΠΎΠ΄ΠΈΠΌ ΠΏΠΎ Π²ΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠ°ΠΌ; Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°ΡΠΌ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΠΏΠΎΡΠΎΠΊ Π² `output_format_context` ΡΠ΅ΡΠ΅Π· [avformat_new_stream](https://ffmpeg.org/doxygen/trunk/group__lavf__core.html#gadcb0fd3e507d9b58fe78f61f8ad39827). ΠΠΎΡΠΎΠΊΠΈ Π½Π΅ ΡΠΈΠΏΠ° Π²ΠΈΠ΄Π΅ΠΎ/Π°ΡΠ΄ΠΈΠΎ/ΡΡΠ±ΡΠΈΡΡΡ ΠΏΠΎΠΌΠ΅ΡΠ°Π΅ΠΌ, ΡΡΠΎΠ±Ρ ΠΈΡ
ΠΏΠΎΡΠΎΠΌ ΠΏΡΠΎΠΏΡΡΡΠΈΡΡ.
+
+```c
+for (i = 0; i < input_format_context->nb_streams; i++) {
+ AVStream *out_stream;
+ AVStream *in_stream = input_format_context->streams[i];
+ AVCodecParameters *in_codecpar = in_stream->codecpar;
+ if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
+ in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
+ in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
+ streams_list[i] = -1;
+ continue;
+ }
+ streams_list[i] = stream_index++;
+ out_stream = avformat_new_stream(output_format_context, NULL);
+ if (!out_stream) {
+ fprintf(stderr, "Failed allocating output stream\n");
+ ret = AVERROR_UNKNOWN;
+ goto end;
+ }
+ ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
+ if (ret < 0) {
+ fprintf(stderr, "Failed to copy codec parameters\n");
+ goto end;
+ }
+}
+```
+
+Π’Π΅ΠΏΠ΅ΡΡ ΡΠΎΠ·Π΄Π°ΡΠΌ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ».
+
+```c
+if (!(output_format_context->oformat->flags & AVFMT_NOFILE)) {
+ ret = avio_open(&output_format_context->pb, out_filename, AVIO_FLAG_WRITE);
+ if (ret < 0) {
+ fprintf(stderr, "Could not open output file '%s'", out_filename);
+ goto end;
+ }
+}
+
+ret = avformat_write_header(output_format_context, NULL);
+if (ret < 0) {
+ fprintf(stderr, "Error occurred when opening output file\n");
+ goto end;
+}
+```
+
+ΠΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΏΠΎΡΠΎΠΊΠΈ ΠΏΠ°ΠΊΠ΅Ρ Π·Π° ΠΏΠ°ΠΊΠ΅ΡΠΎΠΌ ΠΈΠ· Π²Ρ
ΠΎΠ΄Π° Π² Π²ΡΡ
ΠΎΠ΄. Π ΡΠΈΠΊΠ»Π΅, ΠΏΠΎΠΊΠ° Π΅ΡΡΡ ΠΏΠ°ΠΊΠ΅ΡΡ (`av_read_frame`): ΠΏΠ΅ΡΠ΅ΡΡΠΈΡΡΠ²Π°Π΅ΠΌ PTS/DTS ΠΈ ΠΏΠΈΡΠ΅ΠΌ (`av_interleaved_write_frame`) Π² Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ.
+
+```c
+while (1) {
+ AVStream *in_stream, *out_stream;
+ ret = av_read_frame(input_format_context, &packet);
+ if (ret < 0)
+ break;
+ in_stream = input_format_context->streams[packet.stream_index];
+ if (packet.stream_index >= number_of_streams || streams_list[packet.stream_index] < 0) {
+ av_packet_unref(&packet);
+ continue;
+ }
+ packet.stream_index = streams_list[packet.stream_index];
+ out_stream = output_format_context->streams[packet.stream_index];
+ /* ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΏΠ°ΠΊΠ΅Ρ */
+ packet.pts = av_rescale_q_rnd(packet.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+ packet.dts = av_rescale_q_rnd(packet.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
+ packet.duration = av_rescale_q(packet.duration, in_stream->time_base, out_stream->time_base);
+ // https://ffmpeg.org/doxygen/trunk/structAVPacket.html#ab5793d8195cf4789dfb3913b7a693903
+ packet.pos = -1;
+
+ // https://ffmpeg.org/doxygen/trunk/group__lavf__encoding.html#ga37352ed2c63493c38219d935e71db6c1
+ ret = av_interleaved_write_frame(output_format_context, &packet);
+ if (ret < 0) {
+ fprintf(stderr, "Error muxing packet\n");
+ break;
+ }
+ av_packet_unref(&packet);
+}
+```
+
+Π§ΡΠΎΠ±Ρ Π·Π°Π²Π΅ΡΡΠΈΡΡ, Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Β«Ρ
Π²ΠΎΡΡΒ» ΠΏΠΎΡΠΎΠΊΠ° Π² ΡΠ°ΠΉΠ» ΡΡΠ½ΠΊΡΠΈΠ΅ΠΉ [av_write_trailer](https://ffmpeg.org/doxygen/trunk/group__lavf__encoding.html#ga7f14007e7dc8f481f054b21614dfec13).
+
+```c
+av_write_trailer(output_format_context);
+```
+
+Π’Π΅ΠΏΠ΅ΡΡ ΠΏΡΠΎΡΠ΅ΡΡΠΈΡΡΠ΅ΠΌ β ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠ΅ΡΡ: ΡΠΌΠ΅Π½Π° ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ° ΠΈΠ· MP4 Π² MPEG-TS. ΠΠΎ ΡΡΡΠΈ, ΠΏΠΎΠ²ΡΠΎΡΡΠ΅ΠΌ `ffmpeg input.mp4 -c copy output.ts` Π½Π° libav.
+
+```bash
+make run_remuxing_ts
+```
+
+Π Π°Π±ΠΎΡΠ°Π΅Ρ!!! ΠΠ΅ Π²Π΅ΡΠΈΡΠ΅? Π ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎ β ΠΏΡΠΎΠ²Π΅ΡΠΈΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ `ffprobe`:
+
+```bash
+ffprobe -i remuxed_small_bunny_1080p_60fps.ts
+
+Input #0, mpegts, from 'remuxed_small_bunny_1080p_60fps.ts':
+ Duration: 00:00:10.03, start: 0.000000, bitrate: 2751 kb/s
+ Program 1
+ Metadata:
+ service_name : Service01
+ service_provider: FFmpeg
+ Stream #0:0[0x100]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(progressive), 1920x1080 [SAR 1:1 DAR 16:9], 60 fps, 60 tbr, 90k tbn, 120 tbc
+ Stream #0:1[0x101]: Audio: ac3 ([129][0][0][0] / 0x0081), 48000 Hz, 5.1(side), fltp, 320 kb/s
+```
+
+ΠΡΠΎΠ³ Π½Π° ΠΊΠ°ΡΡΠΈΠ½ΠΊΠ΅: Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΡ ΠΊ [ΠΈΠ΄Π΅Π΅ Π°ΡΡ
ΠΈΡΠ΅ΠΊΡΡΡΡ libav](https://github.com/leandromoreira/ffmpeg-libav-tutorial#ffmpeg-libav-architecture), Π½ΠΎ ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°Π΅ΠΌ, ΡΡΠΎ ΠΊΠΎΠ΄Π΅ΠΊ-ΡΠ»ΠΎΠΉ ΠΌΡ ΠΏΡΠΎΠΏΡΡΡΠΈΠ»ΠΈ.
+
+
+
+ΠΠ΅ΡΠ΅Π΄ Π·Π°ΠΊΡΡΡΠΈΠ΅ΠΌ Π³Π»Π°Π²Ρ β Π²Π°ΠΆΠ½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ: **ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ ΠΎΠΏΡΠΈΠΈ ΠΌΡΠ»ΡΡΠΈΠΏΠ»Π΅ΠΊΡΠΎΡΡ**. ΠΠΎΠΏΡΡΡΠΈΠΌ, Ρ
ΠΎΡΠΈΠΌ Π²ΡΠ΄Π°Π²Π°ΡΡ [MPEG-DASH](https://developer.mozilla.org/en-US/docs/Web/Apps/Fundamentals/Audio_and_video_delivery/Setting_up_adaptive_streaming_media_sources#MPEG-DASH_Encoding); Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ Π½ΡΠΆΠ΅Π½ [fragmented mp4](https://stackoverflow.com/a/35180327) (`fmp4`) Π²ΠΌΠ΅ΡΡΠΎ MPEG-TS ΠΈΠ»ΠΈ ΠΎΠ±ΡΡΠ½ΠΎΠ³ΠΎ MP4.
+
+Π§Π΅ΡΠ΅Π· CLI ΡΡΠΎ ΠΏΡΠΎΡΡΠΎ:
+
+```
+ffmpeg -i non_fragmented.mp4 -movflags frag_keyframe+empty_moov+default_base_moof fragmented.mp4
+```
+
+ΠΠΎΡΡΠΈ ΡΡΠΎΠ»Ρ ΠΆΠ΅ ΠΏΡΠΎΡΡΠΎ β Π½Π° libav: ΠΏΠ΅ΡΠ΅Π΄Π°ΡΠΌ ΠΎΠΏΡΠΈΠΈ ΠΏΡΠΈ Π·Π°ΠΏΠΈΡΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° (Π΄ΠΎ ΠΊΠΎΠΏΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΠ°ΠΊΠ΅ΡΠΎΠ²).
+
+```c
+AVDictionary* opts = NULL;
+av_dict_set(&opts, "movflags", "frag_keyframe+empty_moov+default_base_moof", 0);
+ret = avformat_write_header(output_format_context, &opts);
+```
+
+Π’Π΅ΠΏΠ΅ΡΡ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ fragmented mp4:
+
+```bash
+make run_remuxing_fragmented_mp4
+```
+
+Π§ΡΠΎΠ±Ρ ΡΠ±Π΅Π΄ΠΈΡΡΡΡ, ΡΡΠΎ Ρ Π½Π΅ Π²ΡΡ, ΠΌΠΎΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΡΠΈΠΊΠ°ΡΠ½ΡΠΌΠΈ ΡΡΠ»Π·Π°ΠΌΠΈ [gpac/mp4box.js](http://download.tsi.telecom-paristech.fr/gpac/mp4box.js/filereader.html) ΠΈΠ»ΠΈ [http://mp4parser.com/](http://mp4parser.com/). Π‘Π½Π°ΡΠ°Π»Π° Π·Π°Π³ΡΡΠ·ΠΈΡΠ΅ Β«ΠΎΠ±ΡΡΠ½ΡΠΉΒ» mp4.
+
+
+
+ΠΠΈΠ΄ΠΈΠΌ ΠΎΠ΄ΠΈΠ½ `mdat` Π°ΡΠΎΠΌ/Π±ΠΎΠΊΡ β **Π·Π΄Π΅ΡΡ Π»Π΅ΠΆΠ°Ρ Π²ΠΈΠ΄Π΅ΠΎ/Π°ΡΠ΄ΠΈΠΎ ΠΊΠ°Π΄ΡΡ**. Π’Π΅ΠΏΠ΅ΡΡ Π·Π°Π³ΡΡΠ·ΠΈΡΠ΅ fragmented mp4 ΠΈ ΡΠ²ΠΈΠ΄ΠΈΡΠ΅, ΡΡΠΎ `mdat` ΡΠ°Π·Π±ΠΈΡ Π½Π° ΡΠ°ΡΡΠΈ.
+
+
+
+## ΠΠ»Π°Π²Π° 3 β ΡΡΠ°Π½ΡΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
+
+> #### TLDR; ΠΏΠΎΠΊΠ°ΠΆΠΈ [ΠΊΠΎΠ΄](/3_transcoding.c) ΠΈ ΠΊΠ°ΠΊ Π΅Π³ΠΎ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ.
+>
+> ```bash
+> $ make run_transcoding
+> ```
+>
+> ΠΠ΅ΡΠ°Π»ΠΈ ΡΠ°ΡΡΠΈΡΠ½ΠΎ ΠΎΠΏΡΡΡΠΈΠΌ β [ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ Π½Π° GitHub](/3_transcoding.c).
+
+Π ΡΡΠΎΠΉ Π³Π»Π°Π²Π΅ ΡΠΎΠ·Π΄Π°Π΄ΠΈΠΌ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΠΈΡΡΠΈΡΠ½ΡΠΉ ΡΡΠ°Π½ΡΠΊΠΎΠ΄Π΅Ρ Π½Π° C, ΠΊΠΎΡΠΎΡΡΠΉ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΡΠ΅Ρ Π²ΠΈΠ΄Π΅ΠΎ ΠΈΠ· H264 Π² H265, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ **FFmpeg/libav**: [libavcodec](https://ffmpeg.org/libavcodec.html), libavformat ΠΈ libavutil.
+
+
+
+> *ΠΠΎΡΠΎΡΠΊΠΈΠΉ ΠΏΠΎΠ²ΡΠΎΡ:* [**AVFormatContext**](https://www.ffmpeg.org/doxygen/trunk/structAVFormatContext.html) β Π°Π±ΡΡΡΠ°ΠΊΡΠΈΡ ΡΠΎΡΠΌΠ°ΡΠ° (ΠΊΠΎΠ½ΡΠ΅ΠΉΠ½Π΅ΡΠ°: MKV, MP4, WebM, TS). [**AVStream**](https://www.ffmpeg.org/doxygen/trunk/structAVStream.html) β ΡΠΈΠΏ Π΄Π°Π½Π½ΡΡ
Π² ΡΠΎΡΠΌΠ°ΡΠ΅ (audio, video, subtitle, metadata). [**AVPacket**](https://www.ffmpeg.org/doxygen/trunk/structAVPacket.html) β ΡΡΠ°Π³ΠΌΠ΅Π½Ρ ΡΠΆΠ°ΡΡΡ
Π΄Π°Π½Π½ΡΡ
ΠΈΠ· `AVStream`, ΠΊΠΎΡΠΎΡΡΠΉ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΡΠ΅ΡΡΡ [**AVCodec**](https://www.ffmpeg.org/doxygen/trunk/structAVCodec.html) (av1, h264, vp9, hevc) Π² ΡΡΡΡΠ΅ [**AVFrame**](https://www.ffmpeg.org/doxygen/trunk/structAVFrame.html).
+
+### Transmuxing
+
+ΠΠ°ΡΠ½ΡΠΌ Ρ ΠΏΡΠΎΡΡΠΎΠ³ΠΎ ΡΠ΅ΠΌΡΠΊΡΠ°, Π·Π°ΡΠ΅ΠΌ ΠΏΡΠΎΡΡΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΠΌ Π΅Π³ΠΎ. ΠΠ΅ΡΠ²ΡΠΉ ΡΠ°Π³ β **Π·Π°Π³ΡΡΠ·ΠΊΠ° Π²Ρ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°**.
+
+```c
+// ΠΡΠ΄Π΅Π»ΡΠ΅ΠΌ AVFormatContext
+avfc = avformat_alloc_context();
+// ΠΡΠΊΡΡΠ²Π°Π΅ΠΌ Π²Ρ
ΠΎΠ΄ ΠΈ ΡΠΈΡΠ°Π΅ΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ.
+avformat_open_input(avfc, in_filename, NULL, NULL);
+// Π§ΠΈΡΠ°Π΅ΠΌ ΠΏΠ°ΠΊΠ΅ΡΡ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΏΠΎΡΠΎΠΊΠ°Ρ
.
+avformat_find_stream_info(avfc, NULL);
+```
+
+ΠΠ°Π»Π΅Π΅ Π³ΠΎΡΠΎΠ²ΠΈΠΌ Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ: `AVFormatContext` Π΄Π°ΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊΠΎ Π²ΡΠ΅ΠΌ `AVStream`. ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π½Π°Ρ
ΠΎΠ΄ΠΈΠΌ `AVCodec`, ΡΠΎΠ·Π΄Π°ΡΠΌ `AVCodecContext` ΠΈ ΠΎΡΠΊΡΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ΄Π΅ΠΊ β ΠΏΠΎΡΠ»Π΅ ΡΡΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ.
+
+> [**AVCodecContext**](https://www.ffmpeg.org/doxygen/trunk/structAVCodecContext.html) Ρ
ΡΠ°Π½ΠΈΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ ΠΌΠ΅Π΄ΠΈΠ°: Π±ΠΈΡΡΠ΅ΠΉΡ, fps, sample rate, channels, Π²ΡΡΠΎΡΡ/ΡΠΈΡΠΈΠ½Ρ ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠ΅ Π΄ΡΡΠ³ΠΎΠ΅.
+
+```c
+for (int i = 0; i < avfc->nb_streams; i++)
+{
+ AVStream *avs = avfc->streams[i];
+ AVCodec *avc = avcodec_find_decoder(avs->codecpar->codec_id);
+ AVCodecContext *avcc = avcodec_alloc_context3(*avc);
+ avcodec_parameters_to_context(*avcc, avs->codecpar);
+ avcodec_open2(*avcc, *avc, NULL);
+}
+```
+
+ΠΡΠΆΠ½ΠΎ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΈΡΡ ΠΈ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ» Π΄Π»Ρ ΡΠ΅ΠΌΠ°ΠΊΡΠ°: **Π²ΡΠ΄Π΅Π»ΡΠ΅ΠΌ ΠΏΠ°ΠΌΡΡΡ** ΠΏΠΎΠ΄ `AVFormatContext` Π΄Π»Ρ Π²ΡΡ
ΠΎΠ΄Π°. Π‘ΠΎΠ·Π΄Π°ΡΠΌ **ΠΊΠ°ΠΆΠ΄ΡΠΉ ΠΏΠΎΡΠΎΠΊ** Π² Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΌ ΡΠΎΡΠΌΠ°ΡΠ΅. Π§ΡΠΎΠ±Ρ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ ΡΠΏΠ°ΠΊΠΎΠ²Π°Π»ΠΎΡΡ, **ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΊΠΎΠ΄Π΅ΠΊΠ°** ΠΈΠ· Π΄Π΅ΠΊΠΎΠ΄Π΅ΡΠ°.
+
+Π‘ΡΠ°Π²ΠΈΠΌ ΡΠ»Π°Π³ `AV_CODEC_FLAG_GLOBAL_HEADER`, Π³ΠΎΠ²ΠΎΡΡ ΡΠ½ΠΊΠΎΠ΄Π΅ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΡΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ, Π·Π°ΡΠ΅ΠΌ ΠΎΡΠΊΡΡΠ²Π°Π΅ΠΌ **ΡΠ°ΠΉΠ» Π½Π° Π·Π°ΠΏΠΈΡΡ** ΠΈ ΡΠΎΡ
ΡΠ°Π½ΡΠ΅ΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ.
+
+```c
+avformat_alloc_output_context2(&encoder_avfc, NULL, NULL, out_filename);
+
+AVStream *avs = avformat_new_stream(encoder_avfc, NULL);
+avcodec_parameters_copy(avs->codecpar, decoder_avs->codecpar);
+
+if (encoder_avfc->oformat->flags & AVFMT_GLOBALHEADER)
+ encoder_avfc->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
+
+avio_open(&encoder_avfc->pb, encoder->filename, AVIO_FLAG_WRITE);
+avformat_write_header(encoder->avfc, &muxer_opts);
+```
+
+ΠΡ Π±Π΅ΡΡΠΌ `AVPacket` ΠΈΠ· Π΄Π΅ΠΊΠΎΠ΄Π΅ΡΠ°, ΠΊΠΎΡΡΠ΅ΠΊΡΠΈΡΡΠ΅ΠΌ ΡΠ°ΠΉΠΌΡΡΠ°ΠΌΠΏΡ ΠΈ Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΠΌ Π΅Π³ΠΎ Π² Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ». ΠΠ΅ΡΠΌΠΎΡΡΡ Π½Π° Π½Π°Π·Π²Π°Π½ΠΈΠ΅ `av_interleaved_write_frame`, Π·Π°ΠΏΠΈΡΡΠ²Π°Π΅ΡΡΡ ΠΏΠ°ΠΊΠ΅Ρ. ΠΠ°Π²Π΅ΡΡΠ°Π΅ΠΌ ΡΠ΅ΠΌΠ°ΠΊΡ Π·Π°ΠΏΠΈΡΡΡ ΡΡΠ΅ΠΉΠ»Π΅ΡΠ°.
+
+```c
+AVFrame *input_frame = av_frame_alloc();
+AVPacket *input_packet = av_packet_alloc();
+
+while (av_read_frame(decoder_avfc, input_packet) >= 0)
+{
+ av_packet_rescale_ts(input_packet, decoder_video_avs->time_base, encoder_video_avs->time_base);
+ av_interleaved_write_frame(*avfc, input_packet) < 0));
+}
+
+av_write_trailer(encoder_avfc);
+```
+
+### Transcoding
+
+Π ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΌ ΡΠ°Π·Π΄Π΅Π»Π΅ Π±ΡΠ» ΠΏΡΠΎΡΡΠΎΠΉ ΡΠ΅ΠΌΡΠΊΡΠ΅Ρ. Π’Π΅ΠΏΠ΅ΡΡ Π΄ΠΎΠ±Π°Π²ΠΈΠΌ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ β Π½Π°ΡΡΠΈΠΌ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΡ ΡΡΠ°Π½ΡΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ Π²ΠΈΠ΄Π΅ΠΎ `h264` β `h265`.
+
+ΠΠΎΡΠ»Π΅ ΠΏΠΎΠ΄Π³ΠΎΡΠΎΠ²ΠΊΠΈ Π΄Π΅ΠΊΠΎΠ΄Π΅ΡΠ°, Π½ΠΎ Π΄ΠΎ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΌΠ΅Π΄ΠΈΠ°ΡΠ°ΠΉΠ»Π° β Π½Π°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ ΡΠ½ΠΊΠΎΠ΄Π΅Ρ.
+
+* Π‘ΠΎΠ·Π΄Π°ΡΠΌ Π²ΠΈΠ΄Π΅ΠΎ-`AVStream` Π² ΡΠ½ΠΊΠΎΠ΄Π΅ΡΠ΅, [`avformat_new_stream`](https://www.ffmpeg.org/doxygen/trunk/group__lavf__core.html#gadcb0fd3e507d9b58fe78f61f8ad39827)
+* ΠΠ΅ΡΡΠΌ `AVCodec` ΠΏΠΎ ΠΈΠΌΠ΅Π½ΠΈ `libx265`, [`avcodec_find_encoder_by_name`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__encoding.html#gaa614ffc38511c104bdff4a3afa086d37)
+* Π‘ΠΎΠ·Π΄Π°ΡΠΌ `AVCodecContext` Π΄Π»Ρ ΡΡΠΎΠ³ΠΎ ΠΊΠΎΠ΄Π΅ΠΊΠ°, [`avcodec_alloc_context3`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__core.html#gae80afec6f26df6607eaacf39b561c315)
+* ΠΠ°ΡΡΡΠ°ΠΈΠ²Π°Π΅ΠΌ Π±Π°Π·ΠΎΠ²ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΠ΅ΡΡΠΈΠΈ
+* ΠΡΠΊΡΡΠ²Π°Π΅ΠΌ ΠΊΠΎΠ΄Π΅ΠΊ ΠΈ ΠΊΠΎΠΏΠΈΡΡΠ΅ΠΌ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΈΠ· ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° Π² ΠΏΠΎΡΠΎΠΊ: [`avcodec_open2`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__core.html#ga11f785a188d7d9df71621001465b0f1d), [`avcodec_parameters_from_context`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__core.html#ga0c7058f764778615e7978a1821ab3cfe)
+
+```c
+AVRational input_framerate = av_guess_frame_rate(decoder_avfc, decoder_video_avs, NULL);
+AVStream *video_avs = avformat_new_stream(encoder_avfc, NULL);
+
+char *codec_name = "libx265";
+char *codec_priv_key = "x265-params";
+// ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Π²Π½ΡΡΡΠ΅Π½Π½ΠΈΠ΅ ΠΎΠΏΡΠΈΠΈ x265:
+// ΠΎΡΠΊΠ»ΡΡΠ°Π΅ΠΌ Π΄Π΅ΡΠ΅ΠΊΡΠΈΡ ΡΠΌΠ΅Π½Ρ ΡΡΠ΅Π½Ρ ΠΈ ΡΠΈΠΊΡΠΈΡΡΠ΅ΠΌ
+// GOP Π½Π° 60 ΠΊΠ°Π΄ΡΠΎΠ².
+char *codec_priv_value = "keyint=60:min-keyint=60:scenecut=0";
+
+AVCodec *video_avc = avcodec_find_encoder_by_name(codec_name);
+AVCodecContext *video_avcc = avcodec_alloc_context3(video_avc);
+// ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΡΠ½ΠΊΠΎΠ΄Π΅ΡΠ°
+av_opt_set(sc->video_avcc->priv_data, codec_priv_key, codec_priv_value, 0);
+video_avcc->height = decoder_ctx->height;
+video_avcc->width = decoder_ctx->width;
+video_avcc->pix_fmt = video_avc->pix_fmts[0];
+// ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ Π±ΠΈΡΡΠ΅ΠΉΡΠ°
+video_avcc->bit_rate = 2 * 1000 * 1000;
+video_avcc->rc_buffer_size = 4 * 1000 * 1000;
+video_avcc->rc_max_rate = 2 * 1000 * 1000;
+video_avcc->rc_min_rate = 2.5 * 1000 * 1000;
+// time base
+video_avcc->time_base = av_inv_q(input_framerate);
+video_avs->time_base = sc->video_avcc->time_base;
+
+avcodec_open2(sc->video_avcc, sc->video_avc, NULL);
+avcodec_parameters_from_context(sc->video_avs->codecpar, sc->video_avcc);
+```
+
+Π Π°ΡΡΠΈΡΠΈΠΌ ΡΠΈΠΊΠ» Π΄Π΅ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π΄Π»Ρ Π²ΠΈΠ΄Π΅ΠΎΡΡΠ°Π½ΡΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°Π½ΠΈΡ:
+
+* ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ Π²Ρ
ΠΎΠ΄Π½ΠΎΠΉ `AVPacket` Π² Π΄Π΅ΠΊΠΎΠ΄Π΅Ρ β [`avcodec_send_packet`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga58bc4bf1e0ac59e27362597e467efff3)
+* ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΡΡΠΎΠΉ `AVFrame` β [`avcodec_receive_frame`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c)
+* ΠΠ°ΡΠΈΠ½Π°Π΅ΠΌ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΡΡΠΎΠΉ ΠΊΠ°Π΄Ρ,
+* ΠΡΠΏΡΠ°Π²Π»ΡΠ΅ΠΌ ΠΊΠ°Π΄Ρ β [`avcodec_send_frame`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga9395cb802a5febf1f00df31497779169)
+* ΠΠΎΠ»ΡΡΠ°Π΅ΠΌ ΡΠΆΠ°ΡΡΠΉ `AVPacket` β [`avcodec_receive_packet`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__decoding.html#ga5b8eff59cf259747cf0b31563e38ded6)
+* ΠΡΡΡΠ°Π²Π»ΡΠ΅ΠΌ ΡΠ°ΠΉΠΌΡΡΠ°ΠΌΠΏΡ β [`av_packet_rescale_ts`](https://www.ffmpeg.org/doxygen/trunk/group__lavc__packet.html#gae5c86e4d93f6e7aa62ef2c60763ea67e)
+* ΠΠΈΡΠ΅ΠΌ Π² Π²ΡΡ
ΠΎΠ΄Π½ΠΎΠΉ ΡΠ°ΠΉΠ» β [`av_interleaved_write_frame`](https://www.ffmpeg.org/doxygen/trunk/group__lavf__encoding.html#ga37352ed2c63493c38219d935e71db6c1)
+
+```c
+AVFrame *input_frame = av_frame_alloc();
+AVPacket *input_packet = av_packet_alloc();
+
+while (av_read_frame(decoder_avfc, input_packet) >= 0)
+{
+ int response = avcodec_send_packet(decoder_video_avcc, input_packet);
+ while (response >= 0) {
+ response = avcodec_receive_frame(decoder_video_avcc, input_frame);
+ if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
+ break;
+ } else if (response < 0) {
+ return response;
+ }
+ if (response >= 0) {
+ encode(encoder_avfc, decoder_video_avs, encoder_video_avs, decoder_video_avcc, input_packet->stream_index);
+ }
+ av_frame_unref(input_frame);
+ }
+ av_packet_unref(input_packet);
+}
+av_write_trailer(encoder_avfc);
+
+// ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΠ°Ρ ΡΡΠ½ΠΊΡΠΈΡ
+int encode(AVFormatContext *avfc, AVStream *dec_video_avs, AVStream *enc_video_avs, AVCodecContext video_avcc int index) {
+ AVPacket *output_packet = av_packet_alloc();
+ int response = avcodec_send_frame(video_avcc, input_frame);
+
+ while (response >= 0) {
+ response = avcodec_receive_packet(video_avcc, output_packet);
+ if (response == AVERROR(EAGAIN) || response == AVERROR_EOF) {
+ break;
+ } else if (response < 0) {
+ return -1;
+ }
+
+ output_packet->stream_index = index;
+ output_packet->duration = enc_video_avs->time_base.den / enc_video_avs->time_base.num / dec_video_avs->avg_frame_rate.num * dec_video_avs->avg_frame_rate.den;
+
+ av_packet_rescale_ts(output_packet, dec_video_avs->time_base, enc_video_avs->time_base);
+ response = av_interleaved_write_frame(avfc, output_packet);
+ }
+ av_packet_unref(output_packet);
+ av_packet_free(&output_packet);
+ return 0;
+}
+```
+
+ΠΡ ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°Π»ΠΈ Π²ΠΈΠ΄Π΅ΠΎΠΏΠΎΡΠΎΠΊ `h264` β `h265`. ΠΠ°ΠΊ ΠΈ ΠΎΠΆΠΈΠ΄Π°Π»ΠΎΡΡ, `h265`-Π²Π΅ΡΡΠΈΡ ΠΌΠ΅Π½ΡΡΠ΅ `h264`. ΠΡΠΈ ΡΡΠΎΠΌ [Π½Π°ΠΏΠΈΡΠ°Π½Π½Π°Ρ ΠΏΡΠΎΠ³ΡΠ°ΠΌΠΌΠ°](/3_transcoding.c) ΡΠΌΠ΅Π΅Ρ ΠΏΡΠΎΠ²ΠΎΠ΄ΠΈΡΡ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΈ:
+
+```c
+
+ /*
+ * H264 -> H265
+ * Audio -> remuxed (Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ)
+ * MP4 - MP4
+ */
+ StreamingParams sp = {0};
+ sp.copy_audio = 1;
+ sp.copy_video = 0;
+ sp.video_codec = "libx265";
+ sp.codec_priv_key = "x265-params";
+ sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0";
+
+ /*
+ * H264 -> H264 (ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ GOP)
+ * Audio -> remuxed (Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ)
+ * MP4 - MP4
+ */
+ StreamingParams sp = {0};
+ sp.copy_audio = 1;
+ sp.copy_video = 0;
+ sp.video_codec = "libx264";
+ sp.codec_priv_key = "x264-params";
+ sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
+
+ /*
+ * H264 -> H264 (ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ GOP)
+ * Audio -> remuxed (Π±Π΅Π· ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΠΉ)
+ * MP4 - fragmented MP4
+ */
+ StreamingParams sp = {0};
+ sp.copy_audio = 1;
+ sp.copy_video = 0;
+ sp.video_codec = "libx264";
+ sp.codec_priv_key = "x264-params";
+ sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
+ sp.muxer_opt_key = "movflags";
+ sp.muxer_opt_value = "frag_keyframe+empty_moov+delay_moov+default_base_moof";
+
+ /*
+ * H264 -> H264 (ΡΠΈΠΊΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ GOP)
+ * Audio -> AAC
+ * MP4 - MPEG-TS
+ */
+ StreamingParams sp = {0};
+ sp.copy_audio = 0;
+ sp.copy_video = 0;
+ sp.video_codec = "libx264";
+ sp.codec_priv_key = "x264-params";
+ sp.codec_priv_value = "keyint=60:min-keyint=60:scenecut=0:force-cfr=1";
+ sp.audio_codec = "aac";
+ sp.output_extension = ".ts";
+
+ /* Π ΡΠ°Π±ΠΎΡΠ΅ :P -> Π½Π΅ ΠΈΠ³ΡΠ°Π΅Ρ Π²ΠΎ VLC, ΠΈΡΠΎΠ³ΠΎΠ²ΡΠΉ Π±ΠΈΡΡΠ΅ΠΉΡ ΠΎΠ³ΡΠΎΠΌΠ΅Π½
+ * H264 -> VP9
+ * Audio -> Vorbis
+ * MP4 - WebM
+ */
+ //StreamingParams sp = {0};
+ //sp.copy_audio = 0;
+ //sp.copy_video = 0;
+ //sp.video_codec = "libvpx-vp9";
+ //sp.audio_codec = "libvorbis";
+ //sp.output_extension = ".webm";
+
+```
+
+> Π§Π΅ΡΡΠ½ΠΎ Π³ΠΎΠ²ΠΎΡΡ, ΡΡΠΎ ΠΎΠΊΠ°Π·Π°Π»ΠΎΡΡ [ΡΠ»ΠΎΠΆΠ½Π΅Π΅, ΡΠ΅ΠΌ Ρ Π΄ΡΠΌΠ°Π»](https://github.com/leandromoreira/ffmpeg-libav-tutorial/pull/54): ΠΏΡΠΈΡΠ»ΠΎΡΡ ΠΊΠΎΠΏΠ°ΡΡ [ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ FFmpeg CLI](https://github.com/leandromoreira/ffmpeg-libav-tutorial/pull/54#issuecomment-570746749) ΠΈ ΠΌΠ½ΠΎΠ³ΠΎ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°ΡΡ. ΠΠΎΡ
ΠΎΠΆΠ΅, Ρ Π΅ΡΡ ΡΡΠΎ-ΡΠΎ ΡΠΏΡΡΠΊΠ°Ρ: ΠΏΡΠΈΡΠ»ΠΎΡΡ Π²ΠΊΠ»ΡΡΠΈΡΡ `force-cfr`, ΡΡΠΎΠ±Ρ `h264` Π·Π°ΡΠ°Π±ΠΎΡΠ°Π», ΠΈ Ρ Π²ΡΡ Π΅ΡΡ Π²ΠΈΠΆΡ ΠΏΡΠ΅Π΄ΡΠΏΡΠ΅ΠΆΠ΄Π΅Π½ΠΈΡ Π²ΡΠΎΠ΄Π΅ `warning messages (forced frame type (5) at 80 was changed to frame type (3))`.
diff --git a/README.md b/README.md
index 8b88cb5..7885879 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
[πͺπΈ](/README-es.md "Spanish")
[π»π³](/README-vn.md "Vietnamese")
[π§π·](/README-pt.md "Portuguese")
+[π·πΊ](/README-ru.md "Russian")
[](https://img.shields.io/badge/license-BSD--3--Clause-blue.svg)