Open Thiagobhmg opened 4 years ago
I managed to run a batch to generate the .m3u8 file, you could add the conversion to this format in the list too, with more options.
"F:\convertvideos\Axiom.FFmpeg\ffmpeg\bin\ffmpeg.exe"
-i "F:\test\test.mp4"
-profile:v baseline -level 3.0 -s 1920x1080 -start_number 0 -hls_time 10 -hls_list_size 0
-f hls index.m3u8
I return to congratulate the work that is being developed in this program. I think they should really think about adding the output in HLS (m3u8). In none of the other systems there is the possibility of making this conversion. I managed to adapt the script but it would be great to have this option to select.
@Thiagobhmg
I will take a look at adding it.
What is the conversion doing? It converts the .mp4
to a .ts
file and creates an .m3u8
playlist for it?
Do you have more information on these 3 options?:
I am testing various combinations. I will try to describe what each thing in HLS does as I understand it.
The best combination so far has been this one. Because it ran with the CUDA of the video card (I was very happy with the possibility) because it improved the conversion speed of the files by 6x. I didn't understand why you don't use all the processing power of the board, is it possible to configure this?
"F:\convertvideos\Axiom.FFmpeg\ffmpeg\bin\ffmpeg.exe"
-y
-hwaccel cuda
-i "F:\test\test.mp4"
-vf scale=w=1280:h=720:force_original_aspect_ratio=decrease
-c:a aac
-ar 44100
-b:a 128k
-c:v h264_nvenc
-profile:v main
-crf 20
-g 48
-keyint_min 48
-sc_threshold 0
-b:v 2500k
-maxrate 2675k
-bufsize 3750k
-hls_time 4
-hls_playlist_type vod
-hls_segment_filename test/720p_%03d.ts test/720p.m3u8
-hls_time
is every few seconds the file will be broken into .TS the default is 2 seconds, but it can be configured as the person wants. As I understand it when advancing through the time line he always starts the video .Ts closest to where he clicked on the player's timeline.
-hls_segment_filename
is how it saves the name of the .Ts segments and the .m3u8 file (which generates the playlist with the .Ts segments)
The ideal here would be to be able to configure variables such as output-directory / date-time-name-of-the-original-file.
-vf scale
Here is for the person to scale the video. I found it best to use in this configuration. But people should be able to choose the format they want.
Resolution Playlist
Another thing that would be important to implement is the generation of one of the playlist for loading the video in the player according to the desired resolutions of the video.
For example: 360p, 540p, 720p or 1080p.
I found this script that can help: would it be possible to run this script on Windows?
Sorry for the questions, I'm not a developer. I understand only the basics of programming.
I found this script that can help:
would it be possible to run this script on Windows?
Sorry for the questions, I'm not a developer. I understand only the basics of programming.
Developed by @mrbar42
File to be converted to HLS
bash create-vod-hls.sh beach.mkv
#!/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}/"
-vf "scale=w=1280:h=720:force_original_aspect_ratio=decrease" - scale video to maximum possible within 1280x720 while preserving aspect ratio
-c:a aac -ar 48000 -b:a 128k - set audio codec to AAC with sampling of 48kHz and bitrate of 128k
-c:v h264 - set video codec to be H264 which is the standard codec of HLS segments
-profile:v main - set H264 profile to main - this means support in modern devices read more
-crf 20 - Constant Rate Factor, high level factor for overall quality
-g 48 -keyint_min 48 - IMPORTANT create key frame (I-frame) every 48 frames (~2 seconds) - will later affect correct slicing of segments and alignment of renditions
-sc_threshold 0 - don't create key frames on scene change - only according to -g
-b:v 2500k -maxrate 2675k -bufsize 3750k - limit video bitrate, these are rendition specific and depends on your content type - read more
-hls_time 4 - segment target duration in seconds - the actual length is constrained by key frames
-hls_playlist_type vod - adds the #EXT-X-PLAYLIST-TYPE:VOD tag and keeps all segments in the playlist
-hls_segmentfilename test/720p%03d.ts - explicitly define segments files names test/720p.m3u8 - path of the playlist file - also tells ffmpeg to output HLS (.m3u8)
@Thiagobhmg
I will look over all this soon, I had to spend a few days finishing another feature.
updating the conversion script I was able to use.
With this script the youtube video will be downloaded, converted to .mkv and then the file in m3u8 will be converted to VOD, generating the Playlist.
cd /d "F:\test\"
&&
for /f "delims=" %f in ('
@"F:\Axiom.FFmpeg\youtube-dl\youtube-dl.exe"
--get-filename -o "%(title)s" "https://www.youtube.com/watch?v=Cr8GwDXuOLg"
')
do (
@"F:\Axiom.FFmpeg\youtube-dl\youtube-dl.exe"
-f bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best
"https://www.youtube.com/watch?v=Cr8GwDXuOLg"
-o "F:\test\%f.mkv"
--ffmpeg-location "F:\Axiom.FFmpeg\ffmpeg\bin\ffmpeg.exe"
--merge-output-format mkv
&&
"F:\Axiom.FFmpeg\ffmpeg\bin\ffmpeg.exe"
-y
-hwaccel cuda
-i "F:\test\%f.mkv"
-vf scale=w=1280:h=720:force_original_aspect_ratio=decrease
-pix_fmt nv21
-preset slow
-g 48
-sc_threshold 0
-map 0:0 -map 0:1 -map 0:0 -map 0:1
-s:v:0 640x360 -c:v:0 libx264 -b:v:0 365k
-s:v:1 960x540 -c:v:1 libx264 -b:v:1 2000k
-c:v h264_nvenc
-var_stream_map "v:0,a:0 v:1,a:1"
-master_pl_name master.m3u8
-f hls -hls_time 2 -hls_list_size 0
-hls_segment_filename "v%v/fileSequence%d.ts"
v%v/prog_index.m3u8
&&
del "F:\test\%f.mkv"
)
It would be great to be able to output files in HLS. It would be possible? Could anyone help?