Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
bash scripts to create VOD HLS stream with ffmpeg almighty (tested on Linux and OS X)

running:

bash create-vod-hls.sh beach.mkv

will produce:

    beach/
      |- playlist.m3u8
      |- 360p.m3u8
      |- 360p_001.ts
      |- 360p_002.ts
      |- 480p.m3u8
      |- 480p_001.ts
      |- 480p_002.ts
      |- 720p.m3u8
      |- 720p_001.ts
      |- 720p_002.ts
      |- 1080p.m3u8
      |- 1080p_001.ts
      |- 1080p_002.ts  

origin: http://docs.peer5.com/guides/production-ready-hls-vod/

#!/usr/bin/env bash
set -e
# Usage create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME]
[[ ! "${1}" ]] && echo "Usage: create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME]" && exit 1
# comment/add lines here to control which renditions would be created
renditions=(
# resolution bitrate audio-rate
# "426x240 400k 64k"
"640x360 800k 96k"
"842x480 1400k 128k"
"1280x720 2800k 128k"
"1920x1080 5000k 192k"
)
segment_target_duration=4 # try to create a new segment every X seconds
max_bitrate_ratio=1.07 # maximum accepted bitrate fluctuations
rate_monitor_buffer_ratio=1.5 # maximum buffer size between bitrate conformance checks
#########################################################################
source="${1}"
target="${2}"
if [[ ! "${target}" ]]; then
target="${source##*/}" # leave only last component of path
target="${target%.*}" # strip extension
fi
mkdir -p ${target}
key_frames_interval="$(echo `ffprobe ${source} 2>&1 | grep -oE '[[:digit:]]+(.[[:digit:]]+)? fps' | grep -oE '[[:digit:]]+(.[[:digit:]]+)?'`*2 | bc || echo '')"
key_frames_interval=${key_frames_interval:-50}
key_frames_interval=$(echo `printf "%.1f\n" $(bc -l <<<"$key_frames_interval/10")`*10 | bc) # round
key_frames_interval=${key_frames_interval%.*} # truncate to integer
# static parameters that are similar for all renditions
static_params="-c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0"
static_params+=" -g ${key_frames_interval} -keyint_min ${key_frames_interval} -hls_time ${segment_target_duration}"
static_params+=" -hls_playlist_type vod"
# misc params
misc_params="-hide_banner -y"
master_playlist="#EXTM3U
#EXT-X-VERSION:3
"
cmd=""
for rendition in "${renditions[@]}"; do
# drop extraneous spaces
rendition="${rendition/[[:space:]]+/ }"
# rendition fields
resolution="$(echo ${rendition} | cut -d ' ' -f 1)"
bitrate="$(echo ${rendition} | cut -d ' ' -f 2)"
audiorate="$(echo ${rendition} | cut -d ' ' -f 3)"
# calculated fields
width="$(echo ${resolution} | grep -oE '^[[:digit:]]+')"
height="$(echo ${resolution} | grep -oE '[[:digit:]]+$')"
maxrate="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${max_bitrate_ratio}" | bc)"
bufsize="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${rate_monitor_buffer_ratio}" | bc)"
bandwidth="$(echo ${bitrate} | grep -oE '[[:digit:]]+')000"
name="${height}p"
cmd+=" ${static_params} -vf scale=w=${width}:h=${height}:force_original_aspect_ratio=decrease"
cmd+=" -b:v ${bitrate} -maxrate ${maxrate%.*}k -bufsize ${bufsize%.*}k -b:a ${audiorate}"
cmd+=" -hls_segment_filename ${target}/${name}_%03d.ts ${target}/${name}.m3u8"
# add rendition entry in the master playlist
master_playlist+="#EXT-X-STREAM-INF:BANDWIDTH=${bandwidth},RESOLUTION=${resolution}\n${name}.m3u8\n"
done
# start conversion
echo -e "Executing command:\nffmpeg ${misc_params} -i ${source} ${cmd}"
ffmpeg ${misc_params} -i ${source} ${cmd}
# create master playlist file
echo -e "${master_playlist}" > ${target}/playlist.m3u8
echo "Done - encoded HLS is at ${target}/"
@p3rtinax

This comment has been minimized.

Copy link

@p3rtinax p3rtinax commented Mar 2, 2018

is it possible to add "ffprobe source.mp4" and detect input height,
then create HLS resolution =< source ?
example :
source.mp4 is 720p ( 1280x720 )
then create HLS 720p, 480p, 360p, 240p
another thing is:
for example if source is between 1080p and 720p then again output will begin from 720p and so on
if source is between 2160p and 1080p then again output will begin from 1080p and so on

@bapfnet

This comment has been minimized.

Copy link

@bapfnet bapfnet commented Mar 10, 2018

Hi, I thank you for this bash but it doesn't work and I have no idea how to fix it ...
errors listed from: Undefined constant or missing '(' in 'keyint_min'
below.....

