<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Bernd Verst</title>
    <description>The latest articles on DEV Community by Bernd Verst (@berndverst).</description>
    <link>https://dev.to/berndverst</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F14713%2Fadbdec92-90ec-4552-b239-34e04d3b2e23.png</url>
      <title>DEV Community: Bernd Verst</title>
      <link>https://dev.to/berndverst</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/berndverst"/>
    <language>en</language>
    <item>
      <title>From Cloud Security Alert to Open Source Bugfix</title>
      <dc:creator>Bernd Verst</dc:creator>
      <pubDate>Wed, 08 Apr 2020 17:06:00 +0000</pubDate>
      <link>https://dev.to/azure/from-cloud-security-alert-to-open-source-bugfix-3cfi</link>
      <guid>https://dev.to/azure/from-cloud-security-alert-to-open-source-bugfix-3cfi</guid>
      <description>&lt;p&gt;Perhaps you've seen vulnerability reports in your CI/CD pipeline or tools like NPM. Cloud infrastructure has these too and I was surprised to get an alert recently. Naturally, I had to investigate to see where I went wrong... (and of course mitigate the problem in the process). Little did I know about the journey I was embarking on...&lt;/p&gt;

&lt;h2&gt;
  
  
  The security alert
&lt;/h2&gt;

&lt;p&gt;It all started a few weeks ago when I received an email from a colleague with the following content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Secure transfer to storage accounts should be enabled

Subscription ID: devrel-berndverst-demo-test  
Resource: /subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXXX/
    resourcegroups/kubeflowrelease/providers/
    microsoft.storage/storageaccounts/ &amp;gt; fairingXXXXXXXXXXXXXXXXX  
[1-Click mitigation link]

***Note: several similar results have been omitted*
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This was my gut reaction:  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;😱 This cannot be. What did I do wrong? Did I mess something up? 😰&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;My colleague had used &lt;a href="https://docs.microsoft.com/azure/security-center/security-center-intro?WT.mc_id=cloudsecurity-devto-beverst" rel="noopener noreferrer"&gt;Azure Security Center&lt;/a&gt; to generate a report of security issues. Since I had never received such a message before (note I could have set up &lt;a href="https://docs.microsoft.com/azure/security-center/security-center-provide-security-contact-details?WT.mc_id=cloudsecurity-devto-beverst" rel="noopener noreferrer"&gt;email alerts&lt;/a&gt; in Azure Security Center myself) I was a bit skeptical and first verified the authenticity of the email: Email domain, Sender Police Framework (SPF) check, Domain Keys Identified Mail (DKIM) all indicated the email was legitimate.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;1-Click mitigation&lt;/strong&gt; link (which I verified went to the Azure web portal domain) took me directly to the &lt;strong&gt;recommendations&lt;/strong&gt; section in the Azure Security Center for my Azure account and jumped to the relevant entries. The &lt;a href="https://docs.microsoft.com/azure/security-center/recommendations-reference?WT.mc_id=cloudsecurity-devto-beverst" rel="noopener noreferrer"&gt;Security Center recommendations&lt;/a&gt; documentation also had more information on the alert I had received.&lt;/p&gt;
&lt;h2&gt;
  
  
  What I did wrong (supposedly)
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Azure Blob Storage accounts should be configured to only serve traffic over https.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The 1-step mitigation in Azure Security Center resolved the issue, but I could also have followed &lt;a href="https://docs.microsoft.com/azure/storage/common/storage-require-secure-transfer?WT.mc_id=cloudsecurity-devto-beverst" rel="noopener noreferrer"&gt;these instructions&lt;/a&gt; in the docs.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;🤔 Why would I ever not want secure blob transfers? This does not sound like me.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Taking a closer look
&lt;/h2&gt;

&lt;p&gt;I noticed that all affected blob storage accounts had &lt;strong&gt;programmatically generated names&lt;/strong&gt;. Furthermore they all resided in my Azure resource group &lt;code&gt;kubeflowrelease&lt;/code&gt; and contained the string &lt;code&gt;fairing&lt;/code&gt; in the account names.&lt;/p&gt;

