Answers.Body: <h1>Answer</h1>
  <p>Use two-pass Constant Quality mode:</p>
  <pre><code>ffmpeg  -i input.mp4  -b:v 0  -crf 30  -pass 1  -an -f webm -y /dev/null
  ffmpeg  -i input.mp4  -b:v 0  -crf 30  -pass 2  output.webm
  </code></pre>
  <h2>Notes</h2>
  <ol>
  <li><p>If you're using Microsoft Windows™ instead of UNIX, change <code>/dev/null</code> to <code>NUL</code>.</p>
  </li>
  <li><p>We discard the video using <code>/dev/null</code> because the first pass's only purpose is to generate a log file of statistics.</p>
  </li>
  </ol>
  <h2>mp42webm shell script</h2>
  <p>To save typing in the future, this can be put in a UNIX shell script:</p>
  <pre class="lang-sh prettyprint-override"><code>#!/bin/sh -xe
  ffmpeg -i &quot;$1&quot; -b:v 0 -crf 30 -pass 1 -an -f webm -y /dev/null
  ffmpeg -i &quot;$1&quot; -b:v 0 -crf 30 -pass 2 &quot;${1%.mp4}.webm&quot;
  </code></pre>
  <p>Usage: <strong>mp42webm</strong> <em>filename</em>.mp4. <br/>
  Creates <em>filename</em>.webm.</p>
  <h2>Explanation:</h2>
  <p>Setting the video bitrate to <em>zero</em> while also specifying the CRF (Constant Rate Factor) enables Constant Quality mode which targets a certain perceptual quality level. For VP9, the CRF can range from 0 (best quality) to 63 (smallest file size).</p>
  <p>It is important to set the video bitrate to zero. If you do not specify a video bitrate, it defaults to something low which gets you <em>Constrained</em> Quality mode, where each frame has a maximum bitrate. While that can be useful for streaming, it reduces quality significantly as frames with a lot of motion will not have the bandwidth needed to look good.</p>
  <p>Another part of the reason you’re losing quality is that <code>webm</code> (VP9) prefers to encode in two passes for best results. The first pass compiles statistics about the video which is then used in the second pass to make a smaller and higher quality video.</p>
  <p>Please see the <a href="https://trac.ffmpeg.org/wiki/Encode/VP9" rel="nofollow noreferrer">ffmpeg VP9 documentation</a> if you’d like to learn more.</p>
  <h2>A word about transcoding</h2>
  <p>By the way, in general, transcoding formats (taking a compressed video and recompressing it with a different codec) is a bad idea as you’ll not only add the normal errors from lossy video encoding, but you’ll waste bits in the new format trying to preserve the artifacts from the old.</p>
  <h2>If you mean “without quality loss” literally</h2>
  <p>The <code>-lossless 1</code> option of ffmpeg’s VP9 encoder enables lossless quality mode, but with a potentially enormous increase in filesize.</p>
  <p>All you need is this:</p>
  <pre><code>ffmpeg  -i input.mp4  -lossless 1  output.webm
  </code></pre>
  <p>When I tried <code>-lossless 1</code> on a low-quality <code>mp4</code>, the resulting <code>webm</code> was 100× larger, which was not accceptable to me. However, if your <code>mp4</code> files are already very high quality, I expect the size difference will not be so great.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-16T09:01:59.980Z
Answers.Text: `/dev/null`? What does this mean? What would the equivalent be for windows users? Are you overwriting `input.mp4` on the first pass? This answer needs more explanation on what exactly each component is doing. It doesn't offer intermediate users much explanation of how it works.
Answers.UserDisplayName: Hatefiend
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-02-20T04:09:43.083Z
Answers.Text: Hi Hatefriend: My answer already includes a long explanation section plus a link for more information, so I'd rather not make it longer. Did you see the footnote regarding Microsoft Windows which answers your specific question? Also, as mentioned above, the first pass compiles statistics about the input file. There is no need to fear that it might overwrite the input.
Answers.UserDisplayName: hackerb9
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-05-02T14:54:25.227Z
Answers.Text: I tried convert .MTS file to .webm usig these two commands (Ubuntu 20.10, ffmpeg version 4.2.2). But I have got errors: "Invalid channel layout 5.1(side) for specified mapping family -1.
  Error initializing output stream 0:1 -- Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height"
