-
Notifications
You must be signed in to change notification settings - Fork 19
/
wednesday_01.html
733 lines (606 loc) · 31 KB
/
wednesday_01.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
<!DOCTYPE html>
<html>
<head>
<title>Digital Summer School 2024: WED01</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<link rel="stylesheet" href="../style.css"> </head>
<body>
<textarea id="source">
class: center, middle, titlepage
### WED01: *FFmpeg video encoding, filters and QC Tools*
---
class: contentpage
### **Agenda**
FFmpeg video encoding intro
> 1.1 Reading FFmpeg logs
> 1.2 Lossless vs Lossy compression
> 1.3 Bit rate
> 1.4 Bit-depth
> 1.5 Chroma subsampling and colourspaces
> 1.6 Lossless encoding examples
> 1.7 Lossy encoding examples
> 1.8 Other interesting FFmpeg commands
FFmpeg filters
> 2.1 Video filters
> 2.2 Audio filters
> 2.3 Detection filters
> 2.4 Visualisation filters
> 2.5 Generative filters
QCTools
> 3.1 QCTools
> 3.2 AV Artifacts Atlas
---
class: contentpage
### **1 FFmpeg video encoding**
- FFmpeg will receive inputs from regular files, pipes, network streams and capture devices as long as they are specified in the command with the `-i` option
- Each input can contain any number of video, audio, subtitle, attachment and data streams, within reason
- The allowed number and types of streams output will be limited by the container format selected during encoding
- The `-map` option is critical to good mapping of streams from source to output without losing any precious stream data
- Calling streams in commands is simple using their stream order indices (0, 1, 2)
- Input files must always be listed first in the command order, and output files last - they cannot overlap
- FFmpeg allows for granular encoding choices that include encoding libraries, chroma subsampling, colourspace, bit-depth and bit rate
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-03 at 15.31.37.png" width="900">]
The FFmpeg team reverse engineer virtually every video and audio codec that exists. We're incredibly lucky to have an open-source tool like FFmpeg to help with codec obsolescence and encoding/decoding.
---
class: contentpage
### **1 FFmpeg video encoding**
- **libavutil**
A library containing functions for simplifying programming, including random number generators, data structures, mathematic routines, core multimedia utilities and much more.
- **libavcodec**
A library containing decoders and encoders for audio and video codecs
- **libavformat**
A library containing demuxers and muxers for multimedia container formats
- **libavdevice**
A library containing input and output devices for grabbing from and rendering to many common multimedia software frameworks
- **libavfilter**
A Library containing many media filters
- **libswscale**
A library performing highly optimised image scaling and colour space / pixel format conversion
- **libswresample**
A library preforming optimised audio resampling, rematrixing and sample format conversions
---
class: contentpage
### **1 FFmpeg video encoding**
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-08-30 at 14.20.38.png" width="460">]
```
Demuxing ---> Decoding __
---------------------------------------------|----------------------------------------------- |
Separates the streams from a container file | Reverses the process of encoding Filters
Extracts individual audiovisual data packets | Converts compressed data back to raw data Applied
|
Muxing <--- Encoding / Transcoding <--
---------------------------------------------|-----------------------------------------------
Combines multiple streams into one container | Converts raw/encoded streams into another format
Organises the data for synchronised playback | Can reduce stream size while maintaining quality
```
---
class: contentpage
### **1 FFmpeg video encoding**
FFmpeg commands generally consist of a '-flag' and a following value. They usually, but not always, are placed between the input file and the output file in the command line
```
flag / argument | Description
------------------------|----------------------------------------------------------------
-i filename.ext | indicates an input file
-c:v video_codec | select video codec
-c:a audio_codec | select audio codec
-map stream_choice | map specified streams to new file, or all using 0
-vf video_filter | select video filter
-af audio_filter | select audio filter
-filter_complex | selects filter for multiple inputs or outputs
-pix_fmt value | specifies colourspace and chroma subsampling preferred for output
-crf integer 0+ | numerical value for constant rate factor, 0 = best
-b:v [integer]k | numerical value sets the kilobit bitrate of the output file
-f integer | sets the frames per second of the output file
-aspect 4:3 | set the display aspect ratio
-colorspace value | tags video with the specific colourspace
```
To use FFmpeg command in a loop add the `-nostdin` flag at the beginning which blocks FFmpeg's default behaviour of receiving and acting on standard inputs:
```bash
ffmpeg -nostdin -i input.mov...
```
---
class: contentpage
### **1.1 Reading FFmpeg logs**
Don't panic if it fails! A log failure can be a bit scary but they are also really helpful.
The opening contents of a FFmpeg Log:
- Start with FFmpeg's version data and library data
- Input file's configuration reporting on all streams (count from 0+)
- Information about the output file
- Mapping plan is for the new file with stream numbering
The `demux - decoding - encoding - mux` order can be useful when reading the second section of logs:
- To find errors fast don't read from the top-down, read from the bottom-upward!
- Look for the word 'Error'. 'Warnings' generally don't break a process but indicate something isn't ideal
- The logs are colour coded and errors tend to show up in <font color="red">red</font>
- Check the syntax in your command first as errors are mostly caused by us (eg, missing '-i')
- Search for difficult error messages online or with LLMs - most problems have already been discussed on
sites like `Stackoverflow` or the `FFmpeg user forum` and solutions are waiting for you there!
Inspired by Ashley Blewer's presentation [Adventures in Reading FFmpeg Logs](https://youtu.be/15ZUnR3Nx1k)
---
class: contentpage
### **1.2 Lossless vs Lossy compression**
Lossless compression reduces the size of a video file without losing any information or quality. These algorithms preserve the original data in the video stream, and decompression returns a bit perfect copy of the original.
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-08-28 at 20.59.37.png" width="900">]
---
class: contentpage
### **1.2 Lossless vs Lossy compression**
Codecs that use lossy compression reduce the size of a file by discarding some of the redundant information from the original video stream. This process cannot be reversed and the original data cannot be retrieved.
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-08-28 at 21.00.09.png" width="900">]
---
class: contentpage
### **1.2 Lossless vs Lossy compression**
Group of Picture (GOP) length 1 can be used to determine that every file is a key frame and that no image data is discarded
```sh
ffmpeg -i input.mov -c:v libx264 -g 1 -c:a copy output.mp4
```
The file size will still using H.264 I frame compression using GOP=1, but you won't create any B/P frames so the size won't be as small as lossy compression. The default GOP in FFmpeg is 12.
To set a key frame interval for every 2 seconds of a 25 fps file:
```sh
ffmpeg -i input.mov -c:v libx264 -g 25 -sc_threshold 0 -c:a copy output.mp4
```
The GOP is set for every 25 frames (1 second). `-sc_threshold` ensures a new keyframe is set on a scene change.
<font color="orange">Practise:</font> Try the commands above, then use FFprobe to view the frame I,B and P frames:
```sh
ffprobe -v error -show_entries frame=pict_type -of default=nw=1 file.ext
```
---
class: contentpage
### **1.2 Lossless vs Lossy compression**
A number of video codecs can export lossless and lossy video, including:
```
Codecs | Comparison
---------- | -------------------------------------------------------------------------------------
H.264 AVC | Most widely used codec of group with good lossless and lossy options.
H.265 HEVC | 25-50% bit rate savings compared to H.264 with no visual quality loss. Requires x265
VP9 | 20-50% bit rate savings compared to H.264 with no visual quality loss. WebM streaming
AV1 | ~50% higher efficiency than H.264. Support HDR and WCG. Demanding encoding algorithm
```
If you build FFmpeg from source you may need to specify the encoding libraries using these flags:
```
H.264 libx264 --enable-libx264
H.265 libx265 --enable-gpl --enable-libx265
AV1 libaom-av1 --enable-libaom
VP9 libvpx-vp9 --enable-libvpx
VP9 10-bit --enable-vp9-highbitdepth
```
H.265 also requires that you have [x265](https://www.videolan.org/developers/x265.html) installed on your system. This application is from VideoLAN, makers of VLC.
To check if your FFmpeg installation includes support for these codecs you can check with this command:
```sh
ffmpeg -h encoder=libx264
```
The FFmpeg Wiki pages has [compilation guides](https://trac.ffmpeg.org/wiki/CompilationGuide), and individual pages for using [AV1](https://trac.ffmpeg.org/wiki/Encode/AV1), [H264](https://trac.ffmpeg.org/wiki/Encode/H.264), [H265]() and [VP9](https://trac.ffmpeg.org/wiki/Encode/VP9) codecs.
???
Algorithm | Reduces file size but not quality | Reduces size by discarding data
Reversibility | Compression can be reversed | Cannot be reversed
Compression ratio | Lower compression ratios | Higher compression ratios
Quality | Maintains original video quality | Reduces video quality, configurable
Use cases | Archives / where quality required | Access copies for web / other media
AV1 supports new video technologies like High Dynamic Range and Wide Color Gamut. The encoding algorithms can be more intensive in codecs like AV1 and really need new hardware like GPU and SoCs.
SoCs = Systm on a Chip, single piece of silicon that intgetrates computers CPU with the Graphics Processing Unit (GPU), mempry and other components.
We're going to use H.264 for our examples as these new codecs require additonal libraries installing at build to support them.
---
class: contentpage
### **1.2 Lossless vs Lossy compression**
Audio compression codecs are used like video to encode audio streams within a file.
```sh
ffmpeg -i input.wav -c:a aac -b:a 128k output.mka
```
In lossless video encoding examples for preservation you may see:
```sh
-c:a copy
```
This is to ensure that the lossless audio codec is unchanged between two lossless transcodes and though there are lossless audio codecs the size of the audio space saved is negligable compared to video.
```
Container | Accepted audio codecs (also FFmpeg supported)
-------------|-------------------------------------------------------------------------
MKV/MKA | Opus, Vorbis, MP2, MP3, LC-AAC, HE-AAC, WMAv1, WMAv2, AC3, E-AC3, TrueHD
MP4/M4A | Opus, MP2, MP3, LC-AAC, HE-AAC, AC3, E-AC3, TrueHD
FLV/F4V | MP3, LC-AAC, HE-AAC
3GP/3G2 | LC-AAC, HE-AAC
MPG | MP2, MP3
PS/TS Stream | MP2, MP3, LC-AAC, HE-AAC, AC3, TrueHD
M2TS | AC3, E-AC3, TrueHD
VOB | MP2, AC3
RMVB | Vorbis, HE-AAC
WebM & OGG | Vorbis, Opus
```
---
class: contentpage
### **1.2 Lossless vs Lossy compression**
Don't forget all the supported codecs can be found in `ffmpeg -codecs` help. There are some surprises in the list!
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-02 at 16.57.12.png" width="880">]
---
class: contentpage
### **1.3 Bit rates**
Bit rates control the quality of the video compression, which in turn alters the size of your file dramatically. You may have heard of Constant Bit Rate (CBR) and Variable Bit Rate (VBR). VBR generally gives better overall quality when file size and bit rate are not constrained.
FFmpeg Constant Rate Factor (CRF) gives you a consistent quality through your encoding for one pass. You can set it for all your transcodes and let the encoder make the adjustments needed between files:
```sh
ffmpeg -i input.mov -c:v libx264 -crf 23 output.mp4
```
The CRF scale for H264 is 0-51. 0 is best, 23 is default and 51 worst. The `sane` range is considered to be 17-28 for visually lossless encoding. The CRF method is considered best for archival formats, as you can guarantee the quality you want though not the file size. Not recommend for streaming.
There are presets and tuning options for this encoder to help fine tune your encoding results:
- `-preset` ultrafast, superfast, veryfast, faster, fast, medium (default), slow, slower, veryslow
- `-tune` film, animation, grain, stillimage, fastdecode, zerolatency
Slower presets allow for better compressions, and film which lowers deblocking for high quality movie content:
```sh
ffmpeg -i input.mov -c:v libx264 -preset slow -tune film -crf 23 output.mp4
```
---
class: contentpage
### **1.3 Bit rates**
If you want to target a specific file size for your bit rate encodings you can use Two-Pass you can specify it using `-b:v` for video bit rate and `b:a` for audio bit rate:
```sh
ffmpeg -y -i input.mov -c:v libx264 -b:v 2600k -pass 1 -an -f null /dev/null && \
ffmpeg -i input.mov -c:v libx264 -b:v 2600k -pass 2 -c:a aac -b:a 128k output.mp4
```
It's a two pass process and you need to export the first pass to a local file using `-f null /dev/null`. A file named `ffmpeg2pass-0.log.mbtree` will appear in your `pwd`. The second pass will read this file and calculate the required bit rate for the MP4 creation.
Lossless bit rates:
It's possible to use `-crf 0` for lossless H.264 High 4:4:4 Predictive encoding. For other H.264 lossless encoding use '-qp 0', FFmpeg's Quantization Parameter:
```sh
ffmpeg -i input.mov -c:v libx264 -preset veryslow -qp 0 output.mkv
```
<font color="orange">Practise:</font> Try creating a lossless H.264 file from a lossless source. Make and compare Framemd5 files for the two using the `-an` flag to just compare video streams. See what the size differences are.
---
class: contentpage
### **1.4 Bit depth (Quantisation)**
This is my lovely cat Eisenstein on the left in 8 bit greyscale. The image on the right is at 4-bit. The left 8-bit curve is smoother than the 4-bit curve where less bits are available to describe the tones of the analogue wave.
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/4_8_bit_eisey.png" width="1000">]
For a YUV file that would be 8-bit for Y luminance, and 8-bit each for U and V chrominance.
- 8-bit has 256 bits per sample (256 x 3 for colour video)
- 10-bit has 1024 bits per sample (1024 x 3)
- 12-bit has 4096 bits per sample (4096 x 3)
- 16-bit has 65536 bits per sample (65536 x 3)
???
4-bit has only 16 bits per samples, so 16 gradation changes. This is known as Quantisation
---
class: contentpage
### **1.5 Chroma subsampling and colourspaces**
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/chroma_subsampling.png" width="1000">]
- 4:4:4 is chrominance sampled at the same rate as luminance (no compression)
- 4:2:2 is chrominance sampled at half the rate of luminance (compression ~ 1/3 smaller than 4:4:4)
- 4:2:0 is chrominance sampled on alternate lines at half the rate of luminance (compression ~ half 4:4:4)
- 4:1:1 is chrominance sampled at a quarter the rate of the luminance (compression ~ half 4:4:4)
Chroma subsampling values described as four part ratios, eg 4:2:2:4 or 4:4:4:4, have additional chrominance stored in an alpha channel
---
class: contentpage
### **1.5 Chroma subsampling and colourspaces**
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-08-28 at 17.19.31.png" width="900">]
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-08-28 at 17.19.12.png" width="900">]
> > Source: [Wikimedia Commons](https://commons.wikimedia.org/wiki/File:Barn-yuv.png)
---
class: contentpage
### **1.5 Chroma subsampling and colourspaces**
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-08-28 at 17.24.09.png" width="620">]
---
class: contentpage
### **1.5 Chroma subsampling and colourspaces**
FFmpeg Pixel Format:
- `-pix_fmt yuv422p10le`: YUV colourspace, 4:2:2 chroma subsampling, 10 bit-depth, little endian
- `-vf format=yuv420p`: The video filter `format` can also apply Pixel Format options
The most common pix_fmts for video include:
- 8-bit 4:2:0 - yuv420p
- 8-bit 4:2:2 - yuv422p
- 10-bit 4:2:2 - yuv422p10le
- 10-bit 4:4:4 - yuv444p10le
You can view all available with the `-pix_fmts` advanced help option:
```sh
ffmpeg -pix_fmts
ffmpeg -i input.mkv -c:v v210 -pix_fmt yuv422p10le output.mov
ffmpeg -i input.mov -c:v libx264 -vf format=yuv420p output.mp4
```
<font color="orange">Practise:</font> View available Pixel Formats in FFmpeg and try re-encoding your file to a different pix_fmt.
---
class: contentpage
### **1.5 Chroma subsampling and colourspaces**
Embedding colorspace metadata and accepted FFmpeg arguments:
- `color_primaries` selecting the colour model to be tagged with.
smpte170m, bt470bg, bt709, bt2020
- `color_trc` marks the video with transfer characteristics (gamma).
smpte170m, gamma28, bt709, bt2020_10 / _12
- `colorspace` marks the video for having the given colourspace.
smpte170m, bt470bg, bt709, bt2020_cl/_ncl
Use video filter colormatrix to change colourspaces:
```sh
ffmpeg -i input.mov -vf colormatrix=bt709:bt2020 -c copy -map 0 output.mov
```
<font color="orange">Practise:</font> Try to change a colour space to another using the video filter colormatrix, or appending/amending existing colour metadata in some of your test files.
```sh
ffmpeg -i input.mov -color_primaries bt709 -color_trc bt709 -colorspace bt709 -c copy output.mov
```
---
class: contentpage
### **1.6 Lossless video encoding examples**
Encoding V210 MOV to FFV1 Matroska losslessly
```sh
ffmpeg
-i input.mov
-map 0 -dn
-c:v ffv1
-level 3
-g 1
-slicecrc 1
-slices 24
-pix_fmt yuv422p10le
-color_primaries bt709
-color_trc bt709
-colorspace bt709
-color_range 1
-c:a copy
-vf setfield=tff,setdar=4/3
output.mkv
```
View [FFV1 Cheat Sheet from FFmpeg](https://trac.ffmpeg.org/wiki/Encode/FFV1) for more guidance.
---
class: contentpage
### **1.6 Lossless video encoding examples**
Encoding FFV1 Matroska to V210 MOV losslessly
```sh
ffmpeg
-i input.mkv
-map 0
-movflags write_colr
-c:v v210
-pix_fmt yuv422p10le
-color_primaries bt709
-color_trc bt709
-colorspace bt709
-color_range mpeg
-metadata:s:v:0 "encoder=Uncompressed 10-bit 4:2:2"
-c:a copy
-vf setfield=tff,setdar=16/9
-f mov output.mov
```
You can add framemd5 commands to the above to create a FrameMD5 of the transcode simultaneously.
```sh
-f framemd5 -an output.framemd5
```
Useful blog from BAVC [Converting FFV1/MKV to v210/MOV](https://bavc.org/converting-ffv1mkv-v210mov/)
---
class: contentpage
### **1.7 Lossy video encoding examples**
FFV1 Matroska to ProRes 422HQ
```sh
ffmpeg -i
input.mkv
-map 0
-c:v prores_ks
-profile:v 3
-pix_fmt yuv422p10le
-c:a copy
-vendor ap10
-flags +ildct
-color_primaries bt709
-color_trc bt709
-colorspace bt709
-movflags +faststart
output.mov
```
These don't make Apple ProRes files that fully conform to the Apple specifications but the resulting file will play across video players.
---
class: contentpage
### **1.7 Lossy video encoding examples**
BFI automated encoding to H.264 MP4 for access copy creation:
```sh
ffmpeg -nostdin
-i input.mkv
-map 0:v:0
-map 0:a?
-disposition:a:1 default
-dn
-c:v libx264
-crf 28
-pix_fmt yuv420p
-vf yadif,scale=-1:1080:flags=lanczos,pad=1920:1080:-1:-1
-c:a aac
-movflags +faststart
-y
output.mp4
```
Access copies are forced to 16:9 aspect either letterbox or pillar box. CRF 28 is the very highest you can set a transcode for H.264 before you start to see compression artifacts. The video filter `yadif` is used to deinterlace video source files so they play cleanly on computer and other media.
---
class: contentpage
### **1.8 Other FFmpeg commands**
To rewrap a video without changing the codecs use stream copy tool:
```sh
ffmpeg -i input.mov -c copy -map 0 output.mkv
```
Trim video using `-ss`, and `-to` by suppling time codes. Use `-t` and supply total seconds for new duration:
```sh
ffmpeg -ss 00:00:10.000 -i input.mov -to 00:00:25.000 -c:v libx264 -c:a aac output.mp4
```
Convert DCP MXF files to an H.264 file:
```sh
ffmpeg -i video.mxf -i audio.mxf -c:v libx264 -pix_fmt yuv420p -c:a aac output.mp4
```
Concatenate multiple videos of the same type together into one file. First create a text file with one file one each line then use that text file to concatenate the files into one new file (use -safe 0 if using absolute paths in file):
```
file 'first_file.mp4'
file 'second_file.mp4'
```
```sh
ffmpeg -f concat -safe 0 -i list_of_files.txt -c copy output_concat.ext
```
---
class: contentpage
### **1.8 Other FFmpeg commands**
Convert an image sequence, such as your DPX sequence into a lossy ProRes 4:4:4 MOV file with framerate 25 fps
```sh
cd <dpx_folder>
ffmpeg -f image2 -pattern_type glob -i “*.dpx” -c:v prores_ks -profile:v 4
-pix_fmt yuv444p10le -r 25 your_dpx_file.mov
```
Itsoffset can be used to correct lipsync between your video and audio streams:
```sh
ffmpeg -i input.mov -itsoffset 0.125 -i input.mov -map 0:v -map 1:a -c copy output.mov
```
Many of these command ideas are taken from [FFmprovisr from Amia Open Source](https://amiaopensource.github.io/ffmprovisr/) written by the AV preservation community.
---
class: contentpage
### **2. FFmpeg filters**
Filters are created using the `libavfilter` library and come in two classes, the first are simple filtergraphs which have just one input and output of the same type.
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-03 at 17.43.24.png" width="650">]
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-03 at 17.43.30.png" width="700">]
```sh
-filter:v -vf -filter:a -af
```
---
class: contentpage
### **2. FFmpeg filters**
Complex filtegraphs can have multiple inputs and/or multiple outputs, or have stream types that differ between input and output.
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-03 at 17.43.37.png" width="500">]
```sh
-filter_complex
```
---
class: contentpage
### **2. FFmpeg filters**
This is FFmpeg example of a simple `filtergraph` that has one input/output but two split filters:
.center[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-05 at 16.46.32.png" width="600">]
The input stream splits into two named `main` and `tmp`. `tmp` is sent to stream crop and vertical flip, and `main` to the overlay filter where it merges back with `tmp`.
```sh
-vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2"
```
- Filters in the same linear chain are separated only by a comma
- Filters in distinct linear chains are separated by a semicolon
In this example `crop` and `vflip` are in one linear chain. `split` and `overlay` are separately in another.
---
class: contentpage
### **2.1 Video filters**
Deinterlacing filters options that remove top of bottom field interlacement in video from broadcast sources:
```sh
-vf yadif, -vf bwdif, -vf kerndeint
```
Cropping video is possible with the crop filter, after the equals it takes a list of parameters separated by colons:
```sh
ffmpeg -i input.mov -filter:v "crop=672:572:24:32" output.mov
```
Export thumbnails for every frame between 1 and 2 seconds, saved as `png` files:
```sh
ffmpeg -i input.mov -vf select=`between(t,1,2)` -vsync 0 output_images%d.png
```
Flip a video image horizontally or vertically using `hflip` and `vflip` filters:
```sh
ffmpeg -i input.mov -filter:v "hflip,vflip" -c:a copy output.mov
```
Chain filters together like the yadif, colormatix and format which selects a Pixel Format:
```sh
-vf "yadif,colormatrix=bt601:bt709,format=yuv420p"
```
---
class: contentpage
### **2.2 Audio filters**
Mute audio in a video file, between 3 seconds and 5 seconds into an audio stream:
```sh
ffmpeg -i input.mov -c:v copy -af “volume=enable=‘between(t,3,5)':volume=0" input_muted.mov
```
The loudnorm filter applies a standard audio loudness normalisation:
```sh
ffmpeg -i input.wav -af loudnorm -c:a mp3 -b:a 256k -ar 48000 output.mp3
```
The silenceremove filter will remove silent audio at the beginning of an audio file. The dB level can be adjusted
```sh
ffmpeg -i input.wav -af silenceremove=start_threshold=-57dB:start_duration=1:start_periods=1
-c:a pcm_s16le -ar 48000 output.wav
```
The aecho filter allows you to set an echo with adjustable parameters:
```sh
ffmpeg -i input.wav -af "aecho=0.8:0.9:1000:0.3" -c:a copy output.wav
```
Use the afade filter to fade in the first 5 seconds of audio, with type `t=in`:
```sh
ffmpeg -i input.wav -af "afade=t=in:ss=0:d=15" -c:a copy output.wav
```
---
class: contentpage
### **2.3 Detection filters**
Blackdetect can be used to identify in and out points of video that is nearly black and longer than 0.05 of a second, and ensure you just map the first video stream:
```sh
ffmpeg -i input.mov -vf "blackdetect=d=0.05:pix_th=0.10" -map 0:v:0 -f null -
```
Cropdetect filter auto-detects crops sizes of a video frame allowing this to be determined by black pixels:
```sh
ffmpeg -i input.mov -vf "cropdetect,metadata=mode=print" -f null -
```
Freezedetect finds frozen video great than set duration and noise tolerance 0.05, and use the metadata filter to capture just this data to a text file called freeze.txt:
```sh
ffmpeg -i input.mov -vf "freezedetect=d=0.25:n=0.05,metadata=mode=print:file=freeze.txt" -f null -
```
Silencedetect will detect silence in your audio (-50dB for over one second) and log a message when silence is found:
```sh
ffmpeg -i input.mp3 -af "silencedetect=noise=-50dB:d=1" -f null -
```
---
class: contentpage
### **2.4 Generative filters**
FFmpeg's lavfi library can be used to generate content for test video files, or for viewing in FFplay.
Synthesize a `voice utterance` using the libflite library using `flite`:
```sh
ffplay -f lavfi flite=text='Two roads diverged in a yellow wood...'
```
Generate video and audio content for video files using sine wave and mandelbrot:
```sh
ffmpeg -f lavfi -i mandelbrot -c:v v210 -f lavfi -i "sine=frequency=1000:sample_rate=48000"
-c:a pcm_s16le -t 5 output.mov
```
Many test sources can be generated for use in test files:
```sh
ffplay -f lavfi -i "testsrc=duration=5:size=1920x1080:rate=25"
```
Extract an audio spectrogram of a whole audio track, 1024x1024 pixels
```sh
ffmpeg -i input.mov showspectrum=s=1280x480:scale=log
```
---
class: contentpage
### **2.5 Visualisation filters**
The histogram filter computes and draws a colour distibution historgram for the input video. It's highly customisable but can be used simply with:
```sh
ffplay -i input.mov -vf histogram
```
The vectorscope filter displays two colour component values in a two dimensional graph:
```sh
ffplay -i input.mov -vf vectorscope=m=color
```
Simulate a video waveform monitor using the waveform filter, which plots colour component intensity:
```sh
ffplay -i input.mov -vf waveform
```
Map the colour pixels of your video on to a CIE colour diagram:
```sh
ffmpeg -i input.mov -vf ciescope
```
---
class: contentpage
### **3. QC Tools**
[QCTools](https://mediaarea.net/QCTools) uses FFmpeg filters extensively to help quality control audiovisual files. The tool helps users analyse and understand their digitised video files through use of audiovisual analytics and filtering.
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/qc_tools.png" width="1000">]
---
class: contentpage
### **3. QC Tools**
The preview window can display 1, 2 or 4 different filter views, here showing a manually damaged MP4 video on the left with broadcast range pixel and right oscilloscope:
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-16 at 15.56.02.png" width="1000">]
---
class: contentpage
### **3. QC Tools**
[AV Artifacts Atlas](https://www.avartifactatlas.com/) provide amazing detail about audiovisual problems found by archivists, documented with illustrations of how the problem can be identifed in QCTools:
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-17 at 19.52.24.png" width="1000">]
---
class: contentpage
### **3. QC Tools**
.left[<img src="https://raw.githubusercontent.com/digitensions/summer-school-2024-local/main/wednesday/images/Screenshot 2024-09-17 at 20.37.49.png" width="700">]
---
class: contentpage
### **3. QC Tools**
```sh
ffmpeg -i input.mov -bsf noise=60 output_noise.mp4
```
<font color="orange">Practise:</font> Use FFmpeg to add random bits to a new version of a file to create artificial noise then analyse both in QC Tools with help of the following resources:
- [MediaArea QCTools](https://mediaarea.net/QCTools)
- [MediaArea QCTools filter descriptions](https://mediaarea.net/QCTools/Filter_Descriptions)
- [MediaArea QCTools playback filter descriptions](https://mediaarea.net/QCTools/Playback_Filters)
- [QCTools documentation](https://sustainableheritagenetwork.org/system/files/atoms/file/QCTools%20Manual%20%28Printable%20Version%29.pdf)
- [AV Artifacts Atlas](https://www.avartifactatlas.com/)
</textarea>
<script src="https://remarkjs.com/downloads/remark-latest.min.js" type="text/javascript"></script>
<script type="text/javascript">var slideshow = remark.create({ratio: "16:9"});</script>
</body>
</html>