&lt;p&gt;Days earlier I had ported an &lt;a href="https://github.com/kubeflow/examples/tree/master/mnist#azure" rel="noopener noreferrer"&gt;end to end tutorial for Kubeflow&lt;/a&gt; using the MNIST training set to Azure. Of course in the process I deployed &lt;a href="https://www.kubeflow.org" rel="noopener noreferrer"&gt;Kubeflow&lt;/a&gt; to my Kubernetes cluster and went through the tutorial I wrote.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Kubeflow project is dedicated to making deployments of machine learning (ML) workflows on Kubernetes simple, portable and scalable.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The culprit: Kubeflow
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;💡Kubeflow somehow created the storage accounts in question&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Kubeflow Fairing helper library &lt;a href="https://github.com/kubeflow/fairing/blob/c7faf298221d8f28ae2e4794e85ac3d967c6d1e8/fairing/cloud/azure.py#L74" rel="noopener noreferrer"&gt;created the storage account without forcing secure transport&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;
  
  
  How to correctly create secure storage accounts
&lt;/h4&gt;

&lt;p&gt;Looking at the &lt;a href="https://docs.microsoft.com/azure/storage/common/storage-require-secure-transfer?WT.mc_id=cloudsecurity-devto-beverst" rel="noopener noreferrer"&gt;relevant documentation&lt;/a&gt; I discovered something very interesting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;By default, the Secure transfer required property is enabled when you create a storage account in Azure portal. However, it is disabled when you create a storage account with SDK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;In other words, the SDKs default to doing that for which the Azure Security Center alerted me, creating insecure storage accounts.&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;❓Kubeflow Fairing is written in Python. I wonder how to create secure storage accounts with the Azure Python SDK.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The Python SDK sample code at &lt;a href="https://github.com/Azure-Samples/storage-python-manage/blob/31c5e908cb5f5dc0393523e83eea3ab2f422d332/README.md" rel="noopener noreferrer"&gt;github.com/Azure-Samples/storage-python-manage&lt;/a&gt; does not explicitly set the secure option. &lt;strong&gt;The sample code uses the insecure default&lt;/strong&gt; [Edit: &lt;em&gt;it turns out that this depends on the SDK version used&lt;/em&gt;]. I made &lt;a href="https://github.com/Azure-Samples/storage-python-manage/pull/11" rel="noopener noreferrer"&gt;this pull request&lt;/a&gt; to fix this.&lt;/p&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/Azure-Samples/storage-python-manage/pull/11" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Use secure https-only access for newly created storage accounts.
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#11&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/berndverst" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars0.githubusercontent.com%2Fu%2F4535280%3Fv%3D4" alt="berndverst avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/berndverst" rel="noopener noreferrer"&gt;berndverst&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/Azure-Samples/storage-python-manage/pull/11" rel="noopener noreferrer"&gt;&lt;time&gt;Mar 11, 2020&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;Addresses #10&lt;/p&gt;

    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Azure-Samples/storage-python-manage/pull/11" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;




&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Fixing the sample code &lt;strong&gt;led to several unrelated issues with the tests&lt;/strong&gt;, all of which I fixed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Azure Python SDK version was not locked and the API output had changed, no longer matching the mocked responses&lt;/li&gt;
&lt;li&gt;Travis was running tests for a version of Python that was no longer supported&lt;/li&gt;
&lt;li&gt;Travis was not running tests for current versions of Python 3.7 and 3.8.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It took me hours, but the above pull request fixed it all.&lt;/p&gt;

&lt;h4&gt;
  
  
  What did Kubeflow Fairing do?
&lt;/h4&gt;

&lt;p&gt;Taking a close look we can see that Kubeflow Fairing basically &lt;a href="https://github.com/kubeflow/fairing/blob/c7faf298221d8f28ae2e4794e85ac3d967c6d1e8/fairing/cloud/azure.py#L74" rel="noopener noreferrer"&gt;copied from the Azure Python sample code&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I would have done the same.&lt;/em&gt; Good thing that is fixed now!&lt;/p&gt;
&lt;/blockquote&gt;