Bastians-iMac: ffmpeg imac$ bash create-vod-hls.sh orig_homm.mp4 ffprobe orig_homm.mp4
create-vod-hls.sh: line 35: printf: 6.00000000000000000000: invalid number
(standard_in) 1: parse error
Executing command:
ffmpeg -hide_banner -y -i orig_homm.mp4 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g -keyint_min -hls_time 4 -hls_playlist_type vod -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename ffprobe/360p_%03d.ts ffprobe/360p.m3u8 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g -keyint_min -hls_time 4 -hls_playlist_type vod -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename ffprobe/480p_%03d.ts ffprobe/480p.m3u8 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g -keyint_min -hls_time 4 -hls_playlist_type vod -vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename ffprobe/720p_%03d.ts ffprobe/720p.m3u8 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g -keyint_min -hls_time 4 -hls_playlist_type vod -vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename ffprobe/1080p_%03d.ts ffprobe/1080p.m3u8
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'orig_homm.mp4':
Metadata:
major_brand : mp42
minor_version : 0
compatible_brands: mp42isomavc1
creation_time : 2018-01-26T02:37:26.000000Z
encoder : HandBrake 0.9.9 2013051800
Duration: 00:03:57.57, start: 0.000000, bitrate: 16117 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 15966 kb/s, 30 fps, 30 tbr, 90k tbn, 180k tbc (default)
Metadata:
creation_time : 2018-01-26T02:37:26.000000Z
encoder : JVT/AVC Coding
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 151 kb/s (default)
Metadata:
creation_time : 2018-01-26T02:37:26.000000Z
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #0:1 (aac (native) -> aac (native))
Stream #0:0 -> #1:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #1:1 (aac (native) -> aac (native))
Stream #0:0 -> #2:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #2:1 (aac (native) -> aac (native))
Stream #0:0 -> #3:0 (h264 (native) -> h264 (libx264))
Stream #0:1 -> #3:1 (aac (native) -> aac (native))
Press [q] to stop, [?] for help
[libx264 @ 0x7ffd31804c00] [Eval @ 0x7fff577ad7e0] Undefined constant or missing '(' in 'keyint_min'
[libx264 @ 0x7ffd31804c00] Unable to parse option value "-keyint_min"
[libx264 @ 0x7ffd31804c00] Error setting option g to value -keyint_min.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
[aac @ 0x7ffd31806400] Qavg: 20328.691
[aac @ 0x7ffd31806400] 2 frames left in the queue on closing
[aac @ 0x7ffd3180a200] Qavg: 25456.812
[aac @ 0x7ffd3180a200] 2 frames left in the queue on closing
[aac @ 0x7ffd3181b000] Qavg: 25456.812
[aac @ 0x7ffd3181b000] 2 frames left in the queue on closing
[aac @ 0x7ffd3181ee00] Qavg: 52410.695
[aac @ 0x7ffd3181ee00] 2 frames left in the queue on closing
Conversion failed!

@AndriiFed

This comment has been minimized.

Copy link

@AndriiFed AndriiFed commented Mar 23, 2018

Your options -g -keyint_min do not have values.
Should be -g 50 -keyint_min 25 for example.

@sybon

This comment has been minimized.

Copy link

@sybon sybon commented Oct 2, 2018

Dear Andrii,

On the basis of your code (thank you for this !)
Could you give the right command line or advice to produce such a HLS PLaylist (multi video / multi audio / multi subtitle) HLS playlist (m3u8 with synchro. segments) : http://sample.vodobox.com/planete_interdite/planete_interdite_alternate.m3u8
out of an mp4 video for example.

File content of the expecting results for the MASTER.M38 (planete_interdite_alternate.m3u8):
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitle",NAME="#1 Fre",DEFAULT=NO,FORCED=NO,LANGUAGE="fre",URI="subtitles/planete_interdite_subtitle3_fre_vtt.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitle",NAME="#2 Eng",DEFAULT=NO,FORCED=NO,LANGUAGE="eng",URI="subtitles/planete_interdite_subtitle4_eng_vtt.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitle",NAME="#3 Eng",DEFAULT=NO,FORCED=NO,LANGUAGE="eng",URI="subtitles/planete_interdite_subtitle5_eng_vtt.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="low",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="low/planete_interdite_228_h264_144p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="low",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="low/planete_interdite_228_h264_144p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="medium",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="medium/planete_interdite_500_h264_240p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="medium",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="medium/planete_interdite_500_h264_240p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="high",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="high/planete_interdite_1228_q264_360p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="high",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="high/planete_interdite_1228_q264_360p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="veryhigh",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="veryhigh/planete_interdite_2080_q264_480p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="veryhigh",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="veryhigh/planete_interdite_2080_q264_480p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="hdready",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="hdready/planete_interdite_4160_n264_720p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="hdready",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="hdready/planete_interdite_4160_n264_720p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="fullhd",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="fullhd/planete_interdite_8256_n264_1080p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="fullhd",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="fullhd/planete_interdite_8256_n264_1080p_audio2_eng.m3u8"
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=314000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=256x144,AUDIO="low",SUBTITLES="subtitle"
low/planete_interdite_228_h264_144p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=638000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=426x240,AUDIO="medium",SUBTITLES="subtitle"
medium/planete_interdite_500_h264_240p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1942000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=640x360,AUDIO="high",SUBTITLES="subtitle"
high/planete_interdite_1228_q264_360p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3274000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=854x480,AUDIO="veryhigh",SUBTITLES="subtitle"
veryhigh/planete_interdite_2080_q264_480p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4814000,CODECS="avc1.4d001f,mp4a.40.2",RESOLUTION=1280x720,AUDIO="hdready",SUBTITLES="subtitle"
hdready/planete_interdite_4160_n264_720p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=9501000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="fullhd",SUBTITLES="subtitle"
fullhd/planete_interdite_8256_n264_1080p.m3u8

