Compare commits

...

62 Commits

Author SHA1 Message Date
Reto Kromer
7aa124c3d1 fix closing tag 2017-08-08 18:06:07 +02:00
Ashley
50185eb04e Merge pull request #219 from amiaopensource/wordbreak-in-ff
sets wordbreak in firefox for long code
2017-08-07 16:44:12 -04:00
Katherine Frances Nagels
975766188f Merge pull request #218 from amiaopensource/weaver-branch
add sample rate flag to loudnorm
2017-08-08 08:43:58 +12:00
Ashley Blewer
fd1d596f50 sets wordbreak in firefox for long code 2017-08-07 15:25:15 -04:00
Andrew Weaver
18a80c10f1 add sample rate flag 2017-08-07 11:23:41 -07:00
Ashley
c6f7593d65 Merge pull request #217 from amiaopensource/phase-shift
adds audio phase shift command #195
2017-08-07 13:46:06 -04:00
Ashley Blewer
e6962b3ca4 uses word rotating instead of shifting, as it is more specific 2017-08-07 13:44:06 -04:00
Ashley Blewer
0ba25be082 removes spaces from pan= command command command 2017-08-07 13:40:54 -04:00
Ashley Blewer
e4611d8b6b removes spaces from pan= command 2017-08-07 13:39:45 -04:00
Reto Kromer
d609a9b943 guillemets (#216) 2017-08-07 19:33:44 +02:00
Ashley Blewer
d132e86f1d adds audio phase shift command #195 2017-08-07 13:30:35 -04:00
Ashley
e1e1060904 Merge pull request #215 from amiaopensource/ydif-scene-detection
adds ffprobe command for csv of timecode/ydif #213
2017-08-07 13:11:35 -04:00
Ashley Blewer
8b5fa8aa6a adds ffprobe command for csv of timecode/ydif #213 2017-08-07 12:32:54 -04:00
Reto Kromer
7bd05a8163 Merge pull request #214 (typos) 2017-07-29 21:09:12 +02:00
Reto Kromer
126fb1d284 typos 2017-07-29 14:26:47 +02:00
Reto Kromer
9799316c19 Merge pull request #212 (-an not needed) 2017-07-21 20:21:41 +02:00
Reto Kromer
6e4ed74841 -an not needed 2017-07-21 19:33:59 +02:00
Reto Kromer
0a6204264c Merge pull request #210 from kfrn/gh-pages
Normalise filename extensions (except VOB) to lower-case
2017-07-15 09:36:17 +02:00
Kieran O'Leary
c835746c24 change codec explanation for field order (#205)
* change codec explanation for field order

* add ffv1
2017-07-15 09:35:41 +02:00
kfrn
86e53b92c8 Normalise filename extensions (except VOB) to lower-case 2017-07-15 13:39:57 +12:00
Katherine Frances Nagels
41423e0917 Merge pull request #202 from amiaopensource/colorspace-link
convert colourspace - fix ffmpeg link
2017-07-15 11:51:12 +12:00
Reto Kromer
9a0875b692 use official naming 2017-07-14 10:57:41 +02:00
Reto Kromer
0473e85448 Merge pull request #203 from amiaopensource/trimming-map 2017-07-14 10:31:34 +02:00
Reto Kromer
b57349a3ec > should be encoded (#201) 2017-07-13 12:31:56 +02:00
Kieran O'Leary
9f3b56305c Merge pull request #204 from amiaopensource/aspect-ration
fixes aspect ration typo
2017-07-13 09:46:34 +01:00
Kieran O'Leary
5593b86ab7 fixes aspect ration typo 2017-07-12 23:33:37 +01:00
Kieran O'Leary
3544828fb1 adds -map 0 to trimming recipes, #196 2017-07-12 23:28:03 +01:00
Kieran O'Leary
c8691285cc convert colourspace - fix ffmpeg link 2017-07-12 22:56:07 +01:00
bturkus
e4a660967b Update index.html 2017-07-12 22:31:04 +02:00
bturkus
86138a55e1 Update index.html 2017-07-12 22:31:04 +02:00
bturkus
4c14af3209 add eia608 gif 2017-07-12 22:31:04 +02:00
Reto Kromer
8d18077af5 Merge pull request #198 from amiaopensource/update 2017-07-08 20:10:06 +02:00
Reto Kromer
8871868eda Merge pull request #199 from amiaopensource/little_changes 2017-07-08 17:01:07 +02:00
Reto Kromer
e1fb86ec94 Merge pull request #200 from amiaopensource/little_changes-1 2017-07-08 17:00:41 +02:00
Reto Kromer
7fe503d324 uniform 2017-07-08 12:48:15 +02:00
Reto Kromer
513631c80b uniform 2017-07-08 12:48:02 +02:00
Reto Kromer
22ff2368ad uniform 2017-07-08 11:19:09 +02:00
Kieran O'Leary
c81827d98f temporal difference - typo fix 2017-06-17 17:23:14 +01:00
Reto Kromer
19d249a09b Merge pull request #194 from amiaopensource/structure 2017-05-22 16:07:40 +02:00
Ashley
04abe26b53 updates contributors list (#193) 2017-05-22 15:59:43 +02:00
Ashley
ab3a8b25cf adds strip metadata recipe (#192)
- adds strip metadata recipe
2017-05-22 15:48:15 +02:00
Reto Kromer
40e8f8c73c move "Repair" 2017-05-22 14:51:17 +02:00
Ashley
129540fbfc Merge pull request #191 from amiaopensource/licence
CC BY 4.0
2017-05-20 18:47:53 -04:00
Reto Kromer
8578f01e1c CC BY 4.0 2017-05-20 18:43:23 +02:00
Reto Kromer
0158a85a4b HTML5 tweaks 2017-05-20 10:53:30 +02:00
Reto Kromer
cc724200d1 Merge pull request #189 from pjotrek-b/gh-pages
Added command for splitting into segments (segment muxer).
2017-05-18 10:30:45 +02:00
Peter B
0c03f57df6 Added printf-number examples and fixed requested changes. 2017-05-18 10:24:13 +02:00
Reto Kromer
659e920e0b Merge pull request #187 from amiaopensource/offline
add comment
2017-05-18 07:04:52 +02:00
Reto Kromer
2037ec922f Merge pull request #188 from amiaopensource/readme
update installation instructions
2017-05-18 07:04:05 +02:00
Reto Kromer
c745152f8e fix error 2017-05-17 19:27:19 +02:00
Peter B
e12bbb0c6d Added command for splitting into segments (segment muxer). 2017-05-17 18:53:04 +02:00
Reto Kromer
2c0e555dc1 update installation instructions 2017-05-17 18:50:29 +02:00
Reto Kromer
ed81a16458 Merge pull request #186 from amiaopensource/uniform_spacing
uniform spacing
2017-05-13 15:59:53 +02:00
Reto Kromer
172657b1bb add comment 2017-05-13 07:04:10 +02:00
Reto Kromer
7af1a3de2c uniform spacing 2017-05-13 06:48:57 +02:00
Reto Kromer
3f76abc053 Merge pull request #185 from amiaopensource/update-load-script
add query for default browser
2017-05-09 19:30:27 +02:00
Andrew Weaver
e3d11b3e7c add query for default browser 2017-05-09 11:45:28 -04:00
Reto Kromer
dbe9e1a049 Merge pull request #183 from amiaopensource/HTML5
fix HTML5
2017-05-09 11:32:21 +02:00
Reto Kromer
0fe609a683 Merge pull request #184 from kfrn/gh-pages
Minor wording amendment
2017-05-09 11:28:10 +02:00
kfrn
704a87f22c Minor wording amendment 2017-05-09 20:46:51 +12:00
Reto Kromer
b1a5f14e8c uniformise typography
vu en passant
2017-05-08 20:32:00 +02:00
Reto Kromer
55b34452f7 fix HTML5
- delete not opened closing tag
- uniform wells
2017-05-08 16:38:28 +02:00
7 changed files with 270 additions and 111 deletions

View File

@@ -4,10 +4,11 @@ h1, h2, h3, h4, h5, h6 {
code {
word-break: break-all;
word-wrap: break-word;
}
dd {
padding-left:24px;
padding-left: 24px;
}
dt {
@@ -26,9 +27,9 @@ img {
}
h1 {
letter-spacing:8px;
font-size:86px;
line-height:120px;
letter-spacing: 8px;
font-size: 86px;
line-height: 120px;
}
div {

BIN
img/eia608.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 MiB

View File

@@ -30,8 +30,8 @@
<p>For instructions on how to install FFmpeg on Mac, Linux, and Windows, refer to Reto Kromers <a href="https://avpres.net/FFmpeg/#ch1" target="_blank">installation instructions</a>.</p>
<p>For Bash and command line basics, try the <a href="https://learnpythonthehardway.org/book/appendixa.html" target="_blank">Command Line Crash Course</a>. For a little more context presented in an ffmprovisr style, try <a href="http://explainshell.com/" target="_blank">explainshell.com</a>!</p>
<h5>License</h5>
<p><a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank"><img alt="Creative Commons License" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png"></a><br>
This work is licensed under a <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Creative Commons Attribution-ShareAlike 4.0 International License</a>.</p>
<p><a href="https://creativecommons.org/licenses/by/4.0/" target="_blank"><img alt="Creative Commons License" src="https://i.creativecommons.org/l/by/4.0/88x31.png"></a><br>
This work is licensed under a <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank">Creative Commons Attribution 4.0 International License</a>.</p>
<h5>Sister projects</h5>
<p><a href="http://dd388.github.io/crals/" target="_blank">Script Ahoy</a>: Community Resource for Archivists and Librarians Scripting</p>
<p><a href="https://datapraxis.github.io/sourcecaster/" target="_blank">The Sourcecaster</a>: an app that helps you use the command line to work through common challenges that come up when working with digital primary sources.</p>
@@ -60,10 +60,10 @@
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_file</i></dt><dd>path and name of the input file<br>
The extension for the Matroska container is <code>.mkv</code>.</dd>
<dt>-c:v copy</dt><dd>re-encodes using the same video codec</dd>
<dt>-c:a aac</dt><dd>re-encodes using the AAC audio codec<br>
<dt>-c:v copy</dt><dd>copies the video stream without re-encoding it</dd>
<dt>-c:a aac</dt><dd>re-encodes the audio stream using the AAC audio codec<br>
Note that sadly MP4 cannot contain sound encoded by a PCM (Pulse-Code Modulation) audio codec.<br>
For silent videos you can replace <code>-c:a aac</code> by <code>-an</code>.</dd>
For silent videos you can replace <code>-c:a aac</code> by <code>-an</code>, which means that there will be no audio track in the output file.</dd>
<dt><i>output_file</i></dt><dd>path and name of the output file<br>
The extension for the MP4 container is <code>.mp4</code>.</dd>
</dl>
@@ -75,8 +75,6 @@
<!-- ends MKV to MP4 -->
</div>
<!-- ends well -->
<div class="well">
<h4>Change codec (transcode)</h4>
@@ -100,7 +98,7 @@
<li>2 = ProRes 422 (Standard)</li>
<li>3 = ProRes 422 (HQ)</li>
</ul></dd>
<dt>-vf yadif</dt><dd>Runs a deinterlacing video filter (yet another deinterlacing filter) on the new file</dd>
<dt>-vf yadif</dt><dd>Runs a deinterlacing video filter (yet another deinterlacing filter) on the new file. <code>-vf</code> is an alias for <code>-filter:v</code>.</dd>
<dt>-c:a pcm_s16le</dt><dd>Tells ffmpeg to encode the audio stream in 16-bit linear PCM</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file<br>
The extension for the QuickTime container is <code>.mov</code>.</dd>
@@ -129,9 +127,9 @@
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-c:v libx264</dt><dd>tells ffmpeg to change the video codec of the file to H.264</dd>
<dt>-c:v libx264</dt><dd>tells ffmpeg to encode the video stream as H.264</dd>
<dt>-pix_fmt yuv420p</dt><dd> libx264 will use a chroma subsampling scheme that is the closest match to that of the input. This can result in YC<sub>B</sub>C<sub>R</sub> 4:2:0, 4:2:2, or 4:4:4 chroma subsampling. QuickTime and most other non-FFmpeg based players cant decode H.264 files that are not 4:2:0. In order to allow the video to play in all players, you can specify 4:2:0 chroma subsampling.</dd>
<dt>-c:a copy</dt><dd>tells ffmpeg not to change the audio codec</dd>
<dt>-c:a copy</dt><dd>tells ffmpeg to copy the audio stream without re-encoding it</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p>In order to use the same basic command to make a higher quality file, you can add some of these presets:</p>
@@ -158,11 +156,11 @@
<div class="well">
<h3>H.264 from DCP</h3>
<p><code>ffmpeg -i <i>input_video_file</i>.mxf -i <i>input_audio_file</i>.mxf -c:v <i>libx264</i> -pix_fmt <i>yuv420p</i> -c:a <i>aac output_file.mp4</i></code></p>
<p>This will transcode mxf wrapped video and audio files to an H.264 encoded .mp4 file. Please note this only works for unencrypted, single reel DCPs.</p>
<p>This will transcode MXF wrapped video and audio files to an H.264 encoded MP4 file. Please note this only works for unencrypted, single reel DCPs.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_video_file</i></dt><dd>path and name of the video input file. This extension must be .mxf</dd>
<dt>-i <i>input_audio_file</i></dt><dd>path and name of the audio input file. This extension must be .mxf</dd>
<dt>-i <i>input_video_file</i></dt><dd>path and name of the video input file. This extension must be <code>.mxf</code></dd>
<dt>-i <i>input_audio_file</i></dt><dd>path and name of the audio input file. This extension must be <code>.mxf</code></dd>
<dt>-c:v <i>libx264</i></dt><dd>transcodes video to H.264</dd>
<dt>-pix_fmt <i>yuv420p</i></dt><dd>sets pixel format to yuv420p for greater compatibility with media players</dd>
<dt>-c:a aac</dt><dd>re-encodes using the AAC audio codec<br>
@@ -190,7 +188,7 @@
<div class="well">
<h3>Create FFV1 Version 3 video in a Matroska container with framemd5 of input</h3>
<p><code>ffmpeg -i <i>input_file</i> -map 0 -dn -c:v ffv1 -level 3 -g 1 -slicecrc 1 -slices 16 -c:a copy <i>output_file</i>.mkv -f framemd5 -an <i>md5_output_file</i></code></p>
<p>This will losslessly trancode your video with the FFV1 Version 3 codec in a Matroska container. In order to verify losslessness, a framemd5 of the source video is also generated. For more information on FFV1 encoding, <a href="https://trac.ffmpeg.org/wiki/Encode/FFV1" target="_blank">try the ffmpeg wiki</a>.</p>
<p>This will losslessly transcode your video with the FFV1 Version 3 codec in a Matroska container. In order to verify losslessness, a framemd5 of the source video is also generated. For more information on FFV1 encoding, <a href="https://trac.ffmpeg.org/wiki/Encode/FFV1" target="_blank">try the ffmpeg wiki</a>.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command.</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file.</dd>
@@ -203,7 +201,7 @@
<dt>-slices 16</dt><dd>Each frame is split into 16 slices. 16 is a good trade-off between filesize and encoding time. <a href="http://ndsr.nycdigital.org/diving-in-head-first/" target="_blank">[more]</a></dd>
<dt>-c:a copy</dt><dd>copies all mapped audio streams.</dd>
<dt><i>output_file</i>.mkv</dt><dd>path and name of the output file. Use the <code>.mkv</code> extension to save your file in a Matroska container. Optionally, choose a different extension if you want a different container, such as <code>.mov</code> or <code>.avi</code>.</dd>
<dt>-f framemd5</dt><dd> Decodes video with the framemd5 muxer in order to generate md5 checksums for every frame of your input file. This allows you to verify losslessness when compared against the framemd5s of the output file.</dd>
<dt>-f framemd5</dt><dd> Decodes video with the framemd5 muxer in order to generate MD5 checksums for every frame of your input file. This allows you to verify losslessness when compared against the framemd5s of the output file.</dd>
<dt>-an</dt><dd>ignores the audio stream when creating framemd5 (audio no)</dd>
<dt><i>framemd5_output_file</i></dt><dd>path, name and extension of the framemd5 file.</dd>
</dl>
@@ -230,7 +228,7 @@
<dt>-pattern_type glob</dt><dd>tells ffmpeg that the following mapping should "interpret like a <a href="https://en.wikipedia.org/wiki/Glob_%28programming%29" target="_blank">glob</a>" (a "global command" function that relies on the * as a wildcard and finds everything that matches)</dd>
<dt>-i <i>"input_image_*.jpg"</i></dt><dd>maps all files in the directory that start with input_image_, for example input_image_001.jpg, input_image_002.jpg, input_image_003.jpg... etc.<br>
(The quotation marks are necessary for the above “glob” pattern!)</dd>
<dt>-vf scale=250x250</dt><dd>filter the video to scale it to 250x250; -vf is an alias for -filter:v</dd>
<dt>-vf scale=250x250</dt><dd>filter the video to scale it to 250x250; <code>-vf</code> is an alias for <code>-filter:v</code></dd>
<dt><i>output_file.gif</i></dt><dd>path and name of the output file</dd>
</dl>
<p class="link"></p>
@@ -262,7 +260,7 @@
<p>Its also possible to adjust the quality of your output by setting the <b>-crf</b> and <b>-preset</b> values:</p>
<p><code>ffmpeg -i concat:<i>input_file1</i>\|<i>input_file2</i>\|<i>input_file3</i> -c:v libx264 -crf 18 -preset veryslow -c:a copy <i>output_file</i>.mp4</code></p>
<dl>
<dt>-crf 18</dt><dd>sets the constant rate factor to a visually lossless value. Libx264 defaults to a <a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf" target="_blank">crf of 23</a>, considered medium quality; a smaller crf value produces a larger and higher quality video.</dd>
<dt>-crf 18</dt><dd>sets the constant rate factor to a visually lossless value. Libx264 defaults to a <a href="https://trac.ffmpeg.org/wiki/Encode/H.264#crf" target="_blank">crf of 23</a>, considered medium quality; a smaller CRF value produces a larger and higher quality video.</dd>
<dt>-preset veryslow</dt><dd>A slower preset will result in better compression and therefore a higher-quality file. The default is <b>medium</b>; slower presets are <b>slow</b>, <b>slower</b>, and <b>veryslow</b>.</dd>
</dl>
<p>Bear in mind that by default, libx264 will only encode a single video stream and a single audio stream, picking the best of the options available. To preserve all video and audio streams, add <b>-map</b> parameters:</p>
@@ -366,8 +364,6 @@
<!-- ends WAV to AAC/MP4 -->
</div>
<!-- ends well -->
<div class="well">
<h4>Change formats</h4>
@@ -400,7 +396,7 @@
<div class="modal-content">
<div class="well">
<h3>Transform 4:3 aspect ratio into 16:9 with pillarbox</h3>
<p>Transform a video file with 4:3 aspect ratio into a video file with 16:9 aspect ration by correct pillarboxing.</p>
<p>Transform a video file with 4:3 aspect ratio into a video file with 16:9 aspect ratio by correct pillarboxing.</p>
<p><code>ffmpeg -i <i>input_file</i> -filter:v "pad=ih*16/9:ih:(ow-iw)/2:(oh-ih)/2" -c:a copy <i>output_file</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
@@ -424,7 +420,7 @@
<div class="modal-content">
<div class="well">
<h3>Transform 16:9 aspect ratio video into 4:3 with letterbox</h3>
<p>Transform a video file with 16:9 aspect ratio into a video file with 4:3 aspect ration by correct letterboxing.</p>
<p>Transform a video file with 16:9 aspect ratio into a video file with 4:3 aspect ratio by correct letterboxing.</p>
<p><code>ffmpeg -i <i>input_file</i> -filter:v "pad=iw:iw*3/4:(ow-iw)/2:(oh-ih)/2" -c:a copy <i>output_file</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
@@ -580,7 +576,7 @@
<p><span class="beware"></span> Using this command it is possible to add Rec.709 tags to a file that is actually Rec.601 (etc), so apply with caution!</p>
<p>These commands are relevant for H.264 and H.265 videos, encoded with <code>libx264</code> and <code>libx265</code> respectively.</p>
<p><b>Note</b>: If you wish to embed colourspace metadata <i>without</i> changing to another colourspace, omit <code>-vf colormatrix=src:dst</code>. However, since it is <code>libx264</code>/<code>libx265</code> that writes the metadata, its not possible to add these tags without reencoding the video stream.</p>
<p>For all possible values for <code>-color_primaries</code>, <code>-color_trc</code>, and <code>-colorspace</code>, see the ffmpeg documentation on <a href="./index.html#Codec-Options" target="_blank">codec options</a>.</p>
<p>For all possible values for <code>-color_primaries</code>, <code>-color_trc</code>, and <code>-colorspace</code>, see the ffmpeg documentation on <a href="https://www.ffmpeg.org/ffmpeg-codecs.html#Codec-Options" target="_blank">codec options</a>.</p>
<hr>
<p id="fn1" class="footnote">1. Out of step with the regular pattern, <code>-color_trc</code> doesnt accept <code>bt470bg</code>; it is instead here referred to directly as gamma.<br>
In the Rec.601 standard, 525-line/NTSC and 625-line/PAL video have assumed gammas of 2.2 and 2.8 respectively. <a href="#ref1" title="Jump back."></a></p>
@@ -656,7 +652,7 @@
</div>
</div>
<!-- ends abitscope -->
<!-- astats -->
<span data-toggle="modal" data-target="#astats"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Play a graphical output showing decibel levels of an input file">Graphic for audio</button></span>
<div id="astats" class="modal fade" tabindex="-1" role="dialog">
@@ -672,7 +668,7 @@
<dt>movie='<i>input.mp3</i>'</dt><dd>declares audio source file on which to apply filter</dd>
<dt>,</dt><dd>comma signifies the end of audio source section and the beginning of the filter section</dd>
<dt>astats=metadata=1</dt><dd>tells the astats filter to ouput metadata that can be passed to another filter (in this case adrawgraph)</dd>
<dt>:</dt><dd>divides beteen options of the same filter</dd>
<dt>:</dt><dd>divides between options of the same filter</dd>
<dt>reset=1</dt><dd>tells the filter to calculate the stats on every frame (increasing this number would calculate stats for groups of frames)</dd>
<dt>,</dt><dd>comma divides one filter in the chain from another</dd>
<dt>adrawgraph=lavfi.astats.Overall.Peak_level:max=0:min=-30.0</dt><dd>draws a graph using the overall peak volume calculated by the astats filter. It sets the max for the graph to 0 (dB) and the minimum to -30 (dB). For more options on data points that can be graphed see the <a href="https://ffmpeg.org/ffmpeg-filters.html#astats-1" target="_blank">ffmpeg astats documentation</a></dd>
@@ -813,7 +809,7 @@
<dt>-i <i>input01</i> -i <i>input02</i></dt><dd>Designates the files to use for inputs one and two respectively</dd>
<dt>-filter_complex</dt><dd>Lets ffmpeg know we will be using a complex filter (this must be used for multiple inputs)</dd>
<dt>[0:v:0]tblend=all_mode=difference128[a]</dt><dd>Applies the tblend filter (with the settings all_mode and difference128) to the first video stream from the first input and assigns the result to the output [a]</dd>
<dt>[1:v:0]tblend=all_mode=difference128[a]</dt><dd>Applies the tblend filter (with the settings all_mode and difference128) to the first video stream from the second input and assigns the result to the output [b]</dd>
<dt>[1:v:0]tblend=all_mode=difference128[b]</dt><dd>Applies the tblend filter (with the settings all_mode and difference128) to the first video stream from the second input and assigns the result to the output [b]</dd>
<dt>[a][b]hstack[out]</dt><dd>Takes the outputs from the previous steps ([a] and [b] and uses the hstack (horizontal stack) filter on them to create the side by side output. This output is then named [out])</dd>
<dt>-map [out]</dt><dd>Maps the output of the filter chain</dd>
<dt>-f nut</dt><dd>Sets the format for the output video stream to <a href="https://www.ffmpeg.org/ffmpeg-formats.html#nut" target="_blank">Nut</a></dd>
@@ -928,13 +924,14 @@
<div class="modal-content">
<div class="well">
<h3>Excerpt from beginning</h3>
<p><code>ffmpeg -i <i>input_file</i> -t <i>5</i> -c copy <i>output_file</i></code></p>
<p><code>ffmpeg -i <i>input_file</i> -t <i>5</i> -c copy -map 0 <i>output_file</i></code></p>
<p>This command captures a certain portion of a video file, starting from the beginning and continuing for the amount of time (in seconds) specified in the script. This can be used to create a preview file, or to remove unwanted content from the end of the file. To be more specific, use timecode, such as 00:00:05.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-t <i>5</i></dt><dd>Tells ffmpeg to stop copying from the input file after a certain time, and specifies the number of seconds after which to stop copying. In this case, 5 seconds is specified.</dd>
<dt>-c copy</dt><dd>use stream copy mode to re-mux instead of re-encode</dd>
<dt>-map 0</dt><dd>Tells ffmpeg to map all streams of the input to the output.</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p class="link"></p>
@@ -951,7 +948,7 @@
<div class="modal-content">
<div class="well">
<h3>Trim a video without re-encoding</h3>
<p><code>ffmpeg -i <i>input_file</i> -ss 00:02:00 -to 00:55:00 -c copy <i>output_file</i></code></p>
<p><code>ffmpeg -i <i>input_file</i> -ss 00:02:00 -to 00:55:00 -c copy -map 0 <i>output_file</i></code></p>
<p>This command allows you to create an excerpt from a video file without re-encoding the image data.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
@@ -959,6 +956,7 @@
<dt>-ss 00:02:00</dt><dd>sets in point at 00:02:00</dd>
<dt>-to 00:55:00</dt><dd>sets out point at 00:55:00</dd>
<dt>-c copy</dt><dd>use stream copy mode (no re-encoding)<br>
<dt>-map 0</dt><dd>Tells ffmpeg to map all streams of the input to the output.</dd>
<i>Note:</i> watch out when using <code>-ss</code> with <code>-c copy</code> if the source is encoded with an interframe codec (e.g., H.264). Since ffmpeg must split on i-frames, it will seek to the nearest i-frame to begin the stream copy.</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
@@ -982,13 +980,14 @@
<div class="modal-content">
<div class="well">
<h3>Excerpt to end</h3>
<p><code>ffmpeg -i <i>input_file</i> -ss <i>5</i> -c copy <i>output_file</i></code></p>
<p><code>ffmpeg -i <i>input_file</i> -ss <i>5</i> -c copy -map 0 <i>output_file</i></code></p>
<p>This command copies a video file starting from a specified time, removing the first few seconds from the output. This can be used to create an excerpt, or remove unwanted content from the beginning of a video file.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-ss <i>5</i></dt><dd>Tells ffmpeg what timecode in the file to look for to start copying, and specifies the number of seconds into the video that ffmpeg should start copying. To be more specific, you can use timecode such as 00:00:05.</dd>
<dt>-c copy</dt><dd>use stream copy mode to re-mux instead of re-encode</dd>
<dt>-map 0</dt><dd>Tells ffmpeg to map all streams of the input to the output.</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p class="link"></p>
@@ -1005,13 +1004,14 @@
<div class="modal-content">
<div class="well">
<h3>Excerpt from end</h3>
<p><code>ffmpeg -sseof <i>-5</i> -i <i>input_file</i> -c copy <i>output_file</i></code></p>
<p><code>ffmpeg -sseof <i>-5</i> -i <i>input_file</i> -c copy -map 0 <i>output_file</i></code></p>
<p>This command copies a video file starting from a specified time before the end of the file, removing everything before from the output. This can be used to create an excerpt, or extract content from the end of a video file (e.g. for extracting the closing credits).</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-sseof <i>-5</i></dt><dd>This parameter must stay before the input file. It tells ffmpeg what timecode in the file to look for to start copying, and specifies the number of seconds from the end of the video that ffmpeg should start copying. The end of the file has index 0 and the minus sign is needed to reference earlier portions. To be more specific, you can use timecode such as -00:00:05. Note that in most file formats it is not possible to seek exactly, so ffmpeg will seek to the closest point before.</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-c copy</dt><dd>use stream copy mode to re-mux instead of re-encode</dd>
<dt>-map 0</dt><dd>Tells ffmpeg to map all streams of the input to the output.</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p class="link"></p>
@@ -1036,7 +1036,7 @@
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-aspect <i>4:3</i></dt><dd>declares the aspect ratio of the resulting video file. You can also use 16:9.</dd>
<dt>-target <i>ntsc-dvd</i></dt><dd>specifies the region for your DVD. This could be also pal-dvd.</dd>
<dt><i>output_file</i>.mpg</dt><dd>path and name of the output file. The extension must be .mpg</dd>
<dt><i>output_file</i>.mpg</dt><dd>path and name of the output file. The extension must be <code>.mpg</code></dd>
</dl>
<p class="link"></p>
</div>
@@ -1083,20 +1083,20 @@
<div class="well">
<h3>Generate two access MP3s from input. One with appended audio (such as copyright notice) and one unmodified.</h3>
<p> <code>ffmpeg -i <i>input_file</i> -i <i>input_file_to_append</i> -filter_complex "[0:a:0]asplit=2[a][b];[b]afifo[bb];[1:a:0][bb]concat=n=2:v=0:a=1[concatout]" -map "[a]" -codec:a libmp3lame -dither_method modified_e_weighted -qscale:a 2 <i>output_file.mp3</i> -map "[concatout]" -codec:a libmp3lame -dither_method modified_e_weighted -qscale:a 2 <i>output_file_appended.mp3</i></code></p>
<p>This script allows you to generate two derivative audio files from a master while appending audio from a seperate file (for example a copyright or institutional notice) to one of them.</p>
<p>This script allows you to generate two derivative audio files from a master while appending audio from a separate file (for example a copyright or institutional notice) to one of them.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file (the master file)</dd>
<dt>-i <i>input_file_to_append</i></dt><dd>path, name and extension of the input file (the file to be appended to access file)</dd>
<dt>-filter_complex</dt><dd>enables the complex filtering to manage splitting the input to two audio streams</dd>
<dt>[0:a:0]asplit=2[a][b];</dt><dd><code>asplit</code> allows audio streams to be split up for seperate manipulation. This command splits the audio from the first input (the master file) into two streams "a" and "b"</dd>
<dt>[0:a:0]asplit=2[a][b];</dt><dd><code>asplit</code> allows audio streams to be split up for separate manipulation. This command splits the audio from the first input (the master file) into two streams "a" and "b"</dd>
<dt>[b]afifo[bb];</dt><dd>this buffers the stream "b" to help prevent dropped samples and renames stream to "bb"</dd>
<dt>[1:a:0][bb]concat=n=2:v=0:a=1[concatout]</dt><dd><code>concat</code> is used to join files. <code>n=2</code> tells the filter there are two inputs. <code>v=0:a=1</code> Tells the filter there are 0 video outputs and 1 audio output. This command appends the audio from the second input to the beginning of stream "bb" and names the output "concatout"</dd>
<dt>-map "[a]"</dt><dd>this maps the unmodified audio stream to the first output</dd>
<dt>-codec:a libmp3lame -dither_method modified_e_weighted -qscale:a 2</dt><dd>sets up mp3 options (using constant quality)</dd>
<dt>-codec:a libmp3lame -dither_method modified_e_weighted -qscale:a 2</dt><dd>sets up MP3 options (using constant quality)</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file (unmodified)</dd>
<dt>-map "[concatout]"</dt><dd>this maps the modified stream to the second output</dd>
<dt>-codec:a libmp3lame -dither_method modified_e_weighted -qscale:a 2</dt><dd>sets up mp3 options (using constant quality)</dd>
<dt>-codec:a libmp3lame -dither_method modified_e_weighted -qscale:a 2</dt><dd>sets up MP3 options (using constant quality)</dd>
<dt><i>output_file_appended</i></dt><dd>path, name and extension of the output file (with appended notice)</dd>
</dl>
<p class="link"></p>
@@ -1107,10 +1107,33 @@
<!-- ends append notice to access mp3 -->
</div>
<div class="well">
<h4>Normalize/Equalize Audio</h4>
<!-- phase shift -->
<span data-toggle="modal" data-target="#phase_shift"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Inverses the audio phase of the second channel">Flip phase shift</button></span>
<div id="phase_shift" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="well">
<h3>Flip audio phase shift</h3>
<p><code>ffmpeg -i <i>input_file</i> -af pan="stereo|c0=c0|c1=-1*c1" <i>output_file</i></code></p>
<p>This command inverses the audio phase of the second channel by rotating it 180°.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-af</dt><dd>specifies that the next section should be interpreted as an audio filter</dd>
<dt>pan=</dt><dd>tell the quoted text below to use the <a href="https://ffmpeg.org/ffmpeg-filters.html#pan-1" target="_blank">pan filter</a></dd>
<dt>"stereo|c0=c0|c1=-1*c1"</dt><dd>maps the output's first channel (c0) to the input's first channel and the output's second channel (c1) to the inverse of the input's second channel</dd>
<dt><i>output file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p class="link"></p>
</div>
</div>
</div>
</div>
<!-- ends phase shift -->
<!-- loudnorm metadata -->
<span data-toggle="modal" data-target="#loudnorm_metadata"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Calculate Loudness Levels">Calculate Loudness Levels</button></span>
<div id="loudnorm_metadata" class="modal fade" tabindex="-1" role="dialog">
@@ -1120,8 +1143,8 @@
<h3>Calculate Loudness Levels</h3>
<p><code>ffmpeg -i <i>input_file</i> -af loudnorm=print_format=json -f null -</code></p>
<p>This filter calculates and outputs loudness information in json about an input file (labeled input) as well as what the levels would be if loudnorm were applied in its one pass mode (labeled output). The values generated can be used as inputs for a 'second pass' of the loudnorm filter allowing more accurate loudness normalization than if it is used in a single pass.</p>
<p>These instructions use the loudnorm defaults, which align well with PBS recommendations for target loudness. More information can be found at the <a href=https://ffmpeg.org/ffmpeg-filters.html#loudnorm>loudnorm documentation</a>.</p>
<p>Information about PBS loudness standards can be found in the <a href=http://www-tc.pbs.org/capt/Producing/TOS-2012-Pt2-Distribution.pdf>PBS Technical Operating Specifications</a> document. Information about EBU loudness standards can be found in the <a href=https://tech.ebu.ch/docs/r/r128-2014.pdf>EBU R 128</a> recommendation document.</p>
<p>These instructions use the loudnorm defaults, which align well with PBS recommendations for target loudness. More information can be found at the <a href="https://ffmpeg.org/ffmpeg-filters.html#loudnorm">loudnorm documentation</a>.</p>
<p>Information about PBS loudness standards can be found in the <a href="http://www-tc.pbs.org/capt/Producing/TOS-2012-Pt2-Distribution.pdf" target="_blank">PBS Technical Operating Specifications</a> document. Information about EBU loudness standards can be found in the <a href="https://tech.ebu.ch/docs/r/r128-2014.pdf" target="_blank">EBU R 128</a> recommendation document.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt><i>input_file</i></dt><dd>path, name and extension of the input file</dd>
@@ -1143,14 +1166,15 @@
<div class="modal-content">
<div class="well">
<h3>One Pass Loudness Normalization</h3>
<p><code>ffmpeg -i <i>input_file</i> -af loudnorm=dual_mono=true <i>output_file</i></code></p>
<p>This will normalize the loudness of an input using one pass, which is quicker but less accurate than using two passes. This command uses the loudnorm filter defaults for target loudness. These defaults align well with PBS recommendations, but loudnorm does allow targeting of specific loudness levels. More information can be found at the <a href=https://ffmpeg.org/ffmpeg-filters.html#loudnorm>loudnorm documentation</a>.</p>
<p>Information about PBS loudness standards can be found in the <a href=http://www-tc.pbs.org/capt/Producing/TOS-2012-Pt2-Distribution.pdf>PBS Technical Operating Specifications</a> document. Information about EBU loudness standards can be found in the <a href=https://tech.ebu.ch/docs/r/r128-2014.pdf>EBU R 128</a> recommendation document.</p>
<p><code>ffmpeg -i <i>input_file</i> -af loudnorm=dual_mono=true -ar 48k <i>output_file</i></code></p>
<p>This will normalize the loudness of an input using one pass, which is quicker but less accurate than using two passes. This command uses the loudnorm filter defaults for target loudness. These defaults align well with PBS recommendations, but loudnorm does allow targeting of specific loudness levels. More information can be found at the <a href="https://ffmpeg.org/ffmpeg-filters.html#loudnorm" target="_blank">loudnorm documentation</a>.</p>
<p>Information about PBS loudness standards can be found in the <a href="http://www-tc.pbs.org/capt/Producing/TOS-2012-Pt2-Distribution.pdf" target="_blank">PBS Technical Operating Specifications</a> document. Information about EBU loudness standards can be found in the <a href="https://tech.ebu.ch/docs/r/r128-2014.pdf" target="_blank">EBU R 128</a> recommendation document.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt><i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-af loudnorm</dt><dd>activates the loudnorm filter with default settings</dd>
<dt>dual_mono=true</dt><dd>(optional) Use this for mono files meant to be played back on stereo systems for correct loudness. Not necessary for multi-track inputs.</dd>
<dt>-ar 48k</dt><dd>Sets the output sample rate to 48 kHz. (The loudnorm filter upsamples to 192 kHz so it is best to manually set a desired output sample rate).</dd>
<dt><i>output_file</i></dt><dd>path, name and extension for output file</dd>
</dl>
<p class="link"></p>
@@ -1167,9 +1191,9 @@
<div class="modal-content">
<div class="well">
<h3>Two Pass Loudness Normalization</h3>
<p><code>ffmpeg -i <i>input_file</i> -af loudnorm=dual_mono=true:measured_I=<i>input_i</i>:measured_TP=<i>input_tp</i>:measured_LRA=<i>input_lra</i>:measured_thresh=<i>input_thresh</i>:offset=<i>target_offset</i>:linear=true <i>output_file</i></code></p>
<p>This command allows using the levels calculated using a <a href=#loudnorm_metadata>first pass of the loudnorm filter</a> to more accurately normalize loudness. This command uses the loudnorm filter defaults for target loudness. These defaults align well with PBS recommendations, but loudnorm does allow targeting of specific loudness levels. More information can be found at the <a href=https://ffmpeg.org/ffmpeg-filters.html#loudnorm>loudnorm documentation</a>.</p>
<p>Information about PBS loudness standards can be found in the <a href=http://www-tc.pbs.org/capt/Producing/TOS-2012-Pt2-Distribution.pdf>PBS Technical Operating Specifications</a> document. Information about EBU loudness standards can be found in the <a href=https://tech.ebu.ch/docs/r/r128-2014.pdf>EBU R 128</a> recommendation document.</p>
<p><code>ffmpeg -i <i>input_file</i> -af loudnorm=dual_mono=true:measured_I=<i>input_i</i>:measured_TP=<i>input_tp</i>:measured_LRA=<i>input_lra</i>:measured_thresh=<i>input_thresh</i>:offset=<i>target_offset</i>:linear=true -ar 48k <i>output_file</i></code></p>
<p>This command allows using the levels calculated using a <a href=#loudnorm_metadata>first pass of the loudnorm filter</a> to more accurately normalize loudness. This command uses the loudnorm filter defaults for target loudness. These defaults align well with PBS recommendations, but loudnorm does allow targeting of specific loudness levels. More information can be found at the <a href="https://ffmpeg.org/ffmpeg-filters.html#loudnorm" target="_blank">loudnorm documentation</a>.</p>
<p>Information about PBS loudness standards can be found in the <a href="http://www-tc.pbs.org/capt/Producing/TOS-2012-Pt2-Distribution.pdf" target="_blank">PBS Technical Operating Specifications</a> document. Information about EBU loudness standards can be found in the <a href="https://tech.ebu.ch/docs/r/r128-2014.pdf" target="_blank">EBU R 128</a> recommendation document.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt><i>input_file</i></dt><dd>path, name and extension of the input file</dd>
@@ -1180,7 +1204,8 @@
<dt>measured_LRA=<i>input_lra</i></dt><dd>use the 'input_lra' value (loudness range) from the first pass in place of input_lra</dd>
<dt>measured_LRA=<i>input_thresh</i></dt><dd>use the 'input_thresh' value (threshold) from the first pass in place of input_thresh</dd>
<dt>offset=<i>target_offset</i></dt><dd>use the 'target_offset' value (offset) from the first pass in place of target_offset</dd>
<dt>linear=true</i></dt><dd>tells loudnorm to use linear normalization</dd>
<dt>linear=true</dt><dd>tells loudnorm to use linear normalization</dd>
<dt>-ar 48k</dt><dd>Sets the output sample rate to 48 kHz. (The loudnorm filter upsamples to 192 kHz so it is best to manually set a desired output sample rate).</dd>
<dt><i>output_file</i></dt><dd>path, name and extension for output file</dd>
</dl>
<p class="link"></p>
@@ -1198,7 +1223,7 @@
<div class="well">
<h3>RIAA Equalization</h3>
<p><code>ffmpeg -i <i>input_file</i> -af aemphasis=type=riaa <i>output_file</i></code></p>
<p>This will apply RIAA equalization to an input file allowing correct listening of audio transferred 'flat' (without EQ) from records that used this EQ curve. For more information about RIAA equalization see the <a href=https://en.wikipedia.org/wiki/RIAA_equalization>Wikipedia page</a> on the subject.</p>
<p>This will apply RIAA equalization to an input file allowing correct listening of audio transferred 'flat' (without EQ) from records that used this EQ curve. For more information about RIAA equalization see the <a href="https://en.wikipedia.org/wiki/RIAA_equalization" target="_blank">Wikipedia page</a> on the subject.</p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt><i>input_file</i></dt><dd>path, name and extension of the input file</dd>
@@ -1211,8 +1236,8 @@
</div>
</div>
<!-- ends RIAA equalization -->
</div><!-- closes the well -->
</div>
<div class="well">
<h4>Preservation</h4>
@@ -1223,20 +1248,20 @@
<div class="modal-content">
<div class="well">
<h3>Create Bash script to batch process with ffmpeg</h3>
<p>Bash scripts are plain text files saved with a .sh extension. This entry explains how they work with the example of a bash script named “Rewrap-MXF.sh”, which rewraps .MXF files in a given directory to .MOV files.</p>
<p>Bash scripts are plain text files saved with a .sh extension. This entry explains how they work with the example of a bash script named “Rewrap-MXF.sh”, which rewraps .mxf files in a given directory to .mov files.</p>
<p>“Rewrap-MXF.sh” contains the following text:</p>
<p><code>for file in *.MXF; do ffmpeg -i "$file" -map 0 -c copy "${file%.MXF}.mov"; done</code></p>
<p><code>for file in *.mxf; do ffmpeg -i "$file" -map 0 -c copy "${file%.mxf}.mov"; done</code></p>
<dl>
<dt>for file in *.MXF</dt><dd>starts the loop, and states what the input files will be. Here, the ffmpeg command within the loop will be applied to all files with an extension of .MXF.<br>
The word file is an arbitrary variable which will represent each .MXF file in turn as it is looped over.</dd>
<dt>for file in *.mxf</dt><dd>starts the loop, and states what the input files will be. Here, the ffmpeg command within the loop will be applied to all files with an extension of .mxf.<br>
The word file is an arbitrary variable which will represent each .mxf file in turn as it is looped over.</dd>
<dt>do ffmpeg -i "$file"</dt><dd>carry out the following ffmpeg command for each input file.<br>
Per Bash syntax, within the command the variable is referred to by <b>“$file”</b>. The dollar sign is used to reference the variable file, and the enclosing quotation marks prevents reinterpretation of any special characters that may occur within the filename, ensuring that the original filename is retained.</dd>
<dt>-map 0</dt><dd>retain all streams</dd>
<dt>-c copy</dt><dd>enable stream copy (no re-encode)</dd>
<dt>"${file%.MXF}.mov";</dt><dd>retaining the original file name, set the output file wrapper as .mov</dd>
<dt>"${file%.mxf}.mov";</dt><dd>retaining the original file name, set the output file wrapper as .mov</dd>
<dt>done</dt><dd>complete; all items have been processed.</dd>
</dl>
<p><b>Note</b>: the shell script (.sh file) and all .MXF files to be processed must be contained within the same directory, and the script must be run from that directory.<br>
<p><b>Note</b>: the shell script (.sh file) and all .mxf files to be processed must be contained within the same directory, and the script must be run from that directory.<br>
Execute the .sh file with the command <code>sh Rewrap-MXF.sh</code>.</p>
<p>Modify the script as needed to perform different transcodes, or to use with ffprobe. :)</p>
<p>The basic pattern will look similar to this:<br>
@@ -1320,7 +1345,8 @@ foreach ($file in $inputfiles) {
<div class="well">
<h3>Create MD5 checksums (audio samples)</h3>
<p><code>ffmpeg -i <i>input_file</i> -af "asetnsamples=<i>n=48000</i>" -f framemd5 -vn <i>output_file</i></code></p>
<p>This will create an MD5 checksum for each group of 48000 audio samples.<br> The number of samples per group can be set arbitrarily, but it's good practice to match the samplerate of the media file (so you will get one checksum per second).</p>
<p>This will create an MD5 checksum for each group of 48000 audio samples.<br>
The number of samples per group can be set arbitrarily, but it's good practice to match the samplerate of the media file (so you will get one checksum per second).</p>
<p>Examples for other samplerates:</p>
<ul>
<li>44.1 kHz: "asetnsamples=n=44100"</li>
@@ -1473,6 +1499,36 @@ foreach ($file in $inputfiles) {
</div>
<!-- ends QCTools Report (no audio) -->
<!-- Read/Extract EIA-608 Closed Captions -->
<span data-toggle="modal" data-target="#readeia608"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Read or extract EIA-608 (Line 21) closed captioning">Read/Extract EIA-608 Closed Captioning</button></span>
<div id="readeia608" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="well">
<h3>Read/Extract EIA-608 (Line 21) closed captioning</h3>
<p><code>ffprobe -f lavfi -i movie=<i>input_file</i>,readeia608 -show_entries frame=pkt_pts_time:frame_tags=lavfi.readeia608.0.line,lavfi.readeia608.0.cc,lavfi.readeia608.1.line,lavfi.readeia608.1.cc -of csv > <i>input_file</i>.csv</code></p>
<p>This command uses FFmpeg's <a href="https://ffmpeg.org/ffmpeg-filters.html#readeia608" target="_blank">readeia608</a> filter to extract the hexadecimal values hidden within <a href="https://en.wikipedia.org/wiki/EIA-608" target="_blank">EIA-608 (Line 21)</a> Closed Captioning, outputting a csv file. For more information about EIA-608, check out Adobe's <a href="https://www.adobe.com/content/dam/Adobe/en/devnet/video/pdfs/introduction_to_closed_captions.pdf" target="_blank">Introduction to Closed Captions</a>.</p>
<p>If hex isn't your thing, closed captioning <a href="http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/CC_CHARS.HTML" target="_blank">character</a> and <a href="http://www.theneitherworld.com/mcpoodle/SCC_TOOLS/DOCS/CC_CODES.HTML" target="_blank">code</a> sets can be found in the documentation for SCTools.</p>
<dl>
<dt>ffprobe</dt><dd>starts the command</dd>
<dt>-f lavfi</dt><dd>tells ffprobe to use the <a href="http://ffmpeg.org/ffmpeg-devices.html#lavfi" target="_blank">libavfilter</a> input virtual device</dd>
<dt>-i <i>input_file</i></dt><dd>input file and parameters</dd>
<dt>readeia608 -show_entries frame=pkt_pts_time:frame_tags=lavfi.readeia608.0.line,lavfi.readeia608.0.cc,lavfi.readeia608.1.line,lavfi.readeia608.1.cc -of csv</dt><dd>specifies the first two lines of video in which EIA-608 data (hexadecimal byte pairs) are identifiable by ffprobe, outputting comma separated values (CSV)</dd>
<dt>&gt;</dt><dd>redirects the standard output (the data created by ffprobe about the video)</dd>
<dt><i>output_file</i>.csv</dt><dd>names the CSV output file</dd>
</dl>
<div class="sample-image">
<h4>Example</h4>
<p>Side-by-side video with true EIA-608 captions on the left, zoomed in view of the captions on the right (with hex values represented). To achieve something similar with your own captioned video, try out the EIA608/VITC viewer in <a href="https://github.com/bavc/qctools" target="_blank">QCTools</a>.</p>
<img src="img/eia608.gif" alt="GIF of Closed Captions">
</div>
<p class="link"></p>
</div>
</div>
</div>
</div>
<!-- ends Read/Extract EIA-608 Closed Captions -->
</div>
<div class="well">
<h4>Test files</h4>
@@ -1662,6 +1718,33 @@ foreach ($file in $inputfiles) {
</div>
<!-- ends SMPTE bars + Sine wave -->
</div>
<div class="well">
<h4>Repair</h4>
<!-- Fix A/V async 1 -->
<span data-toggle="modal" data-target="#avsync_aresample"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Fix A/V sync issues by resampling audio">Fix AV Sync: Resample audio</button></span>
<div id="avsync_aresample" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="well">
<h3>Fix AV Sync: Resample audio</h3>
<p><code>ffmpeg -i <i>input_file</i> -c:v copy -c:a pcm_s16le -af "aresample=async=1000" <i>output_file</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt><i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-c:v copy</dt><dd>Copy all mapped video streams.</dd>
<dt>-c:a pcm_s16le</dt><dd>Tells ffmpeg to encode the audio stream in 16-bit linear PCM (<a href="https://en.wikipedia.org/wiki/Endianness#Little-endian" target="_blank">little endian</a>)</dd>
<dt>-af "aresample=async=1000"</dt><dd>Stretch/squeezes samples to given timestamps, with maximum of 1000 samples per second compensation <a href="https://ffmpeg.org/ffmpeg-filters.html#aresample-1" target="_blank">[more]</a></dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file. Try different file extensions such as mkv, mov, mp4, or avi.</dd>
</dl>
<p class="link"></p>
</div>
</div>
</div>
</div>
<!-- ends Fix A/V async 1 -->
</div>
<div class="well">
<h4>Other</h4>
@@ -1698,6 +1781,42 @@ e.g.: <code>ffmpeg -f concat -safe 0 -i mylist.txt -c copy <i>output_file</i></c
</div>
<!-- ends Join files together -->
<!-- Split file into segments -->
<span data-toggle="modal" data-target="#segment_file"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Split one file into several smaller segments">Split file into segments</button></span>
<div id="segment_file" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="well">
<h3>Split file into segments</h3>
<p><code>ffmpeg -i <i>input_file</i> -c copy -map 0 -f segment -segment_time 60 -reset_timestamps 1 <i>output_file-%03d.mkv</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>Starts the command.</dd>
<dt>-i <i>input_file</i></dt><dd>Takes in a normal file.</dd>
<dt>-c copy</dt><dd>Use stream copy mode to re-mux instead of re-encode.</dd>
<dt>-map 0</dt><dd>Tells ffmpeg to map all streams of the input to the output.</dd>
<dt>-f segment</dt><dd>Use <a href="http://www.ffmpeg.org/ffmpeg-formats.html#toc-segment_002c-stream_005fsegment_002c-ssegment">segment muxer</a> for generating the output.</dd>
<dt>-segment_time 60</dt><dd>Set duration of each segment (in seconds). This example creates segments with max. duration of 60s each.</dd>
<dt>-reset_timestamps 1</dt><dd>Reset timestamps of each segment to 0. Meant to ease the playback of the generated segments.</dd>
<dt><i>output_file-%03d.mkv</i></dt>
<dd>
<p>Path, name and extension of the output file.<br>
In order to have an incrementing number in each segment filename, FFmpeg supports <a href="http://www.cplusplus.com/reference/cstdio/printf/">printf-style</a> syntax for a counter.</p>
<p>In this example, '%03d' means: 3-digits, zero-padded<br>
Examples:</p>
<ul>
<li><code>%03d</code>: 000, 001, 002, ... 999</li>
<li><code>%05d</code>: 00000, 00001, 00002, ... 99999</li>
<li><code>%d</code>: 0, 1, 2, 3, 4, ... 23, 24, etc. </li>
</ul>
</dd>
</dl>
<p class="link"></p>
</div>
</div>
</div>
</div>
<!-- ends Split file into segments -->
<!-- Play image sequence -->
<span data-toggle="modal" data-target="#play_im_seq"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Play an image sequence directly as moving images">Play an image sequence</button></span>
<div id="play_im_seq" class="modal fade" tabindex="-1" role="dialog">
@@ -1942,7 +2061,7 @@ e.g.: <code>ffmpeg -f concat -safe 0 -i mylist.txt -c copy <i>output_file</i></c
<div class="modal-content">
<div class="well">
<h3>Transcode an image sequence into uncompressed 10-bit video</h3>
<p><code>ffmpeg -f image2 -framerate 24 -i <i>input_file_%06d.ext</i> -c:v v210 -an <i>output_file</i></code></p>
<p><code>ffmpeg -f image2 -framerate 24 -i <i>input_file_%06d.ext</i> -c:v v210 <i>output_file</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-f image2</dt><dd>forces the image file de-muxer for single image files</dd>
@@ -1950,7 +2069,6 @@ e.g.: <code>ffmpeg -f concat -safe 0 -i mylist.txt -c copy <i>output_file</i></c
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file<br>
This must match the naming convention actually used! The regex %06d matches six digits long numbers, possibly with leading zeroes. This allows to read in ascending order, one image after the other, the full sequence inside one folder. For image sequences starting with 086400 (i.e. captured with a timecode starting at 01:00:00:00 and at 24 fps), add the flag <code>-start_number 086400</code> before <code>-i input_file_%06d.ext</code>. The extension for TIFF files is .tif or maybe .tiff; the extension for DPX files is .dpx (or eventually .cin for old files).</dd>
<dt>-c:v v210</dt><dd>encodes an uncompressed 10-bit video stream</dd>
<dt>-an copy</dt><dd>no audio</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p class="link"></p>
@@ -1994,12 +2112,12 @@ e.g.: <code>ffmpeg -f concat -safe 0 -i mylist.txt -c copy <i>output_file</i></c
<div class="modal-content">
<div class="well">
<h3>Change field order of an interlaced video</h3>
<p><code>ffmpeg -i <i>input_file</i> -c:v prores -filter:v setfield=tff <i>output_file</i></code></p>
<p><code>ffmpeg -i <i>input_file</i> -c:v <i>video_codec</i> -filter:v setfield=tff <i>output_file</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-filter:v <i>setfield=tff</i></dt><dd>Sets the field order to top field first. Use <code>setfield=bff</code> for bottom field first.</dd>
<dt>-c:v prores</dt><dd>Tells ffmpeg to transcode the video stream into Apple ProRes 422. Experiment with using other codecs.</dd>
<dt>-c:v <i>video_codec</i></dt><dd>As a video filter is used, it is not possible to use <code>-c copy</code>. The video must be re-encoded with whatever video codec is chosen, e.g. <code>ffv1</code>, <code>v210</code> or <code>prores</code>.</dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file</dd>
</dl>
<p class="link"></p>
@@ -2123,34 +2241,55 @@ e.g.: <code>ffmpeg -f concat -safe 0 -i mylist.txt -c copy <i>output_file</i></c
</div>
</div>
<!-- ends Generate Video Fingerprint -->
</div><!-- closes the well -->
<div class="well">
<h4>Repair</h4>
<!-- Fix A/V async 1 -->
<span data-toggle="modal" data-target="#avsync_aresample"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Fix A/V sync issues by resampling audio">Fix AV Sync: Resample audio</button></span>
<div id="avsync_aresample" class="modal fade" tabindex="-1" role="dialog">
<!-- Strip metadata -->
<span data-toggle="modal" data-target="#strip_metadata"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Strip metadata">Strip metadata</button></span>
<div id="strip_metadata" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="well">
<h3>Fix AV Sync: Resample audio</h3>
<p><code>ffmpeg -i <i>input_file</i> -c:v copy -c:a pcm_s16le -af "aresample=async=1000" <i>output_file</i></code></p>
<h3>Strips metadata from video file</h3>
<p><code>ffmpeg -i <i>input_file</i> -map_metadata -1 -c:v copy -c:a copy <i>output_file</i></code></p>
<dl>
<dt>ffmpeg</dt><dd>starts the command</dd>
<dt><i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-c:v copy</dt><dd>Copy all mapped video streams.</dd>
<dt>-c:a pcm_s16le</dt><dd>Tells ffmpeg to encode the audio stream in 16-bit linear PCM (<a href="https://en.wikipedia.org/wiki/Endianness#Little-endian" target="_blank">little endian</a>)</dd>
<dt>-af "aresample=async=1000"</dt><dd>Stretch/squeezes samples to given timestamps, with maximum of 1000 samples per second compensation <a href="https://ffmpeg.org/ffmpeg-filters.html#aresample-1" target="_blank">[more]</a></dd>
<dt><i>output_file</i></dt><dd>path, name and extension of the output file. Try different file extensions such as mkv, mov, mp4, or avi.</dd>
<dt>-i <i>input_file</i></dt><dd>path, name and extension of the input file</dd>
<dt>-map_metadata -1</dt><dd>sets metadata copying to -1, which copies nothing</dd>
<dt>-vcodec copy</dt><dd>copies video track</dd>
<dt>-acodec copy</dt><dd>copies audio track</dd>
<dt><i>output_file</i></dt><dd>Makes copy of original file and names output file</dd>
</dl>
<p class="link"></p>
</div>
</div>
</div>
</div>
<!-- ends Fix A/V async 1 -->
</div><!-- closes the well -->
<!-- ends Strip metadata -->
<!-- Scene Detection using YDIF -->
<span data-toggle="modal" data-target="#csv-ydif"><button type="button" class="btn btn-default" data-toggle="tooltip" data-placement="bottom" title="Exports CSV for scene detection using YDIF">CSV with timecodes and YDIF</button></span>
<div id="csv-ydif" class="modal fade" tabindex="-1" role="dialog">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="well">
<h3>Exports CSV for scene detection using YDIF</h3>
<p><code>ffprobe -f lavfi -i movie=<i>input_file</i>,signalstats -show_entries frame=pkt_pts_time:frame_tags=lavfi.signalstats.YDIF -of csv</code></p>
<p>This ffprobe command prints a CSV correlating timestamps and their YDIF values, useful for determining cuts.</p>
<dl>
<dt>ffprobe</dt><dd>starts the command</dd>
<dt>-f lavfi</dt><dd>uses the <a href="http://ffmpeg.org/ffmpeg-devices.html#lavfi" target="_blank">Libavfilter input virtual device</a> as chosen format</dd>
<dt>-i movie=<i>input file</i></dt><dd>path, name and extension of the input video file</dd>
<dt>,</dt><dd>comma signifies closing of video source assertion and ready for filter assertion</dd>
<dt>signalstats</dt><dd>tells ffprobe to use the signalstats command</dd>
<dt>-show_entries</dt><dd>sets list of entries to show per column, determined on the next line</dd>
<dt>frame=pkt_pts_time:frame_tags=lavfi.signalstats.YDIF</dt><dd>specifies showing the timecode (<code>pkt_pts_time</code>) in the frame stream and the YDIF section of the frame_tags stream</dd>
<dt>-of csv</dt><dd>sets the output printing format to CSV. <code>-of</code> is an alias of <code>-print_format</code>.</dd>
</dl>
<p class="link"></p>
</div>
</div>
</div>
</div>
<!-- ends sample Scene Detection using YDIF -->
<!-- sample example -->
@@ -2177,6 +2316,7 @@ Change the above data-target field, the hover-over description, the button text,
<!-- ends sample example -->
</div>
</div> <!-- end "well col-md-6 col-md-offset-2" -->
</div> <!-- row -->

View File

@@ -10,7 +10,17 @@ To facilitate better understanding of FFmpeg through collaborative sharing of us
## How do I see it?
The code is found in the gh-pages branch (the default primary branch). Readme is right here. You can see the site live on [GitHub pages](http://amiaopensource.github.io/ffmprovisr), or you can download a [release](https://github.com/amiaopensource/ffmprovisr/releases) and use it locally.
The code is found in the gh-pages branch (the default primary branch). Readme is right here. You can see the site live on [GitHub pages](http://amiaopensource.github.io/ffmprovisr).
You can also install the latest [release](https://github.com/amiaopensource/ffmprovisr/releases) on your computer with the command:
```
brew install amiaopensource/amiaos/ffmprovisr
```
and then call it locally with the command:
```
ffmprovisr
```
This works currently under macOS, Linux and the Linux subsystem on Windows. On classic Windows you can install the last [release](https://github.com/amiaopensource/ffmprovisr/releases) manually and the open `index.html` in a browser.
## How do I contribute?
@@ -22,7 +32,7 @@ To contribute to this project directly (and more quickly), clone this repository
#### Make a request
If you are having trouble with coding it yourself or with github, feel free to [submit an issue](https://github.com/amiaopensource/ffmprovisr/issues) with the kind of command you would like to see added to the site.
If you are having trouble with coding it yourself or with GitHub, feel free to [submit an issue](https://github.com/amiaopensource/ffmprovisr/issues) with the kind of command you would like to see added to the site.
#### General help
@@ -39,7 +49,7 @@ You can read our contributor code of conduct [here](https://github.com/amiaopens
## Contributors
* Gathered using [octohatrack](https://github.com/LABHR/octohatrack)
GitHub Contributors:
*GitHub Contributors*:
ablwr (Ashley)
dericed (Dave Rice)
edsu (Ed Summers)
@@ -48,33 +58,38 @@ kfrn (Katherine Frances Nagels)
kgrons (Kathryn Gronsbell)
kieranjol (Kieran O'Leary)
llogan (Lou)
pjotrek-b (Peter B.)
privatezero (Andrew Weaver)
retokromer (Reto Kromer)
rfraimow
All Contributors:
*All Contributors*:
ablwr (Ashley)
audiovisualopen
brainwane (Sumana Harihareswara)
bturkus
dericed (Dave Rice)
edsu (Ed Summers)
Fizz24
jamessam (Jim)
jamessam (Jim Sam)
jfarbowitz (Jonathan Farbowitz)
jronallo (Jason Ronallo)
kellyhaydon (metacynic)
kfrn (Katherine Frances Nagels)
kgrons (Kathryn Gronsbell)
kieranjol (Kieran O'Leary)
llogan (Lou)
mulvya
pjotrek-b (Peter B.)
privatezero (Andrew Weaver)
retokromer (Reto Kromer)
rfraimow
richardpl (Paul B Mahol)
todrobbins (Tod Robbins)
Repo: amiaopensource/ffmprovisr
GitHub Contributors: 11
All Contributors: 18
GitHub Contributors: 12
All Contributors: 22
## AVHack Team

View File

@@ -1,19 +1,19 @@
#!/usr/bin/env bash
SCRIPT=$(basename "${0}")
VERSION='2017-04-17'
VERSION='2017-07-08'
AUTHOR='ffmprovisr'
RED='\033[1;31m'
BLUE='\033[1;34m'
NC='\033[0m'
if [[ ${OSTYPE} = "cygwin" ]] || [ ! $(which diff) ]; then
if [[ "${OSTYPE}" = "cygwin" ]] || [ ! $(which diff) ]; then
echo -e "${RED}Error: 'diff' is not installed by default. Please install 'diffutils' from Cygwin.${NC}"
exit 1
fi
_output_prompt(){
cat <<EOF
Usage: ${SCRIPT} -h | -i <av_file> -m <md5_file>
Usage: ${SCRIPT} -i <av_file> -m <md5_file> | -h
EOF
exit 1
}
@@ -21,13 +21,11 @@ EOF
_output_help(){
cat <<EOF
Syntax:
${SCRIPT}
Prompts a short help message.
${SCRIPT} -h
This help.
${SCRIPT} -i <av_file> -m <md5_file>
Pass to the script the audio-visual file and the corresponding MD5
file to check.
${SCRIPT} -h
This help.
Dependency:
ffmpeg
About:
@@ -40,11 +38,11 @@ EOF
unset input_file
unset input_hash
while getopts ":hi:m:" opt; do
while getopts ":i:m:h" opt; do
case "${opt}" in
i) input_file=${OPTARG} ;;
m) input_hash=${OPTARG} ;;
h) _output_help ;;
i) input_file=$OPTARG ;;
m) input_hash=$OPTARG ;;
:) echo -e "${RED}Error: option -${OPTARG} requires an argument${NC}" ; _output_prompt ;;
*) echo -e "${RED}Error: bad option -${OPTARG}${NC}" ; _output_prompt ;;
esac
@@ -59,12 +57,12 @@ else
md5_tmp="${HOME}/$(basename "${input_hash}").tmp"
fi
# Find audio frame size for hash calculation
unset sample_rate
sample_rate=$(grep -v '^#' "${input_hash}" | head -n 1 | tr -d ' ' | cut -d',' -f4)
ffmpeg -i "${input_file}" -loglevel 0 -af "asetnsamples=n='$sample_rate'" -f framemd5 -vn "${md5_tmp}"
[[ ! -f ${md5_tmp} ]] && { echo -e "${RED}Error: '${input_file}' is not a valid audio-visual file.${NC}" ; _output_prompt ; }
unset old_file
unset tmp_file
unset sample_rate
old_file=$(grep -v '^#' "${input_hash}")
tmp_file=$(grep -v '^#' "${md5_tmp}")
if [[ "${old_file}" = "${tmp_file}" ]]; then

View File

@@ -1,19 +1,19 @@
#!/usr/bin/env bash
SCRIPT=$(basename "${0}")
VERSION='2017-04-17'
VERSION='2017-07-08'
AUTHOR='ffmprovisr'
RED='\033[1;31m'
BLUE='\033[1;34m'
NC='\033[0m'
if [[ ${OSTYPE} = "cygwin" ]] || [ ! $(which diff) ]; then
if [[ "${OSTYPE}" = "cygwin" ]] || [ ! $(which diff) ]; then
echo -e "${RED}Error: 'diff' is not installed by default. Please install 'diffutils' from Cygwin.${NC}"
exit 1
fi
_output_prompt(){
cat <<EOF
Usage: ${SCRIPT} -h | -i <av_file> -m <md5_file>
Usage: ${SCRIPT} -i <av_file> -m <md5_file> | -h
EOF
exit 1
}
@@ -21,13 +21,11 @@ EOF
_output_help(){
cat <<EOF
Syntax:
${SCRIPT}
Prompts a short help message.
${SCRIPT} -h
This help.
${SCRIPT} -i <av_file> -m <md5_file>
Pass to the script the audio-visual file and the corresponding MD5
file to check.
${SCRIPT} -h
This help.
Dependency:
ffmpeg
About:
@@ -40,11 +38,11 @@ EOF
unset input_file
unset input_hash
while getopts ":hi:m:" opt; do
while getopts ":i:m:h" opt; do
case "${opt}" in
i) input_file=${OPTARG} ;;
m) input_hash=${OPTARG} ;;
h) _output_help ;;
i) input_file=$OPTARG ;;
m) input_hash=$OPTARG ;;
:) echo -e "${RED}Error: option -${OPTARG} requires an argument${NC}" ; _output_prompt ;;
*) echo -e "${RED}Error: bad option -${OPTARG}${NC}" ; _output_prompt ;;
esac
@@ -53,7 +51,7 @@ done
[[ -z "${#}" || ! ${input_file} || ! ${input_hash} ]] && _output_prompt
echo -e "${BLUE}Please wait...${NC}"
unset md5_tmp
if [[ $OSTYPE = "cygwin" ]]; then
if [[ "${OSTYPE}" = "cygwin" ]]; then
md5_tmp="${USERPROFILE}/$(basename "${input_hash}").tmp"
else
md5_tmp="${HOME}/$(basename "${input_hash}").tmp"

View File

@@ -1,14 +1,21 @@
#!/usr/bin/env bash
if [[ $OSTYPE = darwin* ]] ; then
# This allows to open ffmprovisr locally from the terminal.
if [[ "$(uname -s)" = "Darwin" ]] ; then
default_browser=$(plutil -convert json ~/Library/Preferences/com.apple.LaunchServices/com.apple.launchservices.secure.plist -r -o - | grep https -b1 | tail -n1 | cut -d'"' -f4)
if [ -d /usr/local/Cellar/ffmprovisr ] ; then
ffmprovisr_path=$(find /usr/local/Cellar/ffmprovisr -iname 'index.html' | sort -M | tail -n1)
fi
if [ -z "${ffmprovisr_path}" ] ; then
ffmprovisr_path='https://amiaopensource.github.io/ffmprovisr/'
fi
open "${ffmprovisr_path}"
elif [[ $OSTYPE = linux-gnu ]] ; then
if [ -n "${default_browser}" ] ; then
open -b "${default_browser}" "${ffmprovisr_path}"
else
open "${ffmprovisr_path}"
fi
elif [[ "$(uname -s)" = "Linux" ]] ; then
if [ -d ~/.linuxbrew/Cellar/ffmprovisr ] ; then
ffmprovisr_path=$(find ~/.linuxbrew/Cellar/ffmprovisr -iname 'index.html' | sort -M | tail -n1)
fi