&lt;div class="ltag_github-liquid-tag"&gt;
  &lt;h1&gt;
    &lt;a href="https://github.com/kubeflow/fairing/pull/477" rel="noopener noreferrer"&gt;
      &lt;img class="github-logo" alt="GitHub logo" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg"&gt;
      &lt;span class="issue-title"&gt;
        Only use secure transport mode for new Azure Storage Accounts
      &lt;/span&gt;
      &lt;span class="issue-number"&gt;#477&lt;/span&gt;
    &lt;/a&gt;
  &lt;/h1&gt;
  &lt;div class="github-thread"&gt;
    &lt;div class="timeline-comment-header"&gt;
      &lt;a href="https://github.com/berndverst" rel="noopener noreferrer"&gt;
        &lt;img class="github-liquid-tag-img" src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Favatars0.githubusercontent.com%2Fu%2F4535280%3Fv%3D4" alt="berndverst avatar"&gt;
      &lt;/a&gt;
      &lt;div class="timeline-comment-header-text"&gt;
        &lt;strong&gt;
          &lt;a href="https://github.com/berndverst" rel="noopener noreferrer"&gt;berndverst&lt;/a&gt;
        &lt;/strong&gt; posted on &lt;a href="https://github.com/kubeflow/fairing/pull/477" rel="noopener noreferrer"&gt;&lt;time&gt;Mar 11, 2020&lt;/time&gt;&lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag-github-body"&gt;
      &lt;p&gt;&lt;strong&gt;What this PR does / why we need it&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;Currently Fairing creates new Storage Accounts on Azure (if necessary) that do not use best practices of enabling strict transport security. Azure Security Center will flag these storage accounts.&lt;/p&gt;