Thank you if you can help.

Best regards,

Sylvain

@rocketon85

This comment has been minimized.

Copy link

@rocketon85 rocketon85 commented Nov 8, 2018

Dear Andrii,

On the basis of your code (thank you for this !)
Could you give the right command line or advice to produce such a HLS PLaylist (multi video / multi audio / multi subtitle) HLS playlist (m3u8 with synchro. segments) : http://sample.vodobox.com/planete_interdite/planete_interdite_alternate.m3u8
out of an mp4 video for example.

File content of the expecting results for the MASTER.M38 (planete_interdite_alternate.m3u8):
#EXTM3U
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitle",NAME="#1 Fre",DEFAULT=NO,FORCED=NO,LANGUAGE="fre",URI="subtitles/planete_interdite_subtitle3_fre_vtt.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitle",NAME="#2 Eng",DEFAULT=NO,FORCED=NO,LANGUAGE="eng",URI="subtitles/planete_interdite_subtitle4_eng_vtt.m3u8"
#EXT-X-MEDIA:TYPE=SUBTITLES,GROUP-ID="subtitle",NAME="#3 Eng",DEFAULT=NO,FORCED=NO,LANGUAGE="eng",URI="subtitles/planete_interdite_subtitle5_eng_vtt.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="low",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="low/planete_interdite_228_h264_144p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="low",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="low/planete_interdite_228_h264_144p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="medium",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="medium/planete_interdite_500_h264_240p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="medium",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="medium/planete_interdite_500_h264_240p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="high",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="high/planete_interdite_1228_q264_360p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="high",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="high/planete_interdite_1228_q264_360p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="veryhigh",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="veryhigh/planete_interdite_2080_q264_480p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="veryhigh",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="veryhigh/planete_interdite_2080_q264_480p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="hdready",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="hdready/planete_interdite_4160_n264_720p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="hdready",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="hdready/planete_interdite_4160_n264_720p_audio2_eng.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="fullhd",NAME="#1 Fre",DEFAULT=YES,AUTOSELECT=YES,LANGUAGE="fre",URI="fullhd/planete_interdite_8256_n264_1080p_audio1_fre.m3u8"
#EXT-X-MEDIA:TYPE=AUDIO,GROUP-ID="fullhd",NAME="#2 Eng",DEFAULT=NO,AUTOSELECT=YES,LANGUAGE="eng",URI="fullhd/planete_interdite_8256_n264_1080p_audio2_eng.m3u8"
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=314000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=256x144,AUDIO="low",SUBTITLES="subtitle"
low/planete_interdite_228_h264_144p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=638000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=426x240,AUDIO="medium",SUBTITLES="subtitle"
medium/planete_interdite_500_h264_240p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=1942000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=640x360,AUDIO="high",SUBTITLES="subtitle"
high/planete_interdite_1228_q264_360p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=3274000,CODECS="avc1.66.30,mp4a.40.2",RESOLUTION=854x480,AUDIO="veryhigh",SUBTITLES="subtitle"
veryhigh/planete_interdite_2080_q264_480p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=4814000,CODECS="avc1.4d001f,mp4a.40.2",RESOLUTION=1280x720,AUDIO="hdready",SUBTITLES="subtitle"
hdready/planete_interdite_4160_n264_720p.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=9501000,CODECS="avc1.640028,mp4a.40.2",RESOLUTION=1920x1080,AUDIO="fullhd",SUBTITLES="subtitle"
fullhd/planete_interdite_8256_n264_1080p.m3u8

Thank you if you can help.

Best regards,

Sylvain

Uy that would be very good, configure the nginx, but if I use ffmpeg on rtmp I see the video in live, and I can not handle audio, subtitles, etc ... I found some examples but with VideoJs they give me error in "slice .... "

Thanks

@pberthol

This comment has been minimized.

Copy link

@pberthol pberthol commented Nov 13, 2018

great script but i have error when i use your script :

Press [q] to stop, [?] for help
[libx264 @ 0x7febe5808a00] [Eval @ 0x7ffee8d08820] Undefined constant or missing '(' in 'keyint_min'
[libx264 @ 0x7febe5808a00] Unable to parse option value "-keyint_min"
[libx264 @ 0x7febe5808a00] Error setting option g to value -keyint_min.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
Conversion failed!

this part :

  key_frames_interval="$(echo `ffprobe ${source} 2>&1 | grep -oE '[[:digit:]]+(.[[:digit:]]+)? fps' | grep -oE '[[:digit:]]+(.[[:digit:]]+)?'`*2 | bc || echo '')"
 key_frames_interval=${key_frames_interval:-50}
 key_frames_interval=$(echo `printf "%.1f\n" $(bc -l <<<"$key_frames_interval/10")`*10 | bc) # round
key_frames_interval=${key_frames_interval%.*} # truncate to integer

seems doesn't work.

tested on osx mojave
ffmpeg 4.1 ffprobe 4.1