Answers.UserDisplayName: Andrew Krizhanovsky
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-01-09T09:43:28.930Z
Answers.Text: thanks for the answer. if transcoding is generally a bad idea, what do you recommend instead if you need to convert mp4 videos to webm and webm videos to mp4?
Answers.UserDisplayName: Crashalot
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-02-08T22:59:53.030Z
Answers.Text: Hmm. That didn't work. Second command failed: "Invalid channel layout 5.1(side) for specified mapping family -1.
  Error initializing output stream 0:1 -- Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height"
Answers.UserDisplayName: Ken Ingram
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-07-16T13:28:43.540Z
Answers.Text: `File '/dev/null' already exists. Overwrite ? [y/N]` so I will switch it to /tmp/deleteme.webm
Answers.UserDisplayName: reducing activity
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-08-02T00:51:33.637Z
Answers.Text: @reducingactivity Thanks for letting me know that ffmpeg changed the default behaviour. It is safe to answer 'y" when writing to /dev/null as it is a fake file that ignores anything written to it. I've updated my answer to include the `-y` flag so that people won't be asked "Overwrite?".
Answers.UserDisplayName: hackerb9
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2022-05-16T15:54:01.627Z
Answers.Text: I think it is silly that 2 passes cannot be accomplished with one command. When I see two separate commands like this it makes me worry that the 2nd command will not even take into consideration what is accomplished by the first command.
Answers.UserDisplayName: Lonnie Best
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-10T13:53:19.477Z
Answers.Text: Would this work going the other way? ```ffmpeg  -i input.webm  -lossless 1  output.mp4```
Answers.UserDisplayName: majorgear
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-08-10T20:49:05.290Z
Answers.Text: Good question. The answer is no, lossless mode is a feature of webm.
Answers.UserDisplayName: hackerb9
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-08-15T06:16:05.000Z
Answers.LastActivityDate: 2024-02-27T07:18:39.503Z
Answers.LastEditDate: 2024-02-27T07:18:39.503Z
Answers.UserDisplayName: hackerb9
Answers.Body: <p>On Linux I use <a href="https://gitlab.com/es20490446e/optimizeVideo" rel="nofollow noreferrer">optimizeVideo</a>, which is a wrapper around ffmpeg that automatically detects those settings according to <a href="https://developers.google.com/media/vp9/settings/vod/" rel="nofollow noreferrer">Google's recommendations</a>.</p>
  <p>The result is a video which quality difference you cannot tell, but usually orders of magnitude smaller.</p>
  <p><a href="https://i.sstatic.net/BQMCT.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/BQMCT.png" alt="Logo" /></a></p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2020-07-04T00:06:56.963Z
Answers.LastActivityDate: 2020-07-04T00:06:56.963Z
Answers.UserDisplayName: Alberto Salvia Novella
Answers.Body: <p>mp4 and webm are container formats. think of them as boxes that contain within them various video, audio, subtitle, chapter info, etc files.</p>
  <p>if all the streams within the source mp4 container file are compatible with webm container format then it can be losslessly converted to webm, this is called remuxing (aka stream copy). This process simply copies the individual streams from one container to another without changing them in any way.</p>
  <p>which is an extremely quick process and also lossless, has a trivial effect on file size (from mp4 to webm you save a bit of space). There is no generational quality loss due to not modifying the video and audio streams.</p>
  <p><a href="https://ffmpeg.org/ffmpeg.html#Stream-copy" rel="nofollow noreferrer">https://ffmpeg.org/ffmpeg.html#Stream-copy</a></p>
  <pre><code>ffmpeg -i input.mp4 -c copy output.webm
  </code></pre>
  <p>I have tested the above command myself and it works great. if the mp4 container is using streams that are NOT compatible with webm. (for example h264 video. or srt subtitles). Then you cannot remux / stream copy it.</p>
  <p>If one of the streams you are trying to pass to webm is unsupported it will instead error out and inform you that:</p>
  <blockquote>
  <p>Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.</p>
  </blockquote>
  <p>you would have to resort to re-encoding the unsupported stream. if you are re-encoding the video it is a lengthy process that will cause a variable hit to the image quality</p>
  <p>near negligible is possible with the right settings and quality input. although doing so might take a long time and a lot of space. depending on the exact details of input and output codec and configuration. furthermore each time you convert via re-encoding you suffer generational loss. so even negligible losses add up to serious losses if you do it over and over.</p>
  <p>technically, you can re-encode it into a lossless format or lossless setting. But doing so will result in obscenely large files. Making them impractical for many uses. realistically you won't be wanting to do that.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-09-13T11:17:25.720Z