&lt;p&gt;This PR uses the recommended default (which unfortunately isn't the default in the Python SDK).&lt;/p&gt;
&lt;p&gt;References:
&lt;a href="https://github.com/Azure-Samples/storage-python-manage#create-account" rel="noopener noreferrer"&gt;https://github.com/Azure-Samples/storage-python-manage#create-account&lt;/a&gt;
&lt;a href="https://docs.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer" rel="nofollow noopener noreferrer"&gt;https://docs.microsoft.com/en-us/azure/storage/common/storage-require-secure-transfer&lt;/a&gt;
&lt;a href="https://docs.microsoft.com/en-us/python/api/azure-mgmt-storage/azure.mgmt.storage.v2018_07_01.models.storageaccountcreateparameters?view=azure-python" rel="nofollow noopener noreferrer"&gt;https://docs.microsoft.com/en-us/python/api/azure-mgmt-storage/azure.mgmt.storage.v2018_07_01.models.storageaccountcreateparameters?view=azure-python&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Release note&lt;/strong&gt;:
--&amp;gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;NONE
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This change is &lt;a href="https://reviewable.io/reviews/kubeflow/fairing/477" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/0210135a140627a19496177795afadacb8502c1f/68747470733a2f2f72657669657761626c652e696f2f7265766965775f627574746f6e2e737667" height="34" alt="Reviewable"&gt;&lt;/a&gt;&lt;/p&gt;


    &lt;/div&gt;
    &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/kubeflow/fairing/pull/477" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h2&gt;
  
  
  Success?
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- ✅ Kubeflow Fairing now creates secure storage accounts.
- ✅ Anyone finding the Azure Python SDK samples
  for storage account creation will create secure accounts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  What about the API / server-side default?
&lt;/h2&gt;

&lt;p&gt;Since &lt;a href="https://azuresdkdocs.blob.core.windows.net/$web/python/azure-mgmt-storage/8.0.0/azure.mgmt.storage.v2019_04_01.models.html#azure.mgmt.storage.v2019_04_01.models.StorageAccountCreateParameters" rel="noopener noreferrer"&gt;API version 2019-04-01&lt;/a&gt; the secure mode is the default. All current SDKs will be using this API version or a newer one which defaults to the secure setting.&lt;/p&gt;
&lt;h3&gt;
  
  
  So why the Kubeflow Fairing issue afterall?
&lt;/h3&gt;

&lt;p&gt;Kubeflow Fairing was using the deprecated &lt;code&gt;azure&lt;/code&gt; library. Instead &lt;code&gt;azure-mgmt-storage&lt;/code&gt;. As such it was consuming an outdated version of the API with the insecure default setting. &lt;strong&gt;API and SDK versioning is hard!&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;The edits to the Azure Python sample documentation weren't strictly necessary.&lt;/strong&gt; But at least I fixed the tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbernd.dev%2Fimg%2Fsecurityalerts%2Fgodeeper.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fbernd.dev%2Fimg%2Fsecurityalerts%2Fgodeeper.jpg" alt="We must go deeper"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>security</category>
      <category>opensource</category>
      <category>azure</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Trim Videos Instantly</title>
      <dc:creator>Bernd Verst</dc:creator>
      <pubDate>Fri, 03 Apr 2020 22:04:08 +0000</pubDate>
      <link>https://dev.to/berndverst/trim-videos-instantly-adg</link>
      <guid>https://dev.to/berndverst/trim-videos-instantly-adg</guid>
      <description>&lt;p&gt;Is your video too long for upload to Twitter or Instagram? Or do you want to export just a specific clip? Using video editors to trim videos requires reencoding the entire video which takes a long time. Instead I will show you how to &lt;strong&gt;instantly&lt;/strong&gt; trim your videos and even maintain embedded subtitle tracks.&lt;/p&gt;

&lt;h3&gt;
  
  
  Background
&lt;/h3&gt;

&lt;p&gt;A few days ago I created a post on easily &lt;a href="https://bernd.dev/2020/04/adding-subtitles/"&gt;adding subtitles to your videos&lt;/a&gt;. Today I wanted to verify that Twitter correctly shows these subtitles, but I discovered that my video was too long. Having played with &lt;strong&gt;FFmpeg&lt;/strong&gt; I suspected that there may be a more efficient way for trimming videos than using a video editor. Be prepared to have your mind blown! 🤯&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  FFmpeg
&lt;/h3&gt;

&lt;p&gt;You will need the open-source &lt;a href="https://www.ffmpeg.org/"&gt;FFmpeg&lt;/a&gt; tool.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please follow the &lt;a href="http://ffmpeg.org/download.html"&gt;installation instructions here&lt;/a&gt;.&lt;br&gt;
On Mac, simply use &lt;em&gt;Homebrew&lt;/em&gt; with &lt;code&gt;brew install ffmpeg&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Instantly trim videos
&lt;/h2&gt;

&lt;p&gt;The following command reads the source video and copies all streams contained within (video, audio, subtitles) to the output. The various time parameters ensure only a specific part of the original video is written to the output. &lt;strong&gt;The video and audio streams are not reencoded.&lt;/strong&gt; The time required for reencoding would directly depend on the duration of the video, however we are simply copying parts of the video.  For this reason &lt;strong&gt;the following operation is near instant&lt;/strong&gt;. A huge time saving over workflows involving video editors.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


</description>
      <category>todayilearned</category>
      <category>productivity</category>
      <category>bash</category>
      <category>watercooler</category>
    </item>
    <item>
      <title>Adding subtitles to your videos the easy way</title>
      <dc:creator>Bernd Verst</dc:creator>
      <pubDate>Wed, 01 Apr 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/azure/adding-subtitles-to-your-videos-the-easy-way-11m2</link>
      <guid>https://dev.to/azure/adding-subtitles-to-your-videos-the-easy-way-11m2</guid>
      <description>&lt;p&gt;For accessibility reasons all video content you create should be captioned but adding subtitles can be a daunting task. In this article we cover how to quickly and easily add subtitles to your existing videos without any video editing software.&lt;/p&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Inputs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Video Format:&lt;/strong&gt; This approach will only work for &lt;strong&gt;MP4 videos&lt;/strong&gt;. Both &lt;strong&gt;H.264&lt;/strong&gt; and &lt;strong&gt;H.265&lt;/strong&gt;/&lt;strong&gt;HEVC&lt;/strong&gt; are supported.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Caption / Subtitle file:&lt;/strong&gt; Either SRT or WebVTT format are supported. &lt;em&gt;Don't have a caption file? See instructions below&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  FFmpeg
&lt;/h3&gt;

&lt;p&gt;The instructions rely on the open-source &lt;a href="https://www.ffmpeg.org/"&gt;FFmpeg&lt;/a&gt; tool.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;FFmpeg is the leading multimedia framework, able to decode, encode, transcode, mux, demux, stream, filter and play pretty much anything that humans and machines have created.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Please follow the &lt;a href="http://ffmpeg.org/download.html"&gt;installation instructions here&lt;/a&gt;.&lt;br&gt;
On Mac, simply use &lt;em&gt;Homebrew&lt;/em&gt; with &lt;code&gt;brew install ffmpeg&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating a caption file automatically (optional)
&lt;/h2&gt;

&lt;p&gt;If you do not have a captions file with subtitles for your video you can easily &lt;strong&gt;auto-caption&lt;/strong&gt; your video with one of two methods.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Upload your video to YouTube. YouTube can &lt;a href="https://support.google.com/youtube/answer/6373554"&gt;automatically caption&lt;/a&gt; your video. Captions can be downloaded in SRT file format.&lt;/li&gt;
&lt;li&gt;If your company has &lt;a href="https://docs.microsoft.com/stream/overview?WT.mc_id=captions-devto-beverst"&gt;Microsoft Stream&lt;/a&gt;, upload your video to enjoy auto-captioning. Once the captions have been generated you can easily make edits through the web interface before &lt;a href="https://docs.microsoft.com/stream/portal-add-subtitles-captions#download-subtitles-or-captions?WT.mc_id=captions-devto-beverst"&gt;downloading your captions&lt;/a&gt; in WebVTT format.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  Making subtitles selectable
&lt;/h2&gt;

&lt;p&gt;These subtitles can be toggled on or off in any video player that supports subtitles.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8D9NKS5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bernd.dev/img/captions/selectable-subtitles.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8D9NKS5B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bernd.dev/img/captions/selectable-subtitles.jpg" alt="selectable"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; copy &lt;span class="nt"&gt;-c&lt;/span&gt;:s mov_text &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-metadata&lt;/span&gt;:s:s:0 &lt;span class="nv"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;eng outfile_selectable.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Multiple languages
&lt;/h2&gt;

&lt;p&gt;You can even have multiple subtitles in different languages all within the same video.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--LnAHWx0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bernd.dev/img/captions/multi-lingual-subtitles.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--LnAHWx0w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bernd.dev/img/captions/multi-lingual-subtitles.jpg" alt="selectmulti"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle files&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLESENG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;english.vtt
&lt;span class="nv"&gt;SUBTITLEGER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;german.vtt
&lt;span class="nv"&gt;SUBTITLESSPA&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;spanish.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLESENG&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLESGER&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLESSPA&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-map&lt;/span&gt; 0 &lt;span class="nt"&gt;-map&lt;/span&gt; 1:s &lt;span class="nt"&gt;-map&lt;/span&gt; 2:s &lt;span class="nt"&gt;-map&lt;/span&gt; 3:s &lt;span class="nt"&gt;-c&lt;/span&gt; copy &lt;span class="nt"&gt;-c&lt;/span&gt;:s mov_text &lt;span class="nt"&gt;-c&lt;/span&gt;:s mov_text c:s mov_text &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-metadata&lt;/span&gt;:s:s:0 &lt;span class="nv"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;eng &lt;span class="nt"&gt;-metadata&lt;/span&gt;:s:s:1 &lt;span class="nv"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ger &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-metadata&lt;/span&gt;:s:s:2 &lt;span class="nv"&gt;language&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;spa outfile_selectable_multi.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Burned in subtitles
&lt;/h2&gt;

&lt;p&gt;These subtitles are part of the video itself and cannot be toggled off.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yn7xil49--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bernd.dev/img/captions/burnedin-subtitles.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yn7xil49--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://bernd.dev/img/captions/burnedin-subtitles.jpg" alt="burnedin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will need to render the video again with the subtitles permanently added into the video stream. Note that this will take some time depending on the video duration, quality and the quality of your CPU and GPU.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoff:&lt;/strong&gt; While hardware accelerated encoding using GPUs is generally significantly faster, software encoding (CPU only) produces smaller files and better quality.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tradeoff:&lt;/strong&gt; H.264 has the most compatibility. You likely have hardware support for encoding and decoding. H.265/HEVC files are 25-50% more efficient but decoding is much more compute intensive. Only recent GPUs have hardware support for encoding in this format. &lt;strong&gt;Nevertheless, H.265/HEVC is the format of the future.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For output in H.264 with hardware encoding on MacOS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; temp.ass &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;BITRATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ffprobe &lt;span class="nt"&gt;-v&lt;/span&gt; error &lt;span class="nt"&gt;-select_streams&lt;/span&gt; v:0 &lt;span class="nt"&gt;-show_entries&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bit_rate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-of&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;noprint_wrappers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1:nokey&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;$INFILE&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="nv"&gt;ass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;temp.ass &lt;span class="nt"&gt;-vcodec&lt;/span&gt; h264_videotoolbox &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt;:v &lt;span class="nv"&gt;$BITRATE&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy output_burnedin.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For H.264 with hardware encoding on Windows/Linux with NVIDIA GPU&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; temp.ass &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;BITRATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ffprobe &lt;span class="nt"&gt;-v&lt;/span&gt; error &lt;span class="nt"&gt;-select_streams&lt;/span&gt; v:0 &lt;span class="nt"&gt;-show_entries&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bit_rate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-of&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;noprint_wrappers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1:nokey&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;$INFILE&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="nv"&gt;ass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;temp.ass &lt;span class="nt"&gt;-vcodec&lt;/span&gt; h264_nvenc &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt;:v &lt;span class="nv"&gt;$BITRATE&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy output_burnedin.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For H.264 with software encoding on any operating system&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; temp.ass &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;BITRATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ffprobe &lt;span class="nt"&gt;-v&lt;/span&gt; error &lt;span class="nt"&gt;-select_streams&lt;/span&gt; v:0 &lt;span class="nt"&gt;-show_entries&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bit_rate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-of&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;noprint_wrappers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1:nokey&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;$INFILE&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="nv"&gt;ass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;temp.ass &lt;span class="nt"&gt;-vcodec&lt;/span&gt; libx264 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt;:v &lt;span class="nv"&gt;$BITRATE&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy output_burnedin.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For H.265/HEVC with hardware encoding on MacOS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; temp.ass &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;BITRATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ffprobe &lt;span class="nt"&gt;-v&lt;/span&gt; error &lt;span class="nt"&gt;-select_streams&lt;/span&gt; v:0 &lt;span class="nt"&gt;-show_entries&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bit_rate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-of&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;noprint_wrappers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1:nokey&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;$INFILE&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-vcodec&lt;/span&gt; hevc_videotoolbox &lt;span class="nt"&gt;-tag&lt;/span&gt;:v hvc1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt;:v &lt;span class="nv"&gt;$BITRATE&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy &lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="nv"&gt;ass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;temp.ass output_burnedin.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For H.265/HEVC with hardware encoding on Windows/Linux with NVIDIA GPU&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; temp.ass &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;BITRATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ffprobe &lt;span class="nt"&gt;-v&lt;/span&gt; error &lt;span class="nt"&gt;-select_streams&lt;/span&gt; v:0 &lt;span class="nt"&gt;-show_entries&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bit_rate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-of&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;noprint_wrappers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1:nokey&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;$INFILE&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-vcodec&lt;/span&gt; hevc_nvenc &lt;span class="nt"&gt;-tag&lt;/span&gt;:v hvc1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt;:v &lt;span class="nv"&gt;$BITRATE&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy &lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="nv"&gt;ass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;temp.ass output_burnedin.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;For H.265/HEVC software encoding on any operating system&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Replace with your input video and subtitle file&lt;/span&gt;
&lt;span class="nv"&gt;INFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;video.mp4
&lt;span class="nv"&gt;SUBTITLES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;subtitles.vtt

ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$SUBTITLES&lt;/span&gt; temp.ass &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nv"&gt;BITRATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;ffprobe &lt;span class="nt"&gt;-v&lt;/span&gt; error &lt;span class="nt"&gt;-select_streams&lt;/span&gt; v:0 &lt;span class="nt"&gt;-show_entries&lt;/span&gt; &lt;span class="nv"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bit_rate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-of&lt;/span&gt; &lt;span class="nv"&gt;default&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;noprint_wrappers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1:nokey&lt;span class="o"&gt;=&lt;/span&gt;1 &lt;span class="nv"&gt;$INFILE&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nv"&gt;$INFILE&lt;/span&gt; &lt;span class="nt"&gt;-vcodec&lt;/span&gt; libx265 &lt;span class="nt"&gt;-tag&lt;/span&gt;:v hvc1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-b&lt;/span&gt;:v &lt;span class="nv"&gt;$BITRATE&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy &lt;span class="nt"&gt;-vf&lt;/span&gt; &lt;span class="nv"&gt;ass&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;temp.ass output_burnedin.mp4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note&lt;/em&gt;: If the source video was in H.264 format you can also use the H.265 command to produce a final video in H.265/HEVC format. Since H.265 is 25-50% more efficient you should be able to reduce the Bitrate and still maintain the same video quality.&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>tutorial</category>
      <category>bash</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