enhanced :
i want sperate resolution per subfolder
bleach /360p/001.ts 002ts 003.ts...
/720p/001.ts 002ts 003.ts...
how do that ?

@rishcool

This comment has been minimized.

Copy link

@rishcool rishcool commented Dec 5, 2018

Hey!

I need to your help for adding overlay so i made below changes in script and my new "cmd" is below:

filter="movie=test.png[watermark];[watermark][0]scale2ref=200iw/1280:200iw/1280[wm][v];[wm]setsar=1[logo];[v][logo] overlay=main_w-overlay_w-5:main_h-overlay_h-5, scale=floor(iw*min(1,min(${width}/iw,${height}/ih))/2+0.4999999)*2:-2 [out]"

cmd+="-filter_complex "${filter}" -map [out] -map 0:a -c:a copy"
cmd+=" ${static_params} -movflags faststart"
cmd+=" -b:v ${bitrate} -maxrate ${maxrate%.}k -bufsize ${bufsize%.}k -b:a ${audiorate}"
cmd+=" -hls_segment_filename ${target}${name}/${hash}_%03d.ts ${target}${name}/${hash}.m3u8 -strict -1"

but its not taking "' (quotes)" and giving and error
[AVFilterGraph @ 0x2e85280] No such filter: ''

and if i am running below command its working fine:

ffmpeg -hide_banner -y -i test.mp4 -filter_complex movie=test.png[watermark];[watermark][0]scale2ref=200iw/1280:200iw/1280[wm][v];[wm]setsar=1[logo];[v][logo] overlay=main_w-overlay_w-5:main_h-overlay_h-5, scale=floor(iw*min(1,min(426/iw,240/ih))/2+0.4999999)*2:-2 [out] -map [out] -map 0:a -c:a copy -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 60 -keyint_min 60 -hls_time 4 -hls_playlist_type vod -movflags faststart -b:v 400k -maxrate 428k -bufsize 600k -b:a 64k -hls_segment_filename videos/240p/test_%03d.ts videos/240p/test.m3u8 -strict -1 -c copy -f flv

@Sergerant

This comment has been minimized.

Copy link

@Sergerant Sergerant commented Dec 9, 2018

Also having issue on latest Mac OS etc.

./create-vod-hls.sh: line 35: printf: 10.00000000000000000000: invalid number
(standard_in) 1: parse error

[libx264 @ 0x7ff756099e00] [Eval @ 0x7ffee3708760] Undefined constant or missing '(' in 'keyint_min'
[libx264 @ 0x7ff756099e00] Unable to parse option value "-keyint_min"
[libx264 @ 0x7ff756099e00] Error setting option g to value -keyint_min.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height

@jisln

This comment has been minimized.

Copy link

@jisln jisln commented Dec 17, 2018

For mac OS users who get create-vod-hls.sh: line 35: printf: 6.00000000000000000000: invalid number
you can consider adding export LC_NUMERIC="en_US.UTF-8" in the very beginning of your script.

Thanks for the job !

@tamir-maoz

This comment has been minimized.

Copy link

@tamir-maoz tamir-maoz commented Dec 24, 2018

Hi,
I have a multi-rendition video, segmented in 10sec intervals using the above script.
i'm trying to add subtitles (webVTT format).
since my videos are short (~2 min) i don't mind having a single subtitle file (for each language) that will be used for all renditions and segments.
is it possible?
i'm unable to find where and which command should i add to achieve it.
if the above is not possible, what would be the best approach?
Thanks.

@FullstackJack

This comment has been minimized.

Copy link

@FullstackJack FullstackJack commented Jan 30, 2019

Thanks for sharing this, I'll keep testing it out and see if we can make any improvements.

Seems to work on macOS Mojave 10.14.2 with latest brew version of ffmpeg.

Input File: http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4

ffmpeg version 4.1 Copyright (c) 2000-2018 the FFmpeg developers
  built with Apple LLVM version 10.0.0 (clang-1000.11.45.5)
  configuration: --prefix=/usr/local/Cellar/ffmpeg/4.1_3 --enable-shared --enable-pthreads --enable-version3 --enable-hardcoded-tables --enable-avresample --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gpl --enable-libmp3lame --enable-libopus --enable-libsnappy --enable-libtheora --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libx265 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-librtmp --enable-libspeex --enable-videotoolbox
  libavutil      56. 22.100 / 56. 22.100
  libavcodec     58. 35.100 / 58. 35.100
  libavformat    58. 20.100 / 58. 20.100
  libavdevice    58.  5.100 / 58.  5.100
  libavfilter     7. 40.101 /  7. 40.101
  libavresample   4.  0.  0 /  4.  0.  0
  libswscale      5.  3.100 /  5.  3.100
  libswresample   3.  3.100 /  3.  3.100
  libpostproc    55.  3.100 / 55.  3.100
@FullstackJack

This comment has been minimized.

Copy link

@FullstackJack FullstackJack commented Jan 30, 2019

In the terminal, is the time string on the frame line the time elapsed?
For instance, my last frame of transcode for Big Buck Bunny was the following:
frame=19038 fps= 22 q=-1.0 Lq=-1.0 q=-1.0 q=-1.0 size=N/A time=00:10:34.53 bitrate=N/A dup=8 drop=0 speed=0.741

@appserv64

This comment has been minimized.

Copy link