Answers.Text: Your post doesn't seem to answer the question
Answers.UserDisplayName: Dr Mayhem
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-09-22T17:19:38.043Z
Answers.Text: @Dr Mayhem please reread. it clearly answers the question. He wanted to losslessly convert mp4 to webm using ffmpeg. I gave him the command to do so, being `ffmpeg -i input.mp4 -c copy output.webm` with the caveat that it can only be losslessly converted if the source mp4 file contains codecs which are compatible with webm. otherwise he would need to perform a lossy reencode to codecs which are compatible with webm
Answers.UserDisplayName: taltamir
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-09-12T00:28:58.560Z
Answers.LastActivityDate: 2024-09-22T17:23:02.363Z
Answers.LastEditDate: 2024-09-22T17:23:02.363Z
Answers.UserDisplayName: taltamir
Body: <p>What is the best way to convert a <code>mp4</code> file to <code>webm</code> without quality loss (using <code>vp8</code> or <code>vp9</code>) with ffmpeg?</p>
  
  <p>If I do <code>ffmpeg -i in.mp4 out.webm</code> the quality is very bad. I can specify a target bitrate via <code>-b:v</code> and constant quality mode via <code>crf</code>, i.e. </p>
  
  <p><code>ffmpeg -i in.mp4 -crf 10 -b:v 1M out.webm</code> </p>
  
  <p>This gives better quality. However for this I have to lookup the bitrate of the input video (here 1M). </p>
  
  <p>I also noticed that if you specify a much larger value for the target bitrate than the bitrate of the input (here for example <code>-b:v 100M</code>), ffmpeg just seems to use approximately the bitrate from the input video with vp9 or  slightly higher bitrate with vp8. However this solution doesn't seem to be the intended way to do this.</p>
  
  <p>How would you choose the crf value and why?</p>
  
  <p>Is there a parameter which automatically chooses the bitrate of the input file and a suitable crf value to get the same quality as the input file?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-15T18:22:04.973Z
