Answers.Body: <p>Turns out the provided command is actually correct. The problem was in how I was testing the resulting HLS files. It didn't work correctly with VLC media player, but when using video.js in the chrome browser, it actually works.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-08-28T09:35:57.813Z
Answers.LastActivityDate: 2024-08-28T09:35:57.813Z
Answers.UserDisplayName: Gman
Body: <p>I have three videos: <code>low.mp4, mid.mp4</code> and <code>high.mp4</code>, all of which were generated from the same source file using ffmpeg with the following command:</p>
  <pre><code>ffmpeg -y -i source.mp4 -c:v libx264 -crf SOMEVALUE -preset veryfast -vsync 0 -bf 0 -x264-params scenecut=0:keyint=25:min-keyint=25 -c:a aac -ab 128k -f mp4 OUTPUT.mp4
  </code></pre>
  <p>Now, I want to stream these videos using the HLS protocol. I use the following ffmpeg command to generate the HLS streams:</p>
  <pre><code>ffmpeg -i low.mp4 -i mid.mp4 -i high.mp4 \
  -map 0:v -map 0:a -map 1:v -map 1:a -map 2:v -map 2:a \
  -c:v copy -c:a copy \
  -hls_time 4 -hls_playlist_type vod -hls_segment_type fmp4 \
  -hls_flags independent_segments \
  -var_stream_map &quot;v:0,a:0,name:low v:1,a:1,name:mid v:2,a:2,name:high&quot; \
  -master_pl_name master.m3u8 \
  -hls_segment_filename '%v/segment-%06d.m4s' \
  -hls_fmp4_init_filename '%v/init.mp4' \
  -strftime_mkdir 1 \
  -f hls '%v.m3u8'
  </code></pre>
  <p>While this command does generate the HLS streams, the resulting video quality is poor. However, if I omit the <code>-c:v copy -c:a copy</code> flags, the video quality is good, but the command takes significantly longer to run because it re-encodes the video.</p>
  <p>I'm looking for a solution that meets the following requirements:</p>
  <p><strong>Separate Quality Generation:</strong> The different quality versions (low.mp4, mid.mp4, high.mp4) should be created in a separate step. This is important because, in practice, we speed up this process by cutting the videos into smaller pieces, transcoding them in parallel, and then recombining them.</p>
  <p><strong>No Re-encoding During HLS Generation:</strong> The HLS generation step should not involve re-encoding the video, to save time.</p>
  <p><strong>High-Quality HLS Output:</strong> The final HLS output should have good video quality, similar to what is achieved when re-encoding.</p>
  <p>Is this possible? How?</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-28T04:46:22.467Z
Comments.Text: This is bizarre. A re-encoding can, at most, preserve source quality, not improve it. I would check your player and try others.
Comments.UserDisplayName: Gyan
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-08-28T07:37:14.970Z
Comments.Text: Sorry, I think my question was unclear. I’m not expecting higher quality because of re-encoding. My concern is that when I skip the re-encoding step (using -c:v copy -c:a copy), the resulting HLS stream exhibits poor video quality (the video is mostly grey, totally unrecognizable). It seems like the issue may be related to not fully adhering to the HLS protocol or some other compatibility problem.
Comments.UserDisplayName: Gman
Tags: <ffmpeg><streaming><hls>
Title: Generate HLS streams from pre-encoded videos without re-encoding using ffmpeg
UserDisplayName: Gman
ThreadText: # Generate HLS streams from pre-encoded videos without re-encoding using ffmpeg
  
  (Asked by: username_0 on 2024-08-27)
  
  I have three videos: `low.mp4, mid.mp4` and `high.mp4`, all of which were generated from the same source file using ffmpeg with the following command:
  
  ```
  ffmpeg -y -i source.mp4 -c:v libx264 -crf SOMEVALUE -preset veryfast -vsync 0 -bf 0 -x264-params scenecut=0:keyint=25:min-keyint=25 -c:a aac -ab 128k -f mp4 OUTPUT.mp4
  
  ```
  
  Now, I want to stream these videos using the HLS protocol. I use the following ffmpeg command to generate the HLS streams:
  
  ```
  ffmpeg -i low.mp4 -i mid.mp4 -i high.mp4 \
  -map 0:v -map 0:a -map 1:v -map 1:a -map 2:v -map 2:a \
  -c:v copy -c:a copy \
  -hls_time 4 -hls_playlist_type vod -hls_segment_type fmp4 \
  -hls_flags independent_segments \
  -var_stream_map "v:0,a:0,name:low v:1,a:1,name:mid v:2,a:2,name:high" \
  -master_pl_name master.m3u8 \
  -hls_segment_filename '%v/segment-%06d.m4s' \
  -hls_fmp4_init_filename '%v/init.mp4' \
  -strftime_mkdir 1 \
  -f hls '%v.m3u8'
  
  ```
  
  While this command does generate the HLS streams, the resulting video quality is poor. However, if I omit the `-c:v copy -c:a copy` flags, the video quality is good, but the command takes significantly longer to run because it re-encodes the video.
  
  I'm looking for a solution that meets the following requirements:
  
  **Separate Quality Generation:** The different quality versions (low.mp4, mid.mp4, high.mp4) should be created in a separate step. This is important because, in practice, we speed up this process by cutting the videos into smaller pieces, transcoding them in parallel, and then recombining them.
  
  **No Re-encoding During HLS Generation:** The HLS generation step should not involve re-encoding the video, to save time.
  
  **High-Quality HLS Output:** The final HLS output should have good video quality, similar to what is achieved when re-encoding.
  
  Is this possible? How?
  
  **Tags:** ffmpeg, streaming, hls
  
  > **Comments:**
  > **username_1**: This is bizarre. A re-encoding can, at most, preserve source quality, not improve it. I would check your player and try others.  
  > **username_0**: Sorry, I think my question was unclear. I’m not expecting higher quality because of re-encoding. My concern is that when I skip the re-encoding step (using -c:v copy -c:a copy), the resulting HLS stream exhibits poor video quality (the video is mostly grey, totally unrecognizable). It seems like the issue may be related to not fully adhering to the HLS protocol or some other compatibility problem.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2024-08-28. Score: 0
  
  Turns out the provided command is actually correct. The problem was in how I was testing the resulting HLS files. It didn't work correctly with VLC media player, but when using video.js in the chrome browser, it actually works.
  
  
  ---
  
  