@appserv64 appserv64 commented Feb 10, 2019

Ubuntu 16.04 , ffmpeg 4.1.1
create-vod-hls.sh: line 33: bc: command not found
create-vod-hls.sh: line 35: bc: command not found
create-vod-hls.sh: line 35: bc: command not found

@m-emelchenkov

This comment has been minimized.

Copy link

@m-emelchenkov m-emelchenkov commented Feb 11, 2019

@appserv64 bc is a text-mode calculator, not ffmpeg-related tool. You can install it via apt install bc.

@havishmanakkina

This comment has been minimized.

Copy link

@havishmanakkina havishmanakkina commented Apr 1, 2019

Thank you for the script...
It works completely fine...
but takes a lot of time to process when we try to convert a video which is 39 min and 200MB of a size
we are using a dual core processor and 4 gb RAM
it is nearly taking more than an hour to process it
can you help us if there is anything that we can do to speed up the process...
thank you in advance

@elmadkoun

This comment has been minimized.

Copy link

@elmadkoun elmadkoun commented Apr 9, 2019

/usr/bin/create-vod-hls.sh: line 33: bc: command not found
/usr/bin/create-vod-hls.sh: line 35: bc: command not found
/usr/bin/create-vod-hls.sh: line 35: bc: command not found

@FrancoJoaquinTorres

This comment has been minimized.

Copy link

@FrancoJoaquinTorres FrancoJoaquinTorres commented Apr 23, 2019

Hi, thanks for you script. I need help with other problem. I have one video with multiple quality and multiple audios. The audio have the same quality. How i can modify script for this.
Example
video1 --> 1080 | 720 | 480
audio --> english | spanish (same quality)
It possible?
Thanks!

@dangayle

This comment has been minimized.

Copy link

@dangayle dangayle commented Apr 24, 2019

Thank you sir, this is exactly the script I've been looking for.

@Teranode

This comment has been minimized.

Copy link

@Teranode Teranode commented May 19, 2019

@elmadkoun
apt-get install bc
or
yum install bc

@Das-Sreedeep

This comment has been minimized.

Copy link

@Das-Sreedeep Das-Sreedeep commented Jun 17, 2019

Unrecognized option 'hls_playlist_type'.
Error splitting the argument list: Option not found

Getting in ubuntu

@monokal

This comment has been minimized.

Copy link

@monokal monokal commented Jul 2, 2019

Here's a re-write in Python which includes IPFS support. PRs very welcome:
https://github.com/desiredState/IPFSStreamingVideo

@obender75

This comment has been minimized.

Copy link

@obender75 obender75 commented Jul 9, 2019

in key_frames_interval you just get frame rate it has nothing to do with gop size, you may be lucky though 'cuz most of the time gop would be multiple of framerate, but you'll get wrong values of your source was enoded with adaptative gop (which is totally legit in h264). you can even get ts sources where gop changes somemewhere in the middle of the flight. you need to dump frame types, parce it and compute gop size checking the distance b/w idr frames (and may be check if gop is constant and closed as well). check how it's done ~correctly here : https://snippets.bentasker.co.uk/page-1707191206-Get-Video-Keyframe-Interval-(ffprobe)-BASH.html
.
it's a useless stage in fract try to duplicate the gop of your source as you reencode, it might have been pretty useful if you wanted to just repackage mp4 sources encoded for segmented http without transcoding...

@mike1011

This comment has been minimized.

Copy link

@mike1011 mike1011 commented Nov 14, 2019

right way to run this file ...

sudo /bin/bash create-vod-hls.sh public/sample_videos/1.mp4 public/sample_videos/

@desmeit

This comment has been minimized.

Copy link

@desmeit desmeit commented Dec 27, 2019

Is it possible to run this script for all files in a directory?

@mrbar42

This comment has been minimized.

Copy link
Owner Author

@mrbar42 mrbar42 commented Dec 29, 2019

loop all files in my-vids directory that ends with mp4

mkdir -p out
for file in `ls my-vids | grep '\.mp4$'`; do
  bash create-vod-hls.sh "$file"  "out/$file"
done
@vanthoi

This comment has been minimized.

Copy link

@vanthoi vanthoi commented Jan 3, 2020

It works fine on my server CentOS 7. I have 16 Core 16GB RAM but it has all the RAM and CPU. And the one problem I encountered is that I have a 1080p mp4 video file of about 700MB. After the encoder has finished, the total size of 1080p files is up to 1.2GB.
Another problem is that it has too many files in a 40 minute video. It up to thousands of files, they are fragmented and reduce the read speed of the hard drive!

@ufukomer

This comment has been minimized.

Copy link

@ufukomer ufukomer commented Mar 8, 2020

Got an error:

width not divisible by 2 (465x360)
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
@teknetdc

This comment has been minimized.

Copy link

@teknetdc teknetdc commented Apr 9, 2020

Hello

i need this script for nvidia cuda how is possible ?

@teknetdc

This comment has been minimized.

Copy link

@teknetdc teknetdc commented Apr 10, 2020

i wrote

I made some changes to the nvidia gpu. if there is more than one sound and gpu, just enter id

#!/usr/bin/env bash

set -e

# Usage create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME]
[[ ! "${1}" ]] && echo "Usage: create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME] AudioTrack GPUNumber" && exit 1

