ALL 10 TUTORIAL APPENDICES IN FULL:
I have made numerous additions and enhancements to my FFmpeg and mpv tutorial. So much has been added, in fact, that I have now exceeded the 60,000 character limit!
As a result, I had to free up space by removing several appendices from my tutorial's main page:
TUTORIAL: Play or Encode High-Quality Video and Audio – with FFmpeg and mpv
I am therefore including all 10 appendices in this (separate) post:
APPENDIX 1: MOST ESSENTIAL MPV KEYBOARD CONTROLS AND OPTIONS:
Toggle the video between full screen and actual size
Toggle the video (or audio) between pause and play
left and right arrow keys:
Rewind and fast-forward by 6 seconds
up and down arrow keys:
Rewind and fast-forward by 1 minute
9 and 0 keys:
Lower and raise the volume
Make the on-screen display briefly appear to show time remaining, etc.
[ and ] keys:
Speed up or slow down the video
Quit out of the video (or audio)
REMINDER: Be sure to close any open Terminal windows before you use mpv, or you will lose keyboard control.
CUSTOMIZE MPV's BEHAVIOR:
If you wish to customize things further, you can always modify mpv's configuration file (mpv.conf). The mpv.conf file is a standard text file (but with a ".conf" extension) that can be quickly modified with the standard Text Editor. It's located at /home/pi/.config/mpv (you may have to temporarily click View | Show Hidden in order to see these hidden files and folders in File Manager). In my instructions, I already included 2 of the most useful customizations inside the mpv.conf file:
<---This forces all videos, both large and small, to automatically expand to fill your screen. To prevent any distortion, this option always maintains the native aspect ratio of the video. By design, it will never "stretch" or "squeeze" the video to fit the shape of your monitor or TV. But as long as the video's aspect ratio matches the aspect ratio of your screen, the video will completely and perfectly FILL the screen. For example, if you have a 480p, 720p or 1080p video (all of which would normally have a 16:9 aspect ratio) – and you also have a monitor or TV with a 16:9 aspect ratio – then your entire screen will be filled with active pixels.
<---Sometimes, you may watch an old video – or one that's simply not as "wide" as a 16:9 aspect ratio. For example, you might have an old video from a VHS tape with a low resolution of 320 x 240 (a 4:3 aspect ratio). Or you might have a DVD video with a resolution of 720 x 480 (a 3:2 aspect ratio). Either way, these videos are not "wide" enough to perfectly fit the shape of a modern 16:9 display without being stretched or distorted. In those cases, the "rpi-background=yes" option will automatically add black bars to the left and right sides of your screen so that there are no visual distractions in the background!
<---I did NOT add this option in my instructions because many people would not want this particular behavior. But if you're using your Raspberry to power a display at a trade show or other event, for example, this is a great way to make the video automatically play over and over again.
<---This mpv.conf line will force a 1080p video to play at only 4% of the total surface area of a 1080p monitor or TV – and it will place it in the upper-left corner of your screen. NOTE: In case you're wondering how 20% becomes 4%, it all comes down to understanding the difference between linear dimensions and surface dimensions. Assuming the native resolution of the video is the same as your screen's resolution, 20% smaller across the X axis AND 20% smaller across the Y axis means the video would only cover 4% of your screen's total surface area (20% x 20% = 4%).
<---And what if I want a tiny video to appear in the upper-right corner of my screen? For this mpv.conf example, simple math is in order: My 1080p monitor is 1920 pixels across. 20% of 1920 is 384. And 1920 - 384 = 1536. That means the upper-left corner of the video should start at 1536 on the X axis and 0 on the Y axis. In both of these examples, tapping the "f" key will instantly toggle the video back and forth between FULL SCREEN and TINY SCREEN. Mpv handles it beautifully in the blink of an eye.
TAKE MANUAL CONTROL OF MPV:
The contents of the mpv.conf file affects mpv's "fundamental" behavior. In other words, it will always affect the way mpv behaves when it plays video and audio. But for some options, you can temporarily invoke a behavior on a one-time basis without modifying your mpv.conf file. Generally, this only works for options that begin with 2 dashes (--). For example, let's say you do NOT have the "--loop" option in your mpv.conf file, but you still want to launch a video with that behavior on a one-time basis. To do that, you can manually launch the video inside Terminal (instead of double-clicking it in File Manager as you would normally do). Here are some common syntax examples for manual launching of multimedia files:
This is the MANUAL way to play a video with mpv. Normally, as I just mentioned, you would simply double-click the file and it would automatically start playing – but I'm including these manual examples for the benefit of interested users. In this example, we are NOT invoking any special options (other than what's already in your mpv.conf file). It also assumes that Terminal is currently open inside the same folder as your video:
This manually instructs the video to loop continuously (in addition to whatever else your mpv.conf file may have it do). It also assumes that Terminal is currently open inside the same folder as your video:
mpv --loop video.mp4
This does the same thing as Example B, but it does so for a video that's in a completely different folder than the one Terminal is currently located in (which is normally your "home" folder by default – /home/pi). In other words, in this example, you're using the FULL DIRECT PATH to the video. The full path to a file can be easily obtained by right-clicking any file in File Manager and selecting "Copy Path(s)". This syntax is necessary whenever Terminal and the video are in different locations:
mpv --loop /home/pi/vacations/hawaii/video.mp4
This also does the same thing as Example B, but it places the full path inside standard quote marks. Why is this important? You must do this any time there are SPACES in the file path. That's a Linux thing, not a mpv thing. For example:
mpv --loop "/home/pi/truly awesome vacations/hawaii/video.mp4"
MPV HAS HUNDREDS OF OTHER OPTIONS AND FEATURES:
For complete details, please review the extremely thorough manual at mpv's official website
APPENDIX 2: DOWNLOAD AND RETAIN HIGH-QUALITY VIDEOS FROM HUNDREDS OF WEBSITES – WITH YOUTUBE-DL:
Although youtube-dl is available in the Raspbian software repository, it’s nearly a year old. To acquire the very latest version from youtube-dl's official website, enter the following two command lines, one at a time, in the Terminal window:
sudo curl -L https://yt-dl.org/downloads/latest/youtube-dl -o /usr/local/bin/youtube-dl
sudo chmod a+rx /usr/local/bin/youtube-dl
DOWNLOADING MP4 VIDEOS (H.264 / AAC):
Let’s say you have your Raspberry hooked up to a high-definition 1920 x 1080 monitor or TV and you wish to download and enjoy a NASA video, at maximum resolution and quality, of two neutron stars colliding – with the screen completely filled-up by the video. Here’s how you do that with youtube-dl:
Identify the URL of the page that contains the video you want. In this example, it’s a YouTube video at the following URL:
Open the Terminal window and enter the following code (make sure you use a capital “-F”):
youtube-dl -F https://www.youtube.com/watch?v=x_Akn8fUBeQ
You will then see an impressive list of all the different audio and video formats that the YouTube server has available for the NASA video. If you look carefully, you will see there’s a video track with a resolution of 1920 x 1080 that uses the “avc1” codec at 30 FPS (Frames Per Second). “AVC1” is simply another name for the H.264 codec. The Raspberry’s GPU has been specifically optimized to play H.264 video with full-blown hardware acceleration. On the far left column, you will see a “format code” for that particular video format. In this case, it’s code “137”. You will also see a high-quality audio track that’s described as an “m4a” with a sampling rate of 44100Hz. That’s YouTube's terminology for an AAC audio track. It has format code “140”. It's the best choice for this example, since an AAC audio track is specifically designed to work with an H.264 video track when creating an MP4 video. To download the high-resolution video (with sound), you will therefore issue the following command (make sure you use a lower-case “-f”):
1920 x 1080 MP4 – 30 FPS:
youtube-dl -f 137+140 https://www.youtube.com/watch?v=x_Akn8fUBeQ
Once the download is complete, be sure to close the Terminal window or you will lose keyboard control of mpv.
Then, simply double-click the MP4 video you just downloaded and mpv will automatically start playing it full screen! If you downloaded a resolution smaller than your screen, you can tap the "f" key to toggle back and forth between actual size and full screen mode.
DOWNLOADING WEBM VIDEOS (VP9 / Opus):
If you want a much smaller file size at a surprisingly high quality – albeit with lower resolutions of 720p or 480p – the “VP9” format for video and the “Opus” format for audio are the ones you want. They are the most advanced compression technologies currently available. The two tracks will be automatically combined by youtube-dl (using the FFmpeg engine) and merged into a standard WebM video. Be aware that the Raspberry’s GPU is only designed to provide full hardware acceleration for MP4 videos using H.264 – so a 1080p VP9-based WebM video will push your Raspberry to the absolute limit and will likely result in at least some stutter. That's why I recommend 720p and 480p resolutions for VP9-based videos. They also, of course, should not exceed 30 FPS. Finally, if you wish to share the video with someone else who doesn’t have an advanced player like mpv, it’s best to stick with a standard H.264-based MP4 video for compatibility reasons. For the NASA video, here are the two best command lines if you want smaller file sizes (for example, if you're using a cellular connection and need to conserve your data usage). When it's competently encoded by the uploader, I've been consistently amazed by how good a humble 480p video can look when viewed full screen on my large 24 inch 1080p monitor.
1280 x 720 WEBM – 30 FPS:
youtube-dl -f 247+249 https://www.youtube.com/watch?v=x_Akn8fUBeQ
854 x 480 WEBM – 30 FPS:
youtube-dl -f 244+249 https://www.youtube.com/watch?v=x_Akn8fUBeQ
HIGH FRAME-RATE CAPABILITY:
In my testing, I was surprised to discover that the Raspberry’s GPU can handle 1920 x 1080 H.264 video at DOUBLE the normal frame rate – 60 FPS without dropping even one frame! Some newer videos on YouTube are now available in 60 FPS format, and the NASA video is one of them. If you wish to download the 60 FPS version of the above 1080p video, you would simply change the video format code from 137 to 299. In other words, you would use this command line instead:
1920 x 1080 MP4 – 60 FPS:
youtube-dl -f 299+140 https://www.youtube.com/watch?v=x_Akn8fUBeQ
Don't assume the format codes will always be the same. YouTube is quite consistent – but even with them, the available formats can vary from one video to another. For example, I've noticed that YouTube's servers will often place different formats in a queue, prioritizing H.264 over VP9. Even for the mighty Google, encoding video is very computationally intensive and time consuming – so it makes sense for them to quickly get the H.264 version up on their server, and then process the VP9 version an hour or half hour later. Other video sites, however, use completely different format codes and are typically limited to H.264 videos – so for them, you'll want to first run youtube-dl's "-F" option (capital F), as explained above, to see exactly what formats are available. Finally, be aware that most other sites tend to integrate the video and audio tracks into a single pre-packaged MP4 video – so there won't be separate video and audio formats to choose from. YouTube does this as well, by the way. It's usually listed in the last couple lines of their available formats. In YouTube's case, you'll know if everything's already been combined if it says both "avc1" and "mp4a" in the description. In those cases, you would not use the "+" symbol. Instead, you would simply use a single format code.
YOUTUBE-DL HAS MANY OTHER FEATURES AND CAPABILITIES:
To learn more, visit youtube-dl's official website
APPENDIX 3: PLAY ONLINE VIDEOS AUTOMATICALLY WITH MPV (WITHOUT ANY MANUAL DOWNLOADING):
Personally, I like to review all the available video and audio formats before I download a video. If it's a concert or music video, I may want to enjoy it multiple times. By downloading it, as described in Appendix 2, I have immediate access to it at the highest quality – even if I'm offline. Downloading is also crucial if you're using a cellular data connection and need to conserve your data. Even with an "unlimited" plan, your carrier may still throttle back your speed once you reach a monthly limit. For those instances, I've found that 480p videos that use the advanced VP9 video codec and Opus audio codec at 50 or 70 kbps are the perfect balance between file size and quality. In an HD aspect ratio, they typically have resolutions of 854 x 480. For a relatively small video, they look surprisingly good on my large 1080p monitor in full screen mode. Of course, if you want the absolute best in quality on a 1080p screen and data use is not a concern, there's nothing like a 1080p video.
In many cases, however, data use may not be a concern. You also may not have any desire to manually download (and retain) the video. And finally, you may not really care if you're viewing the most optimal format and quality – because you just want to watch a video without any thought. In those cases, I have configured my procedure to support tight integration between mpv and youtube-dl. As long as you have properly followed this tutorial and have installed a recent copy of youtube-dl (see Appendix 2), all you have to do is enter a URL after the mpv command! That will automatically invoke youtube-dl, which will start downloading the first several seconds of the video (invisibly as a background process). It does this to create a sufficient cache to help prevent buffering interruptions while playing. Once it's done that, mpv will automatically start playing the video! Generally, when operating in this mode, youtube-dl's algorithm will attempt to choose the "best quality" version of the video. It works well on leading video sites like YouTube, but there are no guarantees with less sophisticated websites. If you're unsatisfied with the results on other sites, nothing of course beats a manual review of the available formats (as described in Appendix 2).
As an example, if you want to automatically play the NASA video mentioned in Appendix 2, this simple command line is all it takes:
APPENDIX 4: STREAM LIVE TELEVISION FROM AROUND THE WORLD:
Not only can you "download and play" and "auto play" videos from sites like YouTube, you can also use the mpv / youtube-dl combination to stream live television broadcasts from around the world. This is often referred to as IPTV – Internet Protocol TV.
Quality television requires considerable resources to produce – so most high-end content is not freely available. But there are a few sources of free, high-quality streaming content. These are typically government-funded broadcasters that wish to freely share their nation's culture and perspective with the larger world. Perhaps the best examples of this are the national broadcasters of Australia, Germany, Japan, and France.
All four of these broadcasters make their live TV streams openly and freely available on their public websites – so they definitely want people to watch them!
You can also watch these feeds from inside the Raspberry's web browser – but that typically results in stuttering video. Mpv provides a much smoother, customizable, full-screen experience.
All four networks offer live, 24-hour TV news that is generally regarded as relatively fair and journalistically professional. To the best of my knowledge, these are the only "reputable" sources of FREE
TV news from major, internationally-recognized outlets that broadcast in English. The BBC, though also very reputable, limits its TV streams to UK citizens and paying international subscribers only. There are other free "news" broadcasts available – but many of them act as propaganda outlets for various dictatorships around the world.
In my testing, it usually took about 10 seconds from the moment I entered the following command lines until the live TV broadcasts appeared (youtube-dl has to first analyze the stream before it hands it off to mpv, which then buffers and plays it). Technically, due to buffering and other factors, you will see these broadcasts on a slight "tape delay". In other words, as you're watching the news, you're actually seeing it between 10 and 50 seconds in the past. I calculated the typical delays by noting the exact moment the "top of the hour" broadcasts appeared and compared those times to an atomically-synchronized clock. Though interesting, this tiny delay obviously has no meaningful impact on the value of these feeds.
If you're a "cord cutter" and have cancelled your cable or satellite TV, there are also legitimate IPTV subscription services that will provide dozens or hundreds of streams for a monthly fee.
Here, now, are the four best freely available sources of live, international TV news. For each broadcaster, the first command line will simply cause mpv to play the stream. The second command line will play the stream AND
save the video to your system. Be aware that this recording capability is an EXPERIMENTAL
feature of mpv with absolutely no guarantees – although it worked quite well in my testing of these four news sites. My suggested command lines will save the video as a ".ts" file to /home/pi (you can change the path to any location you wish). As with MP4s and virtually all other video formats, you can associate ".ts" files with mpv so that double-clicking the recorded files will automatically play them:
AUSTRALIA – ABC News – Australian Broadcasting Corporation
[640 x 360; 6.8 MB per minute; H.264 stream]
mpv https://abcnews24mha-lh.akamaihd.net/i/[email protected]
mpv https://abcnews24mha-lh.akamaihd.net/i/[email protected]
GERMANY – DW News – Deutsche Welle
[720 x 400; 13.5 MB per minute; H.264 stream]
mpv https://dwstream4-lh.akamaihd.net/i/[email protected]
mpv https://dwstream4-lh.akamaihd.net/i/[email protected]
JAPAN – NHK World – Japan Broadcasting Corporation
[1280 x 720; 9.4 MB per minute; H.264 stream]
mpv https://nhkwtvglobal-i.akamaihd.net/hls/live/263941/nhkwtvglobal/index_1180.m3u8 --record-file="/home/pi/Japan_News.ts"
FRANCE – France 24 – France Vingt-Quatre
[1024 x 576; 8.2 MB per minute; H.264 stream]
mpv http:\/\/static.france24.com\/live\/F24_EN_LO_HLS\/live_web.m3u8 --record-file="/home/pi/France_News.ts"
The URLs in the above command lines could change or expire at any time
– so you may have to search for updated m3u8 streams – or use the technique I developed which appears below. If you get an error message that mentions "[ytdl_hook]" and it says "unable to download webpage", or you see a reference to "HTTP error 403", the URL is either temporarily down or has expired and become a dead link. The source for the above news streams is located at the LegalStream GitHub site
. Finally, in addition to my build of mpv, you must of course have youtube-dl for the streaming function to work (preferably the latest version; see Appendix 2 for details). Hat tip to user "johndavies" for his suggestion to include streaming news!
FIND THE LATEST STREAMING URLs ON YOUR OWN
Since these m3u8 streaming links can change or expire at any time, I developed the following technique to obtain the latest streaming URL for a major national broadcaster. In this case, I'm using the live TV news feed from the Australian Broadcasting Corporation as an example (the same outlet listed above). My method has the added advantage of getting the URL "straight from the source" rather than a third-party website that may have old links. It also lets you choose the resolution (and corresponding data usage). Keep in mind that although I'm using ABC News as an example, my basic approach will work on other websites as well
. Whether or not it works on any particular site depends on what's available in the HTML code! Technical Note: URLs that end with m3u8 use the HLS streaming protocol, the most popular modern standard (the other leading streaming standard is the DASH protocol, which is heavily used by YouTube).
Visit the ABC News channel at this URL:
NOTE: This must be done with Chromium – the built-in web browser that comes with the Raspbian operating system. If you can do it with an alternate browser, that's fine too – just know that I have only tested it with Chromium.
On your keyboard, press CTRL + S. (You can also click the tiny button in the upper-right corner with the 3 vertical dots; then click "More tools"; then click "Save page as...")
In the bottom-right corner of the "Save File" window that appears, you'll see a drop-down button that lets you save the "Complete" web page or just the "HTML Only" version. For our purposes, you only need to save the "HTML Only" version. This has the added advantage of saving only ONE simple file to your system. Once you've set it to "HTML Only", make note of the folder it's saving it to. By default, the file will probably be called "ABC News (Australian Broadcasting Corporation).html". But to make things simple, change the file name to ABC.html and click the Save button!
Using File Manager, right-click the ABC.html file and then click Text Editor.
On your keyboard, press CTRL + F and do a text search for "m3u8" (no quotes). Note: Video streams can use extensions other than m3u8 – so if you're trying this technique on a different website, you can also search for URLs ending in .mpd, .f4m, .mp4, etc.
As of this writing, you'll find only one "hit" in the HTML code for "m3u8". It should appear at the very end of a URL that begins with http or https
That's it – that's the latest m3u8 streaming URL for ABC's 24-hour news channel! So carefully
copy that URL!
You can now place the "mpv" command right before that URL and start watching live TV news from Australia!
The URL I'm using below works perfectly at the time of this writing
– but you may need to occasionally repeat the above procedure to get the latest URL if the old one expires. It's also possible that this entire procedure will suddenly stop working due to a major change in the design of the ABC website. The m3u8 link could suddenly disappear from their HTML code, for example. Nonetheless, at the time of this writing, you would simply use one of the following command lines in Terminal:
VIEW AND RECORD:
mpv https://abc-iview-mediapackagestreams-1.akamaized.net/out/v1/50345bf35f664739912f0b255c172ae9/index.m3u8 --record-file="/home/pi/Australia_News.ts"
WANT TO GET MORE SOPHISTICATED?
I also figured out how to obtain ALL
the video formats that are currently available on the streaming server used by ABC! By "formats", I mean the many different resolutions that are available. In my testing, when you do Step 8 above, the server will automatically feed the highest-resolution format to your Raspberry (1024x576). But if you need to limit your data usage for whatever reason, it can be extremely useful to know how to access the other formats.
To do that, just follow these 2 simple steps:
Copy the m3u8 URL you obtained previously in Step 7 and use it with youtube-dl's "-F" command (capital F). Like this, for example:
youtube-dl -F https://abc-iview-mediapackagestreams-1.akamaized.net/out/v1/50345bf35f664739912f0b255c172ae9/index.m3u8
After a few seconds, you will get a response like this (truncated by me to only show what's relevant; estimated data usage also added by me):
Format Code........ Resolution........ Data Use Per Minute
365...................... 320x180............ 3.1 MB
691...................... 512x288............ 5.4 MB
932...................... 640x360............ 7.1 MB
1276.................... 800x450............ 9.3 MB
1826.................. 1024x576.......... 13.1 MB
Do you see the format codes and their corresponding resolutions? Simply pick one and use it with mpv's "--ytdl-format=" option like this:
VIEW ONLY – 512 x 288 RESOLUTION:
mpv --ytdl-format=691 https://abc-iview-mediapackagestreams-1.akamaized.net/out/v1/50345bf35f664739912f0b255c172ae9/index.m3u8
VIEW AND RECORD – 512 x 288 RESOLUTION:
mpv --ytdl-format=691 https://abc-iview-mediapackagestreams-1.akamaized.net/out/v1/50345bf35f664739912f0b255c172ae9/index.m3u8 --record-file="/home/pi/Australia_News.ts"
In the above command lines, I used format code "691" to retrieve the rather tiny 512x288 resolution format. If you're concerned about data usage, this actually might be the "best bang for the buck" as it looked surprisingly good at full screen on my large 1080p monitor. Feel free to replace the "691" format code with 365, 932, 1276 or 1826. Keep in mind, of course, that those are the available format codes as of this writing. In the future, you can re-do the above procedure to verify that those codes still apply – or to obtain new ones!
APPENDIX 5: SAMPLE FFMPEG COMMAND LINES – TO ENCODE OR PROCESS VIDEO AND AUDIO:
NOTE: In the following examples, simply right-click any folder that contains the media files you wish to encode or process and click “Open in Terminal”. Then, run the following command lines (changing the file names and settings where appropriate).
NOTE: Be aware that most of these examples will only work for those who did my entire tutorial without skipping any steps. In other words, your encoding capabilities will be much more limited if you only did the stripped-down "play-centric" version of my tutorial, which only builds and installs FFmpeg, mpv, and libass (but not the 5 advanced encoders).
TIP: Unless it's necessary, try not to have your media folder open in File Manager while FFmpeg is actively running (by "media folder", I mean the folder in which you're encoding and processing files with FFmpeg). Remember – you can select "Open in Terminal" without actually opening a folder. Depending on what kind of work you're doing, having a folder open (whether its contents are visible on your screen or not) can slow things down considerably – because File Manager will keep automatically refreshing its contents, thus unnecessarily wasting CPU cycles.
EXAMPLE 1: Convert an old AVI video (with sound) – or any other input video format you choose – into a modern MP4 (with H.264 video and AAC audio):
ffmpeg -i input.AVI -vf format=yuv420p -c:v libx264 -crf 23 -c:a libfdk_aac -b:a 128k output.MP4
NOTE: This example uses the higher-quality (but slower) x264 software-based encoder. That means there is no GPU hardware acceleration – however it does use a CPU optimization known as “NEON” that helps to speed up the encoding. The “-crf 23” setting is the default video quality and generally produces excellent results. The lower the number, the higher the encoding quality (at the expense of a larger file size). A setting of 18 is said to be “visually lossless” – but the file size will be almost double that of a 23 setting. Be aware that the number scale is non-linear – but as a rough rule of thumb, a change of 5 to 6 will double (or cut in half) the file size. In many cases, when a smaller file size is important, a setting of 26 still maintains a high-quality appearance. Finally, the “-c:a libfdk_aac -b:a 128k” part indicates that the audio will be converted with the Fraunhofer AAC codec, at a bit rate of 128 kbps.
EXAMPLE 2: Resize a large “1080p” MP4 video (1920 x 1080) with sound into a smaller “480p” MP4 video (854 x 480) with sound – without (unnecessarily) re-encoding the original audio:
ffmpeg -i input.MP4 -vf "format=yuv420p, scale=854:480:flags=lanczos" -c:v libx264 -crf 23 -c:a copy output.MP4
NOTE: In the above FFmpeg command line, "-c:a copy" means that the audio track in the input file will be directly COPIED over to the output file without any transcoding (re-encoding). If you're certain the original audio is already in the desired format, that is the best course of action – because any additional encoding of an already-encoded file will result in some degradation in quality. If, however, the original audio is in the MP3 format (for example) and for some reason you want the output video to use ACC audio instead, then you would simply replace the "-c:a copy" with "-c:a libfdk_aac -b:a 128k".
EXAMPLE 3: Extract every frame from a 30 FPS MP4 video and output it as a padded, 7-digit numerical JPEG image sequence:
ffmpeg -i video.mp4 -vf fps=30 -q:v 2 %07d.jpg
EXAMPLE 4: Convert an alphanumeric image sequence of JPEG pictures into a 30 FPS MP4 video:
ffmpeg -framerate 30 -pattern_type glob -i "*.jpg" -vf format=yuv420p -c:v libx264 -crf 23 output.MP4
EXAMPLE 5: Add a transparent overlay – such as text or a logo – on top of a video:
ffmpeg -i input.MP4 -i overlay.png -filter_complex "[0:v][1:v] overlay=0:0" -c:v libx264 -crf 23 -c:a copy output.MP4
NOTE: The “overlay.png” file must be a transparent PNG file (with alpha channel) that includes your text or logo. This can be created with any standard image-manipulation program like GIMP or Photoshop. The dimensions of the overlay image should obviously be the same as the video's resolution. Also, in this particular example, the inputted MP4 video is assumed to have a proper sound track that can simply be copied over without re-encoding. If the sound requires encoding, simply change “-c:a copy” to “-c:a libfdk_aac -b:a 128k”.
EXAMPLE 6: Use the hardware-accelerated H.264 encoder to convert an AVI into an MP4:
ffmpeg -i input.AVI -c:v h264_omx -b:v 4500k -c:a copy output.MP4
NOTE: The hardware encoder, though about 3 times faster, has fewer options and generally, bit for bit, produces a decent but lower-quality result. The software-based encoder, which relies on the versatile and general-purpose CPU, provides the programmers maximum flexibility to use whatever coding techniques they like – but a hardware encoder, by its very nature, is constrained by the features the GPU supports. Like most things in life, there are pros and cons to each approach. In this example, the “-b:v 4500k” part indicates a bit rate of 4,500 kbps – which is generally good for a large 1080p video. Unlike the software-based encoder, there is no “crf” quality setting, since the hardware-based encoder uses bit rate as a proxy for quality. If your video is smaller than 1080p, you will obviously want to lower the bit rate accordingly – to 2,000, 1,500, etc. Finally, this example assumes the existing audio is already in an MP4-compatible format, such as an AAC or MP3, and can thus be copied over. Other audio formats are NOT compatible with the MP4 container – so if you need to transcode the audio to a compatible format, simply change “-c:a copy” to “-c:a libfdk_aac -b:a 128k”.
EXAMPLE 7: Create a WebM video with the highly-efficient VP9 video encoder and Opus audio encoder:
ffmpeg -y -i input.AVI -vf format=yuv420p -c:v libvpx-vp9 -b:v 480K -pass 1 -c:a libopus -b:a 64K -f webm /dev/null && \
ffmpeg -i input.AVI -vf format=yuv420p -c:v libvpx-vp9 -b:v 480K -pass 2 -c:a libopus -b:a 64K output.WEBM
NOTE: The entire two-line stanza that you see above should be pasted into Terminal as a single block of text. It uses a technique known as 2-pass encoding. On the first pass, it carefully analyzes the video's characteristics from start to finish. It then uses those insights to perform the actual encoding on the second pass. In this example, it's converting a 640 x 480 AVI at 30 FPS to a WebM – but you can choose almost any other video format as the input. As you can see, the input file name needs to be listed twice, but the output file name is only listed once (at the very end of the stanza). The "480K" is the video encoding rate – 480 Kbps (kiloBITS per second, not kiloBYTES). And the "64K" is the audio encoding rate – 64 Kbps. Those are the only values you need to adjust. 480K is a good, mid-range setting for a low-resolution 640 x 480 video. I analyzed the VP9 bit rates that YouTube uses by picking two extreme examples on the opposite ends of the "complexity spectrum". First, I looked at how they handle 640 x 480 videos: For a news show where the presenter is calmly sitting at a desk with a mostly static background, their systems chose an overall bit rate of only 340K. For a major outdoor concert with tons of visual complexity, lighting effects and motion, the overall bit rate shot up to 600K. I ignored the rates listed by the YouTube server – which are accessible via youtube-dl's "-F" option – because those appear to be theoretical maximum bit rates as opposed to the ACTUAL overall bit rate. Instead, my calculations are based on reality – I simply took the total size of the final video track (in bits) and divided by the duration of the video (in seconds). This is especially appropriate for the stanza in my example, because the rates you enter serve as your request for the OVERALL AVERAGE BIT RATE (not maximum, minimum, or anything else). I've tested it, and that's exactly what the VP9 encoder does – the final overall bit rate for the entire file comes out to whatever value you place in my stanza! Using the same method, my findings are that a good mid-range encoding rate for a 1920 x 1080 video is about 2000K. Be aware that the mathematical "scaling behavior" behind these algorithms is not entirely linear. For example, going from 640 x 480 to 1920 x 1080 increases the pixel count by a factor of 6.75 – but the encoding rate that's required to maintain the same visual quality only goes up by a factor of about 4 or 5. But again, whether it's high resolution or low resolution, the optimal bit rate depends on the overall scene complexity and motion levels inside the video. To give you some idea of the optimal range for 1080p, YouTube chose a rate of only 1300K for the news anchor sitting at a desk – and a rate of nearly 2500K for the visually intense concert. It's a pretty simple concept – every video is different and some are more demanding than others!
CRITICAL NOTE: When it comes to encoding a video, the H.264 / AAC combination – wrapped inside an MP4 container file – is almost always the way to go. For one thing, it's the only truly universal modern format. After all, what's the point of encoding a video if 20% or 50% of people can't view it on their device? For a whole bunch of complicated legal and business reasons, an MP4 video is the only modern format that's supported by all the major browser players – Google, Apple, and Microsoft. Thanks to a donation that pays for the licensing rights, even the non-profit Mozilla Foundation supports MP4 videos in the Firefox browser. The VP9 / Opus combination – wrapped inside a WebM container file – is more advanced and can achieve higher compression levels, but it has one giant problem: Apple doesn't support it! Globally, Apple's market share in the mobile space might be "only" 20%. But that's very misleading. Among well-off demographic groups in major countries, Apple's market share can easily exceed 80%! Although WebM is a truly open standard, its main backer is Google – which might explain why Apple still refuses to support it. It is what it is. However, if you're looking to impress your friends with the ultimate in encoding efficiency, nothing beats a WebM. Be aware, however, that there is one other big issue to consider when it comes to VP9 – especially on the Raspberry. That greater efficiency is computationally costly – VERY COSTLY! I used the above stanza on a test video with a low resolution of 640 x 480 (with medium-high motion and moderate complexity). Believe it or not, it took 5.6 MINUTES to encode every 1 SECOND of video! That's an encoding-to-playtime ratio of 336 to 1. So even if you let it run for 8 HOURS while you're sleeping, it would only encode about 85 SECONDS of 640 x 480 video! By comparison, the x264 encoder has a ratio of about 2 to 1 or 3 to 1 on a 640 x 480 video. In other words, it only takes about 2 to 3 seconds for x264 to encode each second of video – a speed that's more than 100 times faster than the VP9 encoder! Keep in mind that my testing only used a 640 x 480 video. If I were encoding a 1080p video with VP9, the ratio could easily increase to about 2,000 to 1! So why is the VP9 encoder so slow on the Raspberry? There are at least 4 reasons: (1) Apples and Oranges. The only time VP9 really shines compared to H.264 is if you're willing to throw extra computing muscle behind it. Now it's true that VP9 also supports 1-pass, constant bit-rate encoding – but my testing has shown that 1-pass encoding produces a file that's about the same size as an H.264. To top it off, my testing has also shown that VP9 1-pass encoding is only 35% faster than VP9 2-pass encoding. In other words, VP9 1-pass encoding still yields a very slow encoding ratio of 218 to 1. VP9 1-pass encoding, therefore, doesn't bring anything special to the table – especially since WebM is less universally compatible to begin with. So if you're going to the trouble to make a WebM, you might as well go "all in" and make one that shines. With the right settings, you can create a WebM video that's HALF the file size of an MP4 – with no obvious difference in visual quality! But the only way to achieve that is with 2-pass encoding. Unfortunately, 2-pass encoding is always going to gobble up more computing time than a single pass. But as I mentioned, that by itself only accounts for a 35% hit in computing time. (2) Pound for pound, the VP9 algorithm is mathematically more complex than the H.264 algorithm. (3) On the Raspberry, the VP9 encoder does not support any CPU optimizations (such as the NEON optimization that the x264 encoder is specifically designed to take advantage of). (4) On the Raspberry, the VP9 encoder does not support any parallel processing and therefore it only uses a single core (the x264 encoder is able to use all 4 cores). Leaving the other 3 cores idle automatically makes the VP9 encoder 300% slower than it could otherwise be. All of these factors are due to the mathematics and source code of VP9 itself, and are therefore unrelated to my build.
EXAMPLE 8: Create an MP3 audio file with the highly-regarded LAME encoder:
ffmpeg -i input.WAV -c:a libmp3lame -q:a 5 output.MP3
NOTE: In this example, we're converting a .wav audio file to a .mp3 audio file (the input file can be almost any audio format of your choosing). The "-q:a 5" part is the encoding quality. The LAME encoder supports a variety of settings, but my example features a quality-centric setting rather than one that attempts to achieve an EXACT – but entirely arbitrary – bit rate. This approach is known as variable bit-rate encoding (VBR). In the case of stereo sound, "-q:a 5" will yield an overall bit rate that's ABOUT (but not exactly) 128 Kbps. This is the most commonly used bit rate, and it roughly approximates "CD-quality" sound. The highest-quality setting, "-q:a 0", will produce an overall bit rate of ABOUT 256 Kbps. Finally, the lowest-quality setting, "-q:a 9", yields an overall bit rate of about 64 to 80 Kbps. For all of these quality settings, the actual bit rate will depend on the overall complexity of the sounds in the input file. Also, if it's a mono recording instead of stereo, the bit rates will be cut roughly in half. Sample rate – such as 22.05 KHz instead of the more common 44.1 KHz – will also lower the overall bit rate. Don't necessarily be dissuaded by the "lowest quality" setting. For a non-musical voice recording, such as an interview, this setting is still quite excellent and produces a file that's roughly 3 to 4 times smaller than the highest-quality setting. If you want to take a "deep dive" on how the "-q:a" setting affects perceived quality, take a sample audio file and encode it 3 separate times – with a "-q:a" of 0, 5, and 9. In many cases, unless you're an expert audiophile with a golden ear, you may not even notice a difference! Finally, be aware there are reports that some MP3 players from the 1990s and early 2000s may not be able to play files that use VBR encoding. I have not personally encountered that issue and won't bother addressing it here – just be aware that LAME also supports constant bit-rate encoding (CBR) in case you experience that issue with an antiquated player.
LEARN MORE ABOUT FFMPEG:
The 8 examples I just explained are only a small sample of the astonishing capabilities of FFmpeg. For more information, visit FFmpeg's official website
APPENDIX 6: IF FOR SOME REASON YOU WISH TO COMPLETELY UNINSTALL ALL 8 PROGRAMS YOU BUILT AND INSTALLED IN THIS TUTORIAL, SIMPLY RUN THE FOLLOWING COMMAND LINE IN TERMINAL. IF YOU ONLY BUILT AND INSTALLED MPV, FFMPEG AND LIBASS, YOU WOULD OBVIOUSLY SHORTEN THE FOLLOWING COMMAND LINE TO INCLUDE ONLY THOSE 3 PROGRAMS:
sudo dpkg -r mpv ffmpeg libass lame opus libvpx fdk-aac x264-snapshot-20180125-2245
THEN, DELETE THE "preferences" FILE YOU USED TO "PIN" THE PROGRAMS (IF YOU HAVE MANUALLY PINNED OTHER PROGRAMS UNRELATED TO THIS TUTORIAL, YOU WOULD OBVIOUSLY WANT TO EDIT THIS FILE, NOT DELETE IT):
sudo rm /etc/apt/preferences
APPENDIX 7: IF FOR SOME REASON YOU NEED TO RE-INSTALL ALL THE PROGRAMS IN THIS TUTORIAL ON YOUR *EXISTING* SYSTEM, YOU CAN DO IT IN LESS THAN ONE MINUTE! BY "EXISTING" SYSTEM, I MEAN THE SAME RASPBERRY WITH THE SAME OPERATING SYSTEM THAT YOU WERE USING WHEN YOU DID MY TUTORIAL. BY "EXISTING" SYSTEM, I ALSO MEAN THAT YOUR CORE SYSTEM AND "FIRMWARE" FILES HAVE NOT BEEN ALTERED. IF YOU HAVE SINCE RE-INSTALLED THE OPERATING SYSTEM OR IT'S A NEW SYSTEM – OR IT JUST ISN'T YOUR "EXISTING" SYSTEM FOR WHATEVER REASON – YOU NEED TO USE APPENDIX 8 INSTEAD. BUT IF IT TRULY IS YOUR EXISTING SYSTEM, SIMPLY RIGHT-CLICK WHATEVER FOLDER CONTAINS ALL THE ".DEB" FILES, SELECT "Open in Terminal", AND RUN THE FOLLOWING COMMAND (SEE STEP 13 OF MY TUTORIAL FOR MORE INFORMATION ON THE DEBIAN PACKAGE FILES). IF YOU BUILT ALL THE PROGRAMS IN MY TUTORIAL, THERE SHOULD BE EXACTLY 8 .DEB FILES IN THE FOLDER. IF YOU ONLY BUILT FFMPEG, MPV, and LIBASS, THERE SHOULD OBVIOUSLY BE ONLY 3 .DEB FILES IN THE FOLDER:
sudo dpkg -i *.deb
APPENDIX 8: IF YOU WISH TO INSTALL ALL THE PROGRAMS IN THIS TUTORIAL ON ANOTHER RASPBERRY PI 3 – OR ON THE SAME RASPBERRY PI 3 AFTER A FRESH INSTALL OF THE OPERATING SYSTEM – IT ONLY TAKES A FEW MINUTES! JUST FOLLOW THESE 9 SIMPLE STEPS:
Make sure the other Raspberry has a completely normal, standard copy of the Raspbian Stretch operating system. Please see my tutorial to find out exactly what I mean by "normal" – both the requirements section and Step 2 have critical information on this topic. If you're certain that everything is perfectly "normal" with the other Raspberry, simply open Terminal and do a standard update to make sure everything is current:
sudo apt-get update
sudo apt-get dist-upgrade
Set your GPU memory allocation to 128 MB (mpv requires 128 MB to work). Proceed as follows:
Click the Raspberry Menu | Preferences | Raspberry Pi Configuration | Performance Tab
Change "GPU Memory" to 128
Click OK | Click YES to reboot!
CRITICAL NOTE: If the GPU memory is already at 128 MB, reboot anyway – to make sure the system upgrade in Step 1 has fully kicked in!
Install the dependencies required by the pre-compiled Debian packages that you created with my tutorial. Because the ".deb" files have already been compiled, most of the dependencies have already been "baked in" during the compiling process – which explains why there are only 3 dependencies in this step (instead of the 19 dependencies that appear in Step 3 of my tutorial):
sudo apt-get install libsdl2-2.0-0 libva-wayland1 libluajit-5.1-2
Install the OpenGL ES (GLES) and EGL files from the official Raspberry GitHub site. These GPU-related files are essential for mpv to function. Since we're installing pre-compiled ".deb" files in this procedure, the compiling has already "baked in" 2 of the 4 GPU-related files – which explains why we only need to install 2 files in this step:
sudo wget -P /opt/vc/lib https://github.com/raspberrypi/firmware/raw/master/hardfp/opt/vc/lib/libEGL.so
sudo wget -P /opt/vc/lib https://github.com/raspberrypi/firmware/raw/master/hardfp/opt/vc/lib/libGLESv2.so
Install all the programs that you built with my tutorial: Locate the folder that contains all the Debian package files – these ".deb" files might be on a separate thumb drive, or wherever you put them for safe keeping (see Step 13 of my tutorial for more on this topic). Then, right-click that folder, select "Open in Terminal", and run the following command. If you built all the programs, there should be exactly 8 ".deb" files in the folder. If you only built FFmpeg, mpv, and libass, there should obviously be only 3 ".deb" files in the folder:
sudo dpkg -i *.deb
Run this command in Terminal to make sure all the “shared libraries” are properly recognized by FFmpeg and mpv. This step is critical, so don't overlook it:
Create mpv's configuration file (mpv.conf):
sudo mkdir -p /home/pi/.config/mpv
sudo nano /home/pi/.config/mpv/mpv.conf
WHEN THE NANO EDITOR APPEARS INSIDE TERMINAL, COPY AND PASTE THE FOLLOWING 2 LINES INTO THE EMPTY FILE:
SAVE THE FILE: PRESS "CTRL + X" TO EXIT OUT OF NANO – THEN TAP "Y" FOR YES – THEN TAP THE ENTER KEY TO ACCEPT THE CHANGE.
NOW RUN THIS COMMAND TO CHANGE THE OWNERSHIP OF THE mpv.conf PARENT FOLDER AND FILE FROM ROOT TO PI:
sudo chown -R pi:pi /home/pi/.config/mpv
Create a proper "Open With" behavior so that you can quickly open any video or audio file by simply double-clicking it within File Manager:
Right-click any media file whose file type you wish to associate with mpv – such as a video ending in ".mp4"
Click “Open With...”
Click the “Custom Command Line” tab
In the “Command line to execute" box, type “mpv %f” (all lower-case, no quotes)
Check “Execute in terminal emulator”
Check “Keep terminal window open after command execution”
In the “Application name” box, type “MPV” (no quotes)
Check “Set selected application as default action for this file type”
Click the OK button (and then tap the "q" key to quit when the media file starts playing)
Repeat this process for any other file type you wish to associate with mpv – such as .webm, .mov, .mkv, .avi, .wmv, .mpg, .mpeg, .3gp, .ts, .wav, .mp3, .m4a, .opus, etc.
Pin the advanced versions of the programs you just installed so that your system does not inappropriately "upgrade" them with older generic versions when you run "sudo apt-get upgrade" or "sudo apt-get dist-upgrade". Hat tip to "rpdom" for his pinning suggestion!
sudo nano /etc/apt/preferences
WHEN THE NANO EDITOR APPEARS INSIDE TERMINAL, COPY AND PASTE THE FOLLOWING 8 STANZAS INTO THE FILE (OR JUST THE FIRST 3 STANZAS IF YOU DIDN'T BUILD THE 5 ADVANCED ENCODERS):
Pin: version 3.4.1-1
Pin: version 0.27.0-1
Pin: version 0.13.7-1
Pin: version 20180125-1
Pin: version 0.1.5-1
Pin: version 1.6.1-1
Pin: version 1.2.1-1
Pin: version 3.100-1
SAVE THE FILE: PRESS "CTRL + X" TO EXIT OUT OF NANO – THEN TAP "Y" FOR YES – THEN TAP THE ENTER KEY TO ACCEPT THE CHANGE.
REBOOT – Just to make sure your system is fully "fresh" and responsive!
APPENDIX 9: TROUBLESHOOTING:
If you encounter any issues in the future, a good thing to try is to simply re-install all the ".deb" packages you backed up in Step 13. The entire process takes less than one minute! See Appendix 7 for details.
If mpv generates any "port" or "MMAL" errors, make sure your GPU memory allocation is 128 MB (as indicated in my mpv instructions). If mpv generates a "failed to add service" error, make sure you're not using the experimental desktop GL drivers known as Full KMS and Fake KMS (as indicated in my requirements section). And if you get a "[ytdl_hook] youtube-dl failed" message, it means you probably didn't install youtube-dl (see Appendix 2 for instructions).
Finally, as mentioned previously, be sure that all Terminal windows are closed before you use mpv (in order to maintain keyboard control).
APPENDIX 10: TECHNICAL NOTES AND OBSERVATIONS:
There are only 19 "explicitly" required dependencies in Step 3 of my tutorial. In other words, only 19 software packages are explicitly listed BY NAME in the "sudo apt-get install" stanza. However, some of the 19 dependencies have dependencies of their own that will automatically "come along for the ride". Some of these other dependencies are necessary for my tutorial to compile and build, and some of them are not. Either way, those other dependencies are determined by the maintainers of the official Raspbian repository – not me. Through careful testing, I have identified the other dependencies whose installation is automatically "triggered" by the 19 explicit dependencies. As just one example, I observed that the explicit installation of "automake" automatically triggers the installation of "autoconf". Autoconf is a critical dependency for my tutorial to work, yet I have deliberately NOT included it due to the fact that its installation is automatically triggered by the installation of automake! Two other essential dependencies that I have NOT explicitly listed are libxcb1-dev and libxcb-xfixes0-dev – both of which are automatically installed as a result of installing libsdl2-dev (one of the 19 explicit dependencies). Theoretically, there is some risk in not explicitly requesting more dependencies – because at some point in the future, the repository behavior could change – resulting in critical dependencies not being installed. Nonetheless, my minimalist philosophy considers it "bad form" to explicitly list more dependencies than necessary. The stanza I created, therefore, has been carefully optimized and verified to provide everything the tutorial needs – no more, no less. Of course, since I obviously don't have a crystal ball, it should go without saying that I can only certify the truth of my statements "at the time of their writing"!
THIS PAGE ONLY CONTAINS THE APPENDICES – PLEASE VISIT MY MAIN TUTORIAL PAGE:
TUTORIAL: Play or Encode High-Quality Video and Audio – with FFmpeg and mpv