Comments.Text: Set bitrate to 0. And experiment with crf. But your method of a high bitrate works too, since the value acts as a ceiling not a target
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-15T19:21:22.133Z
Comments.Text: @Mulvya: Does bitrate 0 mean that there is no limit? I didn't find this in the man page.
Comments.UserDisplayName: student
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T03:14:31.083Z
Comments.Text: With bitrate not set to zero, CRF is constrained by that value. With zero, it's not. It's a quirk of the VPn encoders.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T11:57:38.567Z
Comments.Text: Ok, but if I omit the bitrate parameter completely the quality gets very bad even thoug I didn't give an upper limit for the bitrate.
Comments.UserDisplayName: student
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T12:03:35.093Z
Comments.Text: If you omit it, it defaults to 200k.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T12:14:52.557Z
Comments.Text: @Mulvya. Thanks for the Info. I also cannot find this one in the man page. Is there any other reference manual for ffmpeg which covers this default value?
Comments.UserDisplayName: student
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2016-10-17T12:33:21.700Z
Comments.Text: [Link](https://www.ffmpeg.org/ffmpeg-codecs.html#Codec-Options) for 200k (see first option). For WebM b:v 0, see this [page](https://trac.ffmpeg.org/wiki/Encode/VP9).
Comments.UserDisplayName: Gyan
Tags: <ffmpeg><vp9><lossless>
Title: Convert mp4 to webm without quality loss with ffmpeg
UserDisplayName: student
ThreadText: # Convert mp4 to webm without quality loss with ffmpeg
  
  (Asked by: username_0 on 2016-10-15)
  
  What is the username_8 way to convert a `mp4` file to `webm` without quality loss (using `vp8` or `vp9`) with ffmpeg?
  
  If I do `ffmpeg -i in.mp4 out.webm` the quality is very bad. I can specify a target bitrate via `-b:v` and constant quality mode via `crf`, i.e.
  
  `ffmpeg -i in.mp4 -crf 10 -b:v 1M out.webm`
  
  This gives better quality. However for this I have to lookup the bitrate of the input video (here 1M).
  
  I also noticed that if you specify a much larger value for the target bitrate than the bitrate of the input (here for example `-b:v 100M`), ffmpeg just seems to use approximately the bitrate from the input video with vp9 or slightly higher bitrate with vp8. However this solution doesn't seem to be the intended way to do this.
  
  How would you choose the crf value and why?
  
  Is there a parameter which automatically chooses the bitrate of the input file and a suitable crf value to get the same quality as the input file?
  
  **Tags:** ffmpeg, vp9, lossless
  
  > **Comments:**
  > **username_1**: Set bitrate to 0. And experiment with crf. But your method of a high bitrate works too, since the value acts as a ceiling not a target  
  > **username_0**: @Mulvya: Does bitrate 0 mean that there is no limit? I didn't find this in the man page.  
  > **username_1**: With bitrate not set to zero, CRF is constrained by that value. With zero, it's not. It's a quirk of the VPn encoders.  
  > **username_0**: Ok, but if I omit the bitrate parameter completely the quality gets very bad even thoug I didn't give an upper limit for the bitrate.  
  > **username_1**: If you omit it, it defaults to 200k.  
  > **username_0**: @Mulvya. Thanks for the Info. I also cannot find this one in the man page. Is there any other reference manual for ffmpeg which covers this default value?  
  > **username_1**: [Link](https://www.ffmpeg.org/ffmpeg-codecs.html#Codec-Options) for 200k (see first option). For WebM b:v 0, see this [page](https://trac.ffmpeg.org/wiki/Encode/VP9).  
  
  ---
  
  ## 3 answers
  
  ### Answer by username_2 on 2019-08-15. Score: 40
  
  # Answer
  
  Use two-pass Constant Quality mode:
  
  ```
  ffmpeg  -i input.mp4  -b:v 0  -crf 30  -pass 1  -an -f webm -y /dev/null
  ffmpeg  -i input.mp4  -b:v 0  -crf 30  -pass 2  output.webm
  
  ```
  
  ## Notes
  
  1. If you're using Microsoft Windows™ instead of UNIX, change `/dev/null` to `NUL`.
  2. We discard the video using `/dev/null` because the first pass's only purpose is to generate a log file of statistics.
  
  ## mp42webm shell script
  
  To save typing in the future, this can be put in a UNIX shell script:
  
  ```sh
  #!/bin/sh -xe
  ffmpeg -i "$1" -b:v 0 -crf 30 -pass 1 -an -f webm -y /dev/null
  ffmpeg -i "$1" -b:v 0 -crf 30 -pass 2 "${1%.mp4}.webm"
  
  ```
  
  Usage: **mp42webm** *filename*.mp4.   
  Creates *filename*.webm.
  
  ## Explanation:
  
  Setting the video bitrate to *zero* while also specifying the CRF (Constant Rate Factor) enables Constant Quality mode which targets a certain perceptual quality level. For VP9, the CRF can range from 0 (username_8 quality) to 63 (smallest file size).
  
  It is important to set the video bitrate to zero. If you do not specify a video bitrate, it defaults to something low which gets you *Constrained* Quality mode, where each frame has a maximum bitrate. While that can be useful for streaming, it reduces quality significantly as frames with a lot of motion will not have the bandwidth needed to look good.
  
  Another part of the reason you’re losing quality is that `webm` (VP9) prefers to encode in two passes for username_8 results. The first pass compiles statistics about the video which is then used in the second pass to make a smaller and higher quality video.
  
  Please see the [ffmpeg VP9 documentation](https://trac.ffmpeg.org/wiki/Encode/VP9) if you’d like to learn more.
  
  ## A word about transcoding
  
  By the way, in general, transcoding formats (taking a compressed video and recompressing it with a different codec) is a bad idea as you’ll not only add the normal errors from lossy video encoding, but you’ll waste bits in the new format trying to preserve the artifacts from the old.
  
  ## If you mean “without quality loss” literally
  
  The `-lossless 1` option of ffmpeg’s VP9 encoder enables lossless quality mode, but with a potentially enormous increase in filesize.
  
  All you need is this:
  
  ```
  ffmpeg  -i input.mp4  -lossless 1  output.webm
  
  ```
  
  When I tried `-lossless 1` on a low-quality `mp4`, the resulting `webm` was 100× larger, which was not accceptable to me. However, if your `mp4` files are already very high quality, I expect the size difference will not be so great.
  
  > **Comments:**
  > **username_3**: `/dev/null`? What does this mean? What would the equivalent be for windows users? Are you overwriting `input.mp4` on the first pass? This answer needs more explanation on what exactly each component is doing. It doesn't offer intermediate users much explanation of how it works.  
  > **username_2**: Hi Hatefriend: My answer already includes a long explanation section plus a link for more information, so I'd rather not make it longer. Did you see the footnote regarding Microsoft Windows which answers your specific question? Also, as mentioned above, the first pass compiles statistics about the input file. There is no need to fear that it might overwrite the input.  
  > **username_4**: I tried convert .MTS file to .webm usig these two commands (Ubuntu 20.10, ffmpeg version 4.2.2). But I have got errors: "Invalid channel layout 5.1(side) for specified mapping family -1. Error initializing output stream 0:1 -- Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height"  
  > **username_5**: thanks for the answer. if transcoding is generally a bad idea, what do you recommend instead if you need to convert mp4 videos to webm and webm videos to mp4?  
  > **username_6**: Hmm. That didn't work. Second command failed: "Invalid channel layout 5.1(side) for specified mapping family -1. Error initializing output stream 0:1 -- Error while opening encoder for output stream #0:1 - maybe incorrect parameters such as bit_rate, rate, width or height"  
  > **username_7**: `File '/dev/null' already exists. Overwrite ? [y/N]` so I will switch it to /tmp/deleteme.webm  
  > **username_2**: @username_7 Thanks for letting me know that ffmpeg changed the default behaviour. It is safe to answer 'y" when writing to /dev/null as it is a fake file that ignores anything written to it. I've updated my answer to include the `-y` flag so that people won't be asked "Overwrite?".  
  > **username_8**: I think it is silly that 2 passes cannot be accomplished with one command. When I see two separate commands like this it makes me worry that the 2nd command will not even take into consideration what is accomplished by the first command.  
  > **username_9**: Would this work going the other way? ```ffmpeg  -i input.webm  -lossless 1  output.mp4```  
  > **username_2**: Good question. The answer is no, lossless mode is a feature of webm.  
  
  ---
  
  ### Answer by username_10 on 2020-07-04. Score: 1
  
  On Linux I use [optimizeVideo](https://gitlab.com/es20490446e/optimizeVideo), which is a wrapper around ffmpeg that automatically detects those settings according to [Google's recommendations](https://developers.google.com/media/vp9/settings/vod/).
  
  The result is a video which quality difference you cannot tell, but usually orders of magnitude smaller.
  
  [![Logo](https://i.sstatic.net/BQMCT.png)](https://i.sstatic.net/BQMCT.png)
  
  
  ---
  
  ### Answer by username_11 on 2024-09-12. Score: -1
  
  mp4 and webm are container formats. think of them as boxes that contain within them various video, audio, subtitle, chapter info, etc files.
  
  if all the streams within the source mp4 container file are compatible with webm container format then it can be losslessly converted to webm, this is called remuxing (aka stream copy). This process simply copies the individual streams from one container to another without changing them in any way.
  
  which is an extremely quick process and also lossless, has a trivial effect on file size (from mp4 to webm you save a bit of space). There is no generational quality loss due to not modifying the video and audio streams.
  
  <https://ffmpeg.org/ffmpeg.html#Stream-copy>
  
  ```
  ffmpeg -i input.mp4 -c copy output.webm
  
  ```
  
  I have tested the above command myself and it works great. if the mp4 container is using streams that are NOT compatible with webm. (for example h264 video. or srt subtitles). Then you cannot remux / stream copy it.
  
  If one of the streams you are trying to pass to webm is unsupported it will instead error out and inform you that:
  
  > Only VP8 or VP9 or AV1 video and Vorbis or Opus audio and WebVTT subtitles are supported for WebM.
  
  you would have to resort to re-encoding the unsupported stream. if you are re-encoding the video it is a lengthy process that will cause a variable hit to the image quality
  
  near negligible is possible with the right settings and quality input. although doing so might take a long time and a lot of space. depending on the exact details of input and output codec and configuration. furthermore each time you convert via re-encoding you suffer generational loss. so even negligible losses add up to serious losses if you do it over and over.
  
  technically, you can re-encode it into a lossless format or lossless setting. But doing so will result in obscenely large files. Making them impractical for many uses. realistically you won't be wanting to do that.
  
  > **Comments:**
  > **username_12**: Your post doesn't seem to answer the question  
  > **username_11**: @username_12 please reread. it clearly answers the question. He wanted to losslessly convert mp4 to webm using ffmpeg. I gave him the command to do so, being `ffmpeg -i input.mp4 -c copy output.webm` with the caveat that it can only be losslessly converted if the source mp4 file contains codecs which are compatible with webm. otherwise he would need to perform a lossy reencode to codecs which are compatible with webm  
  
  ---
  
  