# comment/add lines here to control which renditions would be created
renditions=(
# resolution  bitrate  audio-rate
  "426x240    400k    64k"
  "640x360    800k     96k"
  "842x480    1400k    128k"
  "1280x720   2800k    128k"
  "1920x1080  5000k    192k"
)

segment_target_duration=10       # try to create a new segment every X seconds
max_bitrate_ratio=1.07          # maximum accepted bitrate fluctuations
rate_monitor_buffer_ratio=1.5   # maximum buffer size between bitrate conformance checks

#########################################################################

source="${1}"
target="${2}"
if [[ ! "${target}" ]]; then
  target="${source##*/}" # leave only last component of path
  target="${target%.*}"  # strip extension
fi
mkdir -p ${target}


key_frames_interval="$(echo `ffprobe ${source} 2>&1 | grep -oE '[[:digit:]]+(.[[:digit:]]+)? fps' | grep -oE '[[:digit:]]+(.[[:digit:]]+)?'`*2 | bc || echo '')"
key_frames_interval=${key_frames_interval:-50}
key_frames_interval=$(echo `printf "%.1f\n" $(bc -l <<<"$key_frames_interval/10")`*10 | bc) # round
key_frames_interval=${key_frames_interval%.*} # truncate to integer

# static parameters that are similar for all renditions
static_params="-map 0:v:${3} -map 0:a:${4} -c:a libfdk_aac -ar 48000 -c:v h264_nvenc -profile:v main -preset:v fast -rc constqp -qp 30 -crf 20 -sc_threshold 0 "
static_params+=" -g ${key_frames_interval} -keyint_min ${key_frames_interval} -hls_time ${segment_target_duration}"
static_params+=" -hls_playlist_type vod"

# misc params
misc_params="-vsync 0 -hwaccel cuvid -hwaccel_device ${4} -hwaccel_output_format cuda -c:v h264_cuvid -hide_banner -y "

master_playlist="#EXTM3U
#EXT-X-VERSION:3
"
cmd=""
for rendition in "${renditions[@]}"; do
  # drop extraneous spaces
  rendition="${rendition/[[:space:]]+/ }"

  # rendition fields
  resolution="$(echo ${rendition} | cut -d ' ' -f 1)"
  bitrate="$(echo ${rendition} | cut -d ' ' -f 2)"
  audiorate="$(echo ${rendition} | cut -d ' ' -f 3)"

  # calculated fields
  width="$(echo ${resolution} | grep -oE '^[[:digit:]]+')"
  height="$(echo ${resolution} | grep -oE '[[:digit:]]+$')"
  maxrate="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${max_bitrate_ratio}" | bc)"
  bufsize="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${rate_monitor_buffer_ratio}" | bc)"
  bandwidth="$(echo ${bitrate} | grep -oE '[[:digit:]]+')000"
  name="${height}p"

  cmd+=" ${static_params} -vf scale_npp=w=${width}:h=${height}:force_original_aspect_ratio=decrease:format=yuv420p "
  cmd+=" -b:v ${bitrate} -maxrate ${maxrate%.*}k -bufsize ${bufsize%.*}k -b:a ${audiorate}"
  cmd+=" -hls_segment_filename ${target}/${name}_%03d.ts ${target}/${name}.m3u8"

  # add rendition entry in the master playlist
  master_playlist+="#EXT-X-STREAM-INF:BANDWIDTH=${bandwidth},RESOLUTION=${resolution}\n${name}.m3u8\n"
done

# start conversion
echo -e "Executing command:\nffmpeg ${misc_params} -i ${source} ${cmd}"
ffmpeg ${misc_params} -i ${source} ${cmd}

# create master playlist file
echo -e "${master_playlist}" > ${target}/playlist.m3u8

echo "Done - encoded HLS is at ${target}/"
@Jackfritt

This comment has been minimized.

Copy link

@Jackfritt Jackfritt commented Apr 15, 2020

If you use other language than english you get problem with printf in the bash script

../hls.sh ../output-video.mp4 l2r 0 0
../hls.sh: Zeile 36: printf: 5.00000000000000000000: Ungültige Zahl.
(standard_in) 1: syntax error
Executing command:
..

so try this and you get rid of it.

LC_ALL=C ../hls.sh ../output-video.mp4 l2r 0 0

@lehuy2012

This comment has been minimized.

Copy link

@lehuy2012 lehuy2012 commented May 5, 2020

Hi There,
I have a question - hope you can support me.

  1. How can I run this script (create-vod-hls.sh) with input from video on S3 ?
  2. If question 1 is OK... then how can I convert with multi video from S3 (bow)

Many thanks

@Hanoosh

This comment has been minimized.

Copy link

@Hanoosh Hanoosh commented May 15, 2020

is it possible to add "ffprobe source.mp4" and detect input height,
then create HLS resolution =< source ?
example :
source.mp4 is 720p ( 1280x720 )
then create HLS 720p, 480p, 360p, 240p
another thing is:
for example if source is between 1080p and 720p then again output will begin from 720p and so on
if source is between 2160p and 1080p then again output will begin from 1080p and so on

looking for same, did you find a way ?

@0crypto0

This comment has been minimized.

Copy link

@0crypto0 0crypto0 commented May 24, 2020

hi i ran this script and it cut all my files to around 17 secs long vids.
any idea why?

@navanshu

This comment has been minimized.

Copy link

@navanshu navanshu commented Jun 4, 2020

i wrote

I made some changes to the nvidia gpu. if there is more than one sound and gpu, just enter id

#!/usr/bin/env bash

set -e

# Usage create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME]
[[ ! "${1}" ]] && echo "Usage: create-vod-hls.sh SOURCE_FILE [OUTPUT_NAME] AudioTrack GPUNumber" && exit 1

# comment/add lines here to control which renditions would be created
renditions=(
# resolution  bitrate  audio-rate
  "426x240    400k    64k"
  "640x360    800k     96k"
  "842x480    1400k    128k"
  "1280x720   2800k    128k"
  "1920x1080  5000k    192k"
)

segment_target_duration=10       # try to create a new segment every X seconds
max_bitrate_ratio=1.07          # maximum accepted bitrate fluctuations
rate_monitor_buffer_ratio=1.5   # maximum buffer size between bitrate conformance checks

#########################################################################

source="${1}"
target="${2}"
if [[ ! "${target}" ]]; then
  target="${source##*/}" # leave only last component of path
  target="${target%.*}"  # strip extension
fi
mkdir -p ${target}


key_frames_interval="$(echo `ffprobe ${source} 2>&1 | grep -oE '[[:digit:]]+(.[[:digit:]]+)? fps' | grep -oE '[[:digit:]]+(.[[:digit:]]+)?'`*2 | bc || echo '')"
key_frames_interval=${key_frames_interval:-50}
key_frames_interval=$(echo `printf "%.1f\n" $(bc -l <<<"$key_frames_interval/10")`*10 | bc) # round
key_frames_interval=${key_frames_interval%.*} # truncate to integer

# static parameters that are similar for all renditions
static_params="-map 0:v:${3} -map 0:a:${4} -c:a libfdk_aac -ar 48000 -c:v h264_nvenc -profile:v main -preset:v fast -rc constqp -qp 30 -crf 20 -sc_threshold 0 "
static_params+=" -g ${key_frames_interval} -keyint_min ${key_frames_interval} -hls_time ${segment_target_duration}"
static_params+=" -hls_playlist_type vod"

# misc params
misc_params="-vsync 0 -hwaccel cuvid -hwaccel_device ${4} -hwaccel_output_format cuda -c:v h264_cuvid -hide_banner -y "

master_playlist="#EXTM3U
#EXT-X-VERSION:3
"
cmd=""
for rendition in "${renditions[@]}"; do
  # drop extraneous spaces
  rendition="${rendition/[[:space:]]+/ }"

  # rendition fields
  resolution="$(echo ${rendition} | cut -d ' ' -f 1)"
  bitrate="$(echo ${rendition} | cut -d ' ' -f 2)"
  audiorate="$(echo ${rendition} | cut -d ' ' -f 3)"

  # calculated fields
  width="$(echo ${resolution} | grep -oE '^[[:digit:]]+')"
  height="$(echo ${resolution} | grep -oE '[[:digit:]]+$')"
  maxrate="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${max_bitrate_ratio}" | bc)"
  bufsize="$(echo "`echo ${bitrate} | grep -oE '[[:digit:]]+'`*${rate_monitor_buffer_ratio}" | bc)"
  bandwidth="$(echo ${bitrate} | grep -oE '[[:digit:]]+')000"
  name="${height}p"

  cmd+=" ${static_params} -vf scale_npp=w=${width}:h=${height}:force_original_aspect_ratio=decrease:format=yuv420p "
  cmd+=" -b:v ${bitrate} -maxrate ${maxrate%.*}k -bufsize ${bufsize%.*}k -b:a ${audiorate}"
  cmd+=" -hls_segment_filename ${target}/${name}_%03d.ts ${target}/${name}.m3u8"

  # add rendition entry in the master playlist
  master_playlist+="#EXT-X-STREAM-INF:BANDWIDTH=${bandwidth},RESOLUTION=${resolution}\n${name}.m3u8\n"
done

# start conversion
echo -e "Executing command:\nffmpeg ${misc_params} -i ${source} ${cmd}"
ffmpeg ${misc_params} -i ${source} ${cmd}

# create master playlist file
echo -e "${master_playlist}" > ${target}/playlist.m3u8

echo "Done - encoded HLS is at ${target}/"

Option hwaccel (use HW accelerated decoding) cannot be applied to output url cuda -- you are trying to apply an input option to an output file or vice versa. Move this option before the file it belongs to.
Error parsing options for output file cuda.

I get this error. Could you please help me?

@maitrungduc1410

This comment has been minimized.

Copy link

@maitrungduc1410 maitrungduc1410 commented Jun 5, 2020

This is my extended version of this script that supports auto generate bitrates based on video source resolution, and handle cases when video after scaling has dimensions are not divisible by 2 that will cause error at run time.

Link: https://gist.github.com/maitrungduc1410/9c640c61a7871390843af00ae1d8758e

@dotesfera

This comment has been minimized.

Copy link

@dotesfera dotesfera commented Jun 18, 2020

Hi is there anyone willing to show an example to apply vtt subtitles with this script?

@waakobrian

This comment has been minimized.

Copy link

@waakobrian waakobrian commented Jun 28, 2020

Can we have a windows version of the script??

@Feujo

This comment has been minimized.

Copy link

@Feujo Feujo commented Jul 22, 2020

Thanks for the script. But when I run this, here's my error message.

./create-vod-hls.sh 022505043294641312470435.mp4

[libx264 @ 0x55a878bcb800] [Eval @ 0x7fff9d53be00] Undefined constant or missing '(' in 'keyint_min'
[libx264 @ 0x55a878bcb800] Unable to parse option value "-keyint_min"
[libx264 @ 0x55a878bcb800] Error setting option g to value -keyint_min.
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
[aac @ 0x55a878bca840] Qavg: 119.779
[aac @ 0x55a878bca840] 2 frames left in the queue on closing
[aac @ 0x55a878b9c080] Qavg: 119.779
[aac @ 0x55a878b9c080] 2 frames left in the queue on closing
[aac @ 0x55a878bcf800] Qavg: 119.779
[aac @ 0x55a878bcf800] 2 frames left in the queue on closing
[aac @ 0x55a878ba8e40] Qavg: 119.779
[aac @ 0x55a878ba8e40] 2 frames left in the queue on closing

@seenickcode

This comment has been minimized.

Copy link

@seenickcode seenickcode commented Jul 26, 2020

It seems this script only outputs the filename on the next line after each #EXT-X-STREAM-INF line and this seems to 'break' any m3u8 playlist file because the entire URL to the file has to exist, no? (reference from Apple https://developer.apple.com/documentation/http_live_streaming/example_playlists_for_http_live_streaming/creating_a_master_playlist)

On other words, I cannot get this to work with this example:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720
720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
1080p.m3u8

It seems to only work if I cite the URLs to the files:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-STREAM-INF:BANDWIDTH=800000,RESOLUTION=640x360
http://mydomain.com/360p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=2800000,RESOLUTION=1280x720
http://mydomain.com/720p.m3u8
#EXT-X-STREAM-INF:BANDWIDTH=5000000,RESOLUTION=1920x1080
http://mydomain.com/1080p.m3u8
@kashkashio

This comment has been minimized.

Copy link

@kashkashio kashkashio commented Aug 19, 2020

This is my extended version of this script that supports auto generate bitrates based on video source resolution, and handle cases when video after scaling has dimensions are not divisible by 2 that will cause error at run time.

Link: https://gist.github.com/maitrungduc1410/9c640c61a7871390843af00ae1d8758e

You are a life saver ! Works great !
Tho thanks to OP for first answer !

Tho i wonder for exampe how dose sfari determines which resultion to take from the playlist?
By screen size? by network speed? latency etc... ?

P.S
How can i force it to split to even more chunks ? it dose like 3 chunks for 22 seconds video
Can i force it into more ?

@mindjek07

This comment has been minimized.

Copy link

@mindjek07 mindjek07 commented Aug 31, 2020

Hi, thanks for you script. I need help with other problem. I have one video with multiple quality and multiple audios. The audio have the same quality. How i can modify script for this.
Example
video1 --> 1080 | 720 | 480
audio --> english | spanish (same quality)
It possible?
Thanks!

Replace Line Number 39 :

static_params="-c:a copy -map 0:a -map 0:v -c:v h264 -profile:v main -crf 19 -sc_threshold 0

-c:a copy >> copy audio without convert
-c:v copy >> copy video without convert
-c:av copy >> copy audio and video without convert
-map 0:a >> all audio
-map 0:v >> all videos
-map 0:s >> all subtitles

@kutanoor

This comment has been minimized.

Copy link

@kutanoor kutanoor commented Sep 24, 2020

when i try to convert the video it gives me error
bash create-vod-hls.sh vid.mp4 Executing command: ffmpeg -hide_banner -y -i vid.mp4 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 60 -keyint_min 60 -hls_time 4 -hls_playlist_type vod -vf scale=w=640:h=360:force_original_aspect_ratio=decrease -b:v 800k -maxrate 856k -bufsize 1200k -b:a 96k -hls_segment_filename vid/360p_%03d.ts vid/360p.m3u8 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 60 -keyint_min 60 -hls_time 4 -hls_playlist_type vod -vf scale=w=842:h=480:force_original_aspect_ratio=decrease -b:v 1400k -maxrate 1498k -bufsize 2100k -b:a 128k -hls_segment_filename vid/480p_%03d.ts vid/480p.m3u8 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 60 -keyint_min 60 -hls_time 4 -hls_playlist_type vod -vf scale=w=1280:h=720:force_original_aspect_ratio=decrease -b:v 2800k -maxrate 2996k -bufsize 4200k -b:a 128k -hls_segment_filename vid/720p_%03d.ts vid/720p.m3u8 -c:a aac -ar 48000 -c:v h264 -profile:v main -crf 20 -sc_threshold 0 -g 60 -keyint_min 60 -hls_time 4 -hls_playlist_type vod -vf scale=w=1920:h=1080:force_original_aspect_ratio=decrease -b:v 5000k -maxrate 5350k -bufsize 7500k -b:a 192k -hls_segment_filename vid/1080p_%03d.ts vid/1080p.m3u8 Unrecognized option 'hls_playlist_type'. Error splitting the argument list: Option not found

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.