Skip to content

Instantly share code, notes, and snippets.

@visualblind
Last active April 29, 2024 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save visualblind/c7816cabd1cb0a7eb600f91401037467 to your computer and use it in GitHub Desktop.
Save visualblind/c7816cabd1cb0a7eb600f91401037467 to your computer and use it in GitHub Desktop.
FFmpeg CLI Examples with Comments (transcoding, remuxing, metadata stuff, thumbnail generation, nvidia hw-accel cuda h264_nvenc, bash looping, etc)
############################ FFmpeg CLI Examples ############################
-metadata[:metadata_specifier] key=value (output,per-metadata)
For example, for setting the title in the output file:
ffmpeg -i in.avi -metadata title="my title" out.flv
To set the language of the first audio stream:
ffmpeg -i INPUT -metadata:s:a:0 language=eng OUTPUT
-disposition[:stream_specifier] value (output,per-stream)
For example, to make the second audio stream the default stream:
ffmpeg -i in.mkv -c copy -disposition:a:1 default out.mkv
To make the second subtitle stream the default stream and remove the default disposition from the first subtitle stream:
ffmpeg -i in.mkv -c copy -default_mode infer_no_subs -disposition:s:0 0 -disposition:s:1 default out.mkv
"-preset" provides the compression to encoding speed ratio. Use the slowest preset you can.
"-bufsize" sets the buffer size, and can be 1-2 seconds for most gaming screencasts, and up to 5 seconds for more static content.
If you use "-maxrate" 960k then use a "-bufsize" of 960k-1920k. You will have to experiment to see what looks best for your content.
"-g" Use a 2 second GOP (Group of Pictures), so simply multiply your output frame rate * 2.
For example, if your input is -framerate 30, then use -g 60
"-crf 0", short for “constant rate factor,” is used to tell the libx264 encoder to use “lossless mode.”
See https://esoterictek.blogspot.com/2017/04/understanding-ffmpegs-group-of-pictures.html.
The film industry generally chooses 24 FPS in film capturing and production.
############################ FFmpeg real-world examples ############################
#for i in *.flv; do ffmpeg -i "$i" -movflags faststart -c:a aac -c:v libx264 -b:a 128k "${i%.flv}.mp4"; done
for f in $(find . -type f -name '*265.mkv'); do ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s:0 -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 23 "${f/%265.mkv/264.mkv}"; done
for f in $(find . -type f -name '*265.mkv' -print); do ffmpeg -i "${f}" -map 0:v:0 -map 0:a:0 -map 0:s? -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 21 "./working/${f/265/264}"; done
for f in *.mp4; do ffmpeg -i "$f" -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 23 "${f/(x265)/(x264)}"; done
for f in *.mp4; do ffmpeg -i "$f" -map 0:v -map 0:a -map 0:s -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 23 "${f/(x265)/(x264)}"; done
for f in *.mkv; do ffmpeg -i "$f" -map 0 -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 23 "${f/x265/x264}"; done
for f in *.mkv; do ffmpeg -i "$f" -map 0 -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 23 "${f/.mkv/.x264.mkv}"; done
##### Strip all subtitle streams from input file:
for f in *.mkv; do ffmpeg -i "$f" -map 0:v -map 0:a -c:v copy -c:a copy ./working/"${f/.mkv/.x264.mkv}"; done
##### Convert audio stream to AAC and insert subtitles stream from external srt file:
for f in *.mkv; do ffmpeg -i "$f" -f srt -i "${f/.mkv/.srt}" -map 0:v -map 0:a -map 1:0 -c:v copy -c:a aac -c:s srt ./working/"${f/.mkv/.x264.mkv}"; done
for f in *.mkv; do ffmpeg -i "$f" -f srt -i "${f/.en.mkv/.srt}" -map 0:v -map 0:a -map 1:0 -c:v copy -c:a aac -c:s srt ./working/"${f/.mkv/.x264.mkv}"; done
for f in *.mkv; do ffmpeg -i "$f" -f srt -i "${f/.en.mkv/.srt}" -map 0:0 -map 0:1 -map 1:0 -c:v copy -c:a aac -c:s srt ./working/"${f/.mkv/.x264.mkv}"; done
##### Convert 10/8bit HEVC/H.265 to 8bit AVC/H.264 MKV high profile slow preset, insert external SRT subtitle file and not-DEFAULT with eng lang
for f in *.mkv; do ffmpeg -y -i "$f" -f srt -i "${f/mkv/srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -movflags faststart -profile:v high -pix_fmt yuv420p -preset slow -disposition:s:0 0 -metadata:s:s:0 language=eng -codec:v libx264 -codec:a copy -codec:s srt "../.working/${f/find/replace}"; done
##### Convert 10/8bit HEVC/H.265 to 8bit AVC/H.264 MKV high profile slow preset, stream-copy original subtitles (if present) and DEFAULT with eng lang
for f in *.mkv; do ffmpeg -y -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -movflags faststart -profile:v high -pix_fmt yuv420p -preset slow -disposition:s:0 default -metadata:s:s:0 language=eng -codec:v libx264 -codec:a copy -codec:s copy "../.working/${f/find/replace}"; done
##### One off:
ffmpeg -i 'The.Big.Bang.Theory.S05E01.720p.HDTV.mkv' -f srt -i 'The.Big.Bang.Theory.S05E01.720p.HDTV.srt' -map 0:v -map 0:a -map 1:0 -c:v copy -c:a aac -c:s srt './working/The.Big.Bang.Theory.S05E01.720p.HDTV.mkv'
##### Convert audio stream to AAC and do not add subtitles:
for f in *.mkv; do ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -c:v copy -c:a aac ./working/"${f/.old.ext/.new.mkv}"; done
# or
for f in *.mkv; do ffmpeg -i "$f" -map 0:v -map 0:a:0 -c:v copy -c:a aac ./working/"${f/.old.ext/.new.mkv}"; done
ffmpeg -i 'Ip Man (2008) - 1080p H265.mkv' -map 0:v -map 0:a -map 0:s -movflags faststart -c:v libx264 -crf 23 -c:a aac -af "volume=10dB" -c:s srt 'Ip Man (2008) - 1080p x264.mkv'
##### Rearrange audio streams, English audio stream default, Spanish secondary
ffmpeg -i file1.mkv -map 0:v -map 0:a:1 -map 0:a:0 -map 0:s -map_chapters -1 -dn -metadata:s:a:1 language=spa -metadata:s:a:1 title= -metadata:s:s:0 title=English -metadata:s:s:4 title=Spanish -disposition:s 0 -disposition:a 0 -disposition:a:0 default -codec copy file1_2.mkv
########### ###########
########### NVIDIA HARDWARE ACCELERATED TRANSCODING H.265 > H.264 ###########
########### ###########
#Resources:
https://docs.nvidia.com/video-technologies/video-codec-sdk/ffmpeg-with-nvidia-gpu/
https://trac.ffmpeg.org/wiki/HWAccelIntro#CUDANVENCNVDEC
https://developer.nvidia.com/nvidia-video-codec-sdk
#use -vsync 0 option with decode to prevent FFmpeg from creating output YUV with duplicate and extra frames.
ffmpeg -vsync 0 -hwaccel nvdec -i <in file> -c:v h264_nvenc -c:a copy <out file>
ffmpeg -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i <in file> -c:v h264_nvenc -c:a copy <out file>
ffmpeg -vsync 0 -hwaccel cuda -i <in file> -c:v h264_nvenc -c:a copy <out file>
#this one outputs data into special cuda format
ffmpeg -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i <in file> -map 0 -preset slow -c:v h264_nvenc -c:a copy <out file>
### DECODE from .mp4 to .yuv
#The FFmpeg video decoder is straightforward to use. To decode an input bitstream from input.mp4, use the following command.
#This generates the output file in NV12 format (output.yuv).
ffmpeg -y -vsync 0 -c:v h264_cuvid -i input.mp4 output.yuv
ffmpeg -vsync 0 -hwaccel nvdec -y -i "input.mkv" -f srt -i "subtitle.srt" -default_mode infer_no_subs -map 0:v -map 0:a:2 -map 0:a:4 -map 0:a:5 -map 0:a:6 -map 0:a:0 -map 0:a:1 -map 0:a:3 -map 1:0 -profile:v high -pix_fmt yuv420p -preset slow -disposition:a:0 default -disposition:v:0 default -metadata:s:s:0 language=eng -dn -map_chapters -1 -c:v h264_nvenc -c:a copy -c:s srt "output.mkv"
ffmpeg -vsync 0 -hwaccel cuda -y -i "input.mkv" -f srt -i "subtitle.srt" -default_mode infer_no_subs -map 0:v -map 0:a:2 -map 0:a:4 -map 0:a:5 -map 0:a:6 -map 0:a:0 -map 0:a:1 -map 0:a:3 -map 1:0 -profile:v high -pix_fmt yuv420p -preset slow -disposition:a:0 default -disposition:v:0 default -metadata:s:s:0 language=eng -dn -map_chapters -1 -c:v h264_nvenc -c:a copy -c:s srt "output.mkv"
#Command Line for Latency-Tolerant High-Quality Transcoding
1. Slow preset
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:a copy -c:v h264_nvenc -preset p6 -tune hq -b:v 5M -bufsize 5M -maxrate 10M -qmin 0 -g 250 -bf 3 -b_ref_mode middle -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 output.mp4
2. Medium preset
Use -preset p4 instead of -preset p6 in the above command line.
3. Fast preset
Use -preset p2 instead of -preset p6 in the above command line.
#Command Line for Low Latency Transcoding
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:a copy -c:v h264_nvenc -preset p6 -tune ll -b:v 5M -bufsize 5M -maxrate 10M -qmin 0 -g 250 -bf 3 -b_ref_mode middle -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 output.mp4
#NVIDIA hardware accelerated convert H.265 > H.264
find . -mount -depth -maxdepth 1 -name '*.mkv' -type f -exec bash -c 'ffmpeg -y -loglevel verbose -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i "$0" -f srt -i "${0/.mkv/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -movflags faststart -c:v h264_nvenc -preset slow -metadata:s:a:0 language=eng -c:a copy -metadata:s:s:0 language=eng -disposition:s:0 default -c:s:0 srt "./working/${0/x265/x264}"' {} \;
ffmpeg -hwaccel nvdec -i "$f" -movflags faststart -c:v h264_nvenc -c:a copy -c:s copy -crf 23 "${f/(265)/(264)}"
1:1 HWACCEL Transcode without Scaling
The following command reads file input.mp4 and transcodes it to output.mp4 with H.264 video at the same resolution and with the same audio codec.
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
1:1 HWACCEL Transcode with Scaling
The following command reads file input.mp4 and transcodes it to output.mp4 with H.264 video at 720p resolution and with the same audio codec. The following command uses the built in resizer in cuvid decoder.
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda –resize 1280x720 -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
There is a built-in cropper in cuvid decoder as well. The following command illustrates the use of cropping. (-crop (top)x(bottom)x(left)x(right))
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda –crop 16x16x32x32 -i input.mp4 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
Alternately scale_cuda or scale_npp resize filters could be used as shown below
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -vf scale_cuda=1280:720 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i input.mp4 -vf scale_npp=1280:720 -c:a copy -c:v h264_nvenc -b:v 5M output.mp4
#Use -vsync 0 option with decode to prevent FFmpeg from creating output YUV with duplicate and extra frames.
ffmpeg -vsync 0 -hwaccel nvdec -i <in file> -map 0 -preset slow -metadata:s:a:0 language=eng -c:v h264_nvenc -c:a copy <out file>
ffmpeg -vsync 0 -hwaccel cuda -i <in file> -map 0 -preset slow -metadata:s:a:0 language=eng -c:v h264_nvenc -c:a copy <out file>
#This one outputs data into special cuda format
ffmpeg -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i <in file> -map 0 -preset slow -metadata:s:a:0 language=eng -c:v h264_nvenc -c:a copy <out file>
ffmpeg -vsync 0 -hwaccel nvdec -y -i <in file> -f srt -i <subtitle.srt> -default_mode infer_no_subs -map 0:v -map 0:a:2 -map 0:a:4 -map 0:a:5 -map 0:a:6 -map 0:a:0 -map 0:a:1 -map 0:a:3 -map 1:0 -profile:v high -pix_fmt yuv420p -preset slow -disposition:a:0 default -disposition:v:0 default -metadata:s:s:0 language=eng -dn -map_chapters -1 -c:v h264_nvenc -c:a copy -c:s srt <out file>
#!!!!! Cuvid is DEPRECATED
ffmpeg -vsync 0 -hwaccel cuvid -y -i <in file> -f srt -i <subtitle.srt> -default_mode infer_no_subs -map 0:v -map 0:a:2 -map 0:a:4 -map 0:a:5 -map 0:a:6 -map 0:a:0 -map 0:a:1 -map 0:a:3 -map 1:0 -profile:v high -pix_fmt yuv420p -preset slow -disposition:a:0 default -disposition:v:0 default -metadata:s:s:0 language=eng -dn -map_chapters -1 -c:v h264_cuvid -c:a copy -c:s srt <out file>
#Command Line for Latency-Tolerant High-Quality Transcoding
1. Slow preset
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i <in file> -c:a copy -c:v h264_nvenc -preset p6 -tune hq -b:v 5M -bufsize 5M -maxrate 10M -qmin 0 -g 250 -bf 3 -b_ref_mode middle -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 <out file>
2. Medium preset
Use -preset p4 instead of -preset p6 in the above command line.
3. Fast preset
Use -preset p2 instead of -preset p6 in the above command line.
#Command Line for Low Latency Transcoding
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i <in file> -c:a copy -c:v h264_nvenc -preset p6 -tune ll -b:v 5M -bufsize 5M -maxrate 10M -qmin 0 -g 250 -bf 3 -b_ref_mode middle -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 <out file>
ffmpeg -y -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i "Formula1 2021 - Round 03 - Portugal Race (1080p SkyF1HD HEVC AAC x265).mkv" -c:a copy -c:v h264_nvenc -preset p6 -tune hq -b:v 5M -bufsize 5M -maxrate 10M -extra_hw_frames 2 -qmin 0 -g 250 -bf 3 -b_ref_mode middle -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 "Formula1 2021 - Round 03 - Portugal Race (1080p SkyF1HD AVC x264).mkv"
#works
ffmpeg -y -vsync 0 -hwaccel cuda -i "Formula1 2021 - Round 03 - Portugal Race (1080p SkyF1HD HEVC AAC x265).mkv" -c:a copy -c:v h264_nvenc "Formula1 2021 - Round 03 - Portugal Race (1080p SkyF1HD AVC x264).mkv"
ffmpeg -y -vsync 0 -hwaccel cuda -i "Formula1 2021 - Round 03 - Portugal Race (1080p SkyF1HD HEVC AAC x265).mkv" -c:a copy -c:v h264_nvenc -preset p6 -tune hq -b:v 5M -bufsize 5M -maxrate 10M -extra_hw_frames 2 -qmin 0 -g 250 -bf 3 -b_ref_mode middle -temporal-aq 1 -rc-lookahead 20 -i_qfactor 0.75 -b_qfactor 1.1 "Formula1 2021 - Round 03 - Portugal Race (1080p SkyF1HD AVC x264)_2.mkv"
# Nvidia HW accelerated H264 10-bit to 8-bit BT709 color
for f in *.mkv; do /usr/bin/ffmpeg-424 -vsync 0 -hwaccel cuda -y -i "$f" -map 0:v:0 -map 0:a -map "0:s?" -dn -map_chapters -1 -profile:v high -pix_fmt yuv420p -preset slow -vf "colorspace=all=bt709:iall=bt601-6-625:fast=1" -colorspace 1 -color_primaries 1 -color_trc 1 -metadata:s:a:0 title= -disposition:s 0 -codec:v h264_nvenc -codec:a copy -codec:s copy "/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working/${f}"; done
for f in *.mkv; do /usr/bin/ffmpeg-424 -vsync 0 -hwaccel cuda -y -i "$f" -map 0:v:0 -map 0:a:0 -map 0:a:0 -map "0:s:m:language:eng?" -dn -map_chapters -1 -profile:v high -pix_fmt yuv420p -preset slow -vf "colorspace=all=bt709:iall=bt601-6-625:fast=1" -colorspace 1 -color_primaries 1 -color_trc 1 -metadata:s:a:0 title="AAC / 5.1 / 224k / 48000 Hz" -metadata:s:a:1 title="Dolby Digital (AC3) / 5.1 / 224k / 48000 Hz" -metadata:s:s title= -disposition:a:0 default -disposition:a:1 0 -disposition:s 0 -channel_layout:a:0 "5.1" -ac:0 6 -b:a:0 224k -c:v h264_nvenc -c:a:0 aac -c:a:1 copy -c:s copy "/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working/${f}"; done
# Nvidia HW Accelerated H.264 interlaced BT709 > H.264 progressive BT709
ffmpeg -vsync 0 -hwaccel cuda -y -i "BBC.Van.Gogh.Painted.With.Words.1080i.HDTV.MVGroup.mkv" -default_mode infer_no_subs -map 0 -map_chapters -1 -dn -metadata title="BBC.Van.Gogh.Painted.With.Words.1080p.AAC.H264.mkv" -metadata:s:v:0 title= -metadata:s:a:0 title= -vf "yadif=0, colorspace=all=bt709:iall=bt601-6-625:fast=1" -colorspace 1 -color_primaries 1 -color_trc 1 -b:v 6M -bufsize 6M -minrate 3M -maxrate 10M -profile:v high -pix_fmt yuv420p -preset slow -channel_layout "5.1" -strict experimental -max_muxing_queue_size 400 -c:v h264_nvenc -c:a aac -c:s copy "BBC.Van.Gogh.Painted.With.Words.1080p.AAC.H264.mkv"
# For looped Nvidia HW-accelerated h264_nvenc PAL bt601/bt470bg > NTSC transcoding:
# verbose for loop:
for VAR in 01 02 03 04 05 06 07 08 09 10 11 12 13; do ffmpeg -vsync 0 -hwaccel cuda -y -i /media/visualblind/ISOIMAGE/"VTS_$(echo $VAR)_1.VOB" -movflags faststart -map 0:v:0 -map 0:a:0 -dn -map_chapters -1 -profile:v high -pix_fmt yuv420p -preset slow -x264-params "iall=bt601-6-625:fast=1" -color_range 1 -colorspace bt470bg -color_primaries bt470bg -color_trc gamma28 -metadata title="Rainbow Brite (1984) S01E$(echo $VAR)" -metadata:s:a:0 title= -metadata:s:a:0 language=eng -disposition:s 0 -b:v 2500k -minrate 1000k -maxrate 2500k -b:a 128k -codec:v h264_nvenc -channel_layout:a:0 "stereo" -codec:a aac "/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working/Rainbow Brite 1984 - S01E$VAR.mp4"; done
# less-verbose for loop:
for VAR in {01..13}; do ffmpeg -vsync 0 -hwaccel cuda -y -i /media/ISOIMAGE/"VTS_$(echo $VAR)_1.VOB" -movflags faststart -map 0:v:0 -map 0:a:0 -dn -map_chapters -1 -profile:v high -pix_fmt yuv420p -preset slow -x264-params "iall=bt601-6-625:fast=1" -color_range 1 -colorspace bt470bg -color_primaries bt470bg -color_trc gamma28 -metadata title="Rainbow Brite (1984) S01E$(echo $VAR)" -metadata:s:a:0 title= -metadata:s:a:0 language=eng -disposition:s 0 -b:v 2500k -minrate 1000k -maxrate 2500k -b:a 128k -codec:v h264_nvenc -channel_layout:a:0 "stereo" -codec:a aac "/tmp/ffmpeg-vcodec/.working/Rainbow Brite 1984 - S01E$VAR.mp4"; done
# For looped ffmpeg NVIDIA HW-Accelerated h264_nvenc PAL bt601/bt470bg > NTSC transcoding
for VAR in {01..13}; do ffmpeg -vsync 0 -hwaccel cuda -y -i \
/media/ISOIMAGE/"VTS_$(echo $VAR)_1.VOB" -movflags faststart \
-map 0:v:0 -map 0:a:0 -dn -map_chapters -1 -profile:v high \
-pix_fmt yuv420p -preset slow -x264-params "iall=bt601-6-625:fast=1" \
-color_range 1 -colorspace bt470bg -color_primaries bt470bg -color_trc gamma28 \
-metadata title="Rainbow Brite (1984) S01E$(echo $VAR)" -metadata:s:a:0 title= \
-metadata:s:a:0 language=eng -disposition:s 0 \
-b:v 2500k -minrate 1000k -maxrate 2500k -b:a 128k \
-codec:v h264_nvenc -channel_layout:a:0 "stereo" -codec:a aac \
"/tmp/ffmpeg-vcodec/.working/Rainbow Brite 1984 - S01E$VAR.mp4"; done
# another variation for different media:
for VAR in {01..10}; do ffmpeg -y -i /tmp/ffmpeg-vcodec/Mayor.Of.Kingstown.S01E01-10.DLMux.1080p.E-AC3-AC3.ITA.ENG.SUBS/"Mayor of Kingstown S01E$(echo $VAR)"*".mkv" -default_mode infer_no_subs -map 0:v:0 -map 0:a:2 -map "0:s:1?" -dn -map_chapters -1 -metadata title="Mayor of Kingstown S01E$(echo $VAR)" -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata:s:a:0 language=eng -c:v copy -channel_layout "5.1" -disposition:a:0 default -c:a aac -c:s copy "/tmp/ffmpeg-vcodec/.working/Mayor of Kingstown - S01E$VAR.mkv"; done
# one-liner: Constant frame-rate with variable bitrate (VBR) nvidia hw-accel transcoding
for f in *.mkv; do ffmpeg -vsync 2 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs -map 0 -map_chapters -1 -dn -metadata title="${f/.mkv/}" -metadata:s:v:0 title= -metadata:s:a:0 title= -colorspace 1 -color_primaries 1 -color_trc 1 -r 24 -b:v 5M -minrate 3M -maxrate 8M -bufsize 10M -profile:v high -pix_fmt yuv420p -preset slow -strict experimental -max_muxing_queue_size 400 -c:v h264_nvenc -c:a copy -c:s copy "/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working/$f"; done
# multi-lined: Constant frame-rate with variable bitrate (VBR) nvidia hw-accel transcoding
for f in *.mkv; do ffmpeg -vsync 2 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs \
-map 0 -map_chapters -1 -dn -metadata title="${f/.mkv/}" -metadata:s:v:0 title= \
-metadata:s:a:0 title= -colorspace 1 -color_primaries 1 -color_trc 1 -r 24 \
-b:v 5M -minrate 3M -maxrate 8M -bufsize 10M -profile:v high -pix_fmt yuv420p -preset slow \
-strict experimental -max_muxing_queue_size 400 -c:v h264_nvenc -c:a copy -c:s copy \
"/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working/$f"; done
########### ###########
########### NVIDIA END ###########
########### ###########
#?????????? ???????????
#?????????? VFR (variable frame-rate) ???????????
#?????????? ???????????
Frustrated that you hadnt found an answer either, I was going to at least answer other peoples questions about how to enable VFR (not VBR) output from FFMPEG.
The answer to that is the oddly named -vsync option. You can set it to a few different options, but the one you want is "2" or vfr. From the man page:
-vsync parameter
Video sync method. For compatibility reasons old values can be specified as numbers. Newly added values will have to be specified as strings always.
0, passthrough
Each frame is passed with its timestamp from the demuxer to the muxer.
1, cfr
Frames will be duplicated and dropped to achieve exactly the requested constant frame rate.
2, vfr
Frames are passed through with their timestamp or dropped so as to prevent 2 frames from having the same timestamp.
drop
As passthrough but destroys all timestamps, making the muxer generate fresh timestamps based on frame-rate.
-1, auto
Chooses between 1 and 2 depending on muxer capabilities. This is the default method.
Note that the timestamps may be further modified by the muxer, after this. For example, in the case that the format option avoid_negative_ts is enabled.
With -map you can select from which stream the timestamps should be taken. You can leave either video or audio unchanged and sync the remaining stream(s) to the unchanged one.
However, I dont quite have enough reputation to post a comment to just answer that "sub-question" that everyone seems to be having. But I did have a few ideas that I wasnt honestly very optimistic about... But the first one I tried actually worked. So.
You simply need to combine the -vsync 2 option with the -r $maxfps option, of course where you replace $maxfps with the maximum framerate you want! And it WORKS! It doesnt duplicate frames from a source file, but it will drop frames that cause the file to go over the maximum framerate!
By default it seems that -r $maxfps by itself just causes it to duplicate/drop frames to achieve a constant framerate, and -vsync 2 by itself causes it to pull the frames in directly without really affecting the PTS values.
I wasnt optimistic about this because I already knew that -r $maxfps puts it at a constant framerate. I honestly expected an error or for it to just obey whichever came first or last or whatever. The fact that it does exactly what I wanted makes me quite pleased with the FFMPEG developers.
# INTERNAL MEDIA TERMINOLOGIES:
CFR = Constant Frame Rate
VFR = Variable Frame Rate
CBR = Constant Bit Rate
VBR = Variable Bit Rate
#?????????? ???????????
#?????????? VFR END ???????????
#?????????? ???????????
# Generate thumbnails from video
# Adjust the fps interval to change the number of thumbnails generated
ffmpeg -loglevel verbose -i 'input.mp4' -vf "fps=1/1000" thumb-%02d.jpg
# vsync 1 CFR, cq = 30, avi > mp4
for f in *.avi; do ffmpeg -loglevel verbose -vsync 1 -hwaccel cuda -y -i "$f" -f srt -i "${f/avi/srt}" -map 0:v:0 -map 0:a -map 1:0 -dn -map_chapters -1 -movflags faststart -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -metadata:s:a:0 language=eng -metadata:s:s:0 title= -metadata:s:s:0 language=eng -pix_fmt yuv420p -disposition:s:0 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 30 -level:v 4.1 -rc vbr -cbr:v false -channel_layout "stereo" -c:a aac -c:s mov_text .working/"${f/.avi/.mp4}"; done
# vsync 2 VFR, cq = 28, avi > mp4
for f in *.avi; do ffmpeg -loglevel verbose -vsync 2 -hwaccel cuda -y -i "$f" -f srt -i "${f/avi/srt}" -map 0:v:0 -map 0:a -map 1:0 -dn -map_chapters -1 -movflags faststart -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -metadata:s:a:0 language=eng -metadata:s:s:0 title= -metadata:s:s:0 language=eng -pix_fmt yuv420p -disposition:s:0 0 -r 24 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 28 -level:v 4.1 -rc vbr -cbr:v false -channel_layout "stereo" -c:a aac -c:s mov_text .working/"${f/.avi/.mp4}"; done
# vsync 1 CFR, cq = 30, mp4 > mp4
for f in *.mp4; do ffmpeg -loglevel verbose -vsync 1 -hwaccel cuda -y -i "$f" -f srt -i "${f/avi/srt}" -map 0:v:0 -map 0:a -map 1:0 -dn -map_chapters -1 -movflags faststart -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -metadata:s:a:0 language=eng -metadata:s:s:0 title= -metadata:s:s:0 language=eng -pix_fmt yuv420p -disposition:s:0 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 30 -level:v 4.1 -rc vbr -cbr:v false -channel_layout "stereo" -c:a aac -c:s mov_text .working/"${f/.avi/.mp4}"; done
# vsync 1 CFR of 24fps (-r 24), cq = 28
for f in *.mkv; do ffmpeg -loglevel verbose -vsync 1 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a -map "0:s?" -dn -map_chapters -1 -r 24 -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -pix_fmt yuv420p -disposition:s:0 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 28 -level:v 4.1 -rc vbr -cbr:v false -c:a copy -c:s copy /media/visualblind/p1ds0smb/temp/ffmpeg-vcodec/.working/"$f"; done
# vsync 1 CFR, cq = 28, variable bit rate, keep existing frame rate
for f in *.mkv; do ffmpeg -loglevel info -vsync 1 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a -map "0:s?" -dn -map_chapters -1 -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -pix_fmt yuv420p -disposition:s:0 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 28 -level:v 4.1 -rc vbr -cbr:v false -channel_layout "5.1" -c:a aac -c:s copy .working/"${f/x264/AAC51.x264}"; done
# vsync 1 CFR, cq = 23, variable bit rate, keep existing frame rate
for f in *.mkv; do ffmpeg -loglevel info -vsync 1 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a -map "0:s?" -dn -map_chapters -1 -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -pix_fmt yuv420p -disposition:s:0 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 23 -level:v 4.1 -rc vbr -cbr:v false -channel_layout "5.1" -c:a aac -c:s copy .working/"${f/x264/AAC51.x264}"; done
# stream copy/remux, not changing much except for subtitle deposition and other minor changes
for f in *.mkv; do ffmpeg -y -i "$f" -default_mode infer_no_subs -map 0 -dn -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -disposition:v:0 default -disposition:a:0 default -disposition:s 0 -c:v copy -c:a copy -c:s copy /media/visualblind/p1ds0smb/temp/ffmpeg-vcodec/.working/"$f"; done
# avi > mp4 transcoding, constant frame rate at 24fps, variable bit rate, cq 28
for f in */**.avi; do ffmpeg -loglevel verbose -vsync 1 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a -map "0:s?" -movflags faststart -dn -map_chapters -1 -r 24 -metadata title= -metadata:s:v:0 title= -metadata:s:a:0 title= -metadata:s:a:0 language=eng -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -pix_fmt yuv420p -disposition:s:0 0 -disposition:v:0 default -disposition:a:0 default -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 28 -level:v 4.1 -rc vbr -cbr:v false -channel_layout:a:0 "stereo" -c:a aac -c:s srt /media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working/"${f/avi/mp4}"; done
# With mp4 containers you are required to pay attention to which metadata fields are allowed.
# You cannot create your own metadata fields willie nillie as you can with mkv containers.
# It is safe to stick with the "title" and "comment" fields like so.
# Refer to this page for mp4 metadata field references: https://kdenlive.org/en/project/adding-meta-data-to-mp4-video/
for f in *.avi; do ffmpeg -loglevel info -vsync 1 -hwaccel cuda -y -i "$f" -map 0:v:0 -map 0:a:0 -map "0:s?" -movflags faststart -dn -metadata title= -metadata:s:a:0 title= -metadata:s:s:0 title= -metadata:s:a:0 language=eng -metadata "comment"="cfr vbr vsync 1 cq 30 preset p5 transcoder visualblind" -metadata:s:a:0 title= -metadata:s:a:0 language=eng -disposition:a:0 default -disposition:v:0 default -disposition:s:0 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 30 -level:v 4.1 -rc vbr -cbr:v false -channel_layout "stereo" -c:a aac ../.working/"${f/DVDRip.XviD-aAF.avi/480p.AAC.H264.mp4}"; done
# Same as the above but with mkv containers instead
# with the addition of creation_time, ffmpeg_params, and ffmpeg_transcoder metadata fields
for f in *.mkv; do ffmpeg -loglevel info -vsync 1 -hwaccel cuda -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a:0 -map "0:s?" -dn -map_chapters -1 -metadata title= -metadata creation_time="$(date --iso-8601=seconds)" -metadata:s:v creation_time="$(date --iso-8601=seconds)" -metadata:s:a creation_time="$(date --iso-8601=seconds)" -metadata:s:a:0 title= -metadata:s:s:0 title= -metadata:s:a:0 language=eng -metadata:s:v:0 "ffmpeg_params"="cfr vbr vsync 1 cq 23 preset p5" -metadata:s:v:0 "ffmpeg_transcoder"="visualblind" -colorspace 1 -color_primaries 1 -color_trc 1 -pix_fmt yuv420p -disposition:a:0 default -disposition:v:0 default -disposition:s 0 -c:v h264_nvenc -profile:v high -preset p5 -tune hq -b:v 0 -cq 23 -level:v 4.1 -rc vbr -cbr:v false -c:a copy -c:s copy ../.working/"${f/x265/DDP51.H264}"; done
# PROBLEM:
# https://unsplash.com/s/photos/bikini
$ ffmpeg -hide_banner -h encoder=h264_nvenc | xclip -sel clip
Encoder h264_nvenc [NVIDIA NVENC H.264 encoder]:
General capabilities: dr1 delay hardware
Threading capabilities: none
Supported hardware devices: cuda cuda
Supported pixel formats: yuv420p nv12 p010le yuv444p p016le yuv444p16le bgr0 rgb0 cuda
h264_nvenc AVOptions:
-preset <int> E..V....... Set the encoding preset (from 0 to 18) (default p4)
default 0 E..V.......
slow 1 E..V....... hq 2 passes
medium 2 E..V....... hq 1 pass
fast 3 E..V....... hp 1 pass
hp 4 E..V.......
hq 5 E..V.......
bd 6 E..V.......
ll 7 E..V....... low latency
llhq 8 E..V....... low latency hq
llhp 9 E..V....... low latency hp
lossless 10 E..V.......
losslesshp 11 E..V.......
p1 12 E..V....... fastest (lowest quality)
p2 13 E..V....... faster (lower quality)
p3 14 E..V....... fast (low quality)
p4 15 E..V....... medium (default)
p5 16 E..V....... slow (good quality)
p6 17 E..V....... slower (better quality)
p7 18 E..V....... slowest (best quality)
-tune <int> E..V....... Set the encoding tuning info (from 1 to 4) (default hq)
hq 1 E..V....... High quality
ll 2 E..V....... Low latency
ull 3 E..V....... Ultra low latency
lossless 4 E..V....... Lossless
-profile <int> E..V....... Set the encoding profile (from 0 to 3) (default main)
baseline 0 E..V.......
main 1 E..V.......
high 2 E..V.......
high444p 3 E..V.......
-level <int> E..V....... Set the encoding level restriction (from 0 to 62) (default auto)
auto 0 E..V.......
1 10 E..V.......
1.0 10 E..V.......
1b 9 E..V.......
1.0b 9 E..V.......
1.1 11 E..V.......
1.2 12 E..V.......
1.3 13 E..V.......
2 20 E..V.......
2.0 20 E..V.......
2.1 21 E..V.......
2.2 22 E..V.......
3 30 E..V.......
3.0 30 E..V.......
3.1 31 E..V.......
3.2 32 E..V.......
4 40 E..V.......
4.0 40 E..V.......
4.1 41 E..V.......
4.2 42 E..V.......
5 50 E..V.......
5.0 50 E..V.......
5.1 51 E..V.......
5.2 52 E..V.......
6.0 60 E..V.......
6.1 61 E..V.......
6.2 62 E..V.......
-rc <int> E..V....... Override the preset rate-control (from -1 to INT_MAX) (default -1)
constqp 0 E..V....... Constant QP mode
vbr 1 E..V....... Variable bitrate mode
cbr 2 E..V....... Constant bitrate mode
vbr_minqp 8388612 E..V....... Variable bitrate mode with MinQP (deprecated)
ll_2pass_quality 8388616 E..V....... Multi-pass optimized for image quality (deprecated)
ll_2pass_size 8388624 E..V....... Multi-pass optimized for constant frame size (deprecated)
vbr_2pass 8388640 E..V....... Multi-pass variable bitrate mode (deprecated)
cbr_ld_hq 8388616 E..V....... Constant bitrate low delay high quality mode
cbr_hq 8388624 E..V....... Constant bitrate high quality mode
vbr_hq 8388640 E..V....... Variable bitrate high quality mode
-rc-lookahead <int> E..V....... Number of frames to look ahead for rate-control (from 0 to INT_MAX) (default 0)
-surfaces <int> E..V....... Number of concurrent surfaces (from 0 to 64) (default 0)
-cbr <boolean> E..V....... Use cbr encoding mode (default false)
-2pass <boolean> E..V....... Use 2pass encoding mode (default auto)
-gpu <int> E..V....... Selects which NVENC capable GPU to use. First GPU is 0, second is 1, and so on. (from -2 to INT_MAX) (default any)
any -1 E..V....... Pick the first device available
list -2 E..V....... List the available devices
-delay <int> E..V....... Delay frame output by the given amount of frames (from 0 to INT_MAX) (default INT_MAX)
-no-scenecut <boolean> E..V....... When lookahead is enabled, set this to 1 to disable adaptive I-frame insertion at scene cuts (default false)
-forced-idr <boolean> E..V....... If forcing keyframes, force them as IDR frames. (default false)
-b_adapt <boolean> E..V....... When lookahead is enabled, set this to 0 to disable adaptive B-frame decision (default true)
-spatial-aq <boolean> E..V....... set to 1 to enable Spatial AQ (default false)
-spatial_aq <boolean> E..V....... set to 1 to enable Spatial AQ (default false)
-temporal-aq <boolean> E..V....... set to 1 to enable Temporal AQ (default false)
-temporal_aq <boolean> E..V....... set to 1 to enable Temporal AQ (default false)
-zerolatency <boolean> E..V....... Set 1 to indicate zero latency operation (no reordering delay) (default false)
-nonref_p <boolean> E..V....... Set this to 1 to enable automatic insertion of non-reference P-frames (default false)
-strict_gop <boolean> E..V....... Set 1 to minimize GOP-to-GOP rate fluctuations (default false)
-aq-strength <int> E..V....... When Spatial AQ is enabled, this field is used to specify AQ strength. AQ strength scale is from 1 (low) - 15 (aggressive) (from 1 to 15) (default 8)
-cq <float> E..V....... Set target quality level (0 to 51, 0 means automatic) for constant quality mode in VBR rate control (from 0 to 51) (default 0)
-aud <boolean> E..V....... Use access unit delimiters (default false)
-bluray-compat <boolean> E..V....... Bluray compatibility workarounds (default false)
-init_qpP <int> E..V....... Initial QP value for P frame (from -1 to 51) (default -1)
-init_qpB <int> E..V....... Initial QP value for B frame (from -1 to 51) (default -1)
-init_qpI <int> E..V....... Initial QP value for I frame (from -1 to 51) (default -1)
-qp <int> E..V....... Constant quantization parameter rate control method (from -1 to 51) (default -1)
-weighted_pred <int> E..V....... Set 1 to enable weighted prediction (from 0 to 1) (default 0)
-coder <int> E..V....... Coder type (from -1 to 2) (default default)
default -1 E..V.......
auto 0 E..V.......
cabac 1 E..V.......
cavlc 2 E..V.......
ac 1 E..V.......
vlc 2 E..V.......
-b_ref_mode <int> E..V....... Use B frames as references (from 0 to 2) (default disabled)
disabled 0 E..V....... B frames will not be used for reference
each 1 E..V....... Each B frame will be used for reference
middle 2 E..V....... Only (number of B frames)/2 will be used for reference
-a53cc <boolean> E..V....... Use A53 Closed Captions (if available) (default true)
-dpb_size <int> E..V....... Specifies the DPB size used for encoding (0 means automatic) (from 0 to INT_MAX) (default 0)
-multipass <int> E..V....... Set the multipass encoding (from 0 to 2) (default disabled)
disabled 0 E..V....... Single Pass
qres 1 E..V....... Two Pass encoding is enabled where first Pass is quarter resolution
fullres 2 E..V....... Two Pass encoding is enabled where first Pass is full resolution
-ldkfs <int> E..V....... Low delay key frame scale; Specifies the Scene Change frame size increase allowed in case of single frame VBV and CBR (from 0 to 255) (default 0)
# H264 10-bit to 8-bit BT709 color
for f in *.mkv; do ffmpeg -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a -map "0:s?" -dn -map_chapters -1 -profile:v high -pix_fmt yuv420p -preset slow -vf "colorspace=all=bt709:iall=bt601-6-625:fast=1" -colorspace 1 -color_primaries 1 -color_trc 1 -metadata:s:a:0 title= -codec:v libx264 -codec:a copy -codec:s copy "/mnt/p0ds0smb/temp/ffmpeg-vcodec/.working/${f}"; done
##### Convert H.265 > H.264 and convert 6CH AC3 audio to AAC and copy only the first subtitle stream
find . -depth -name '*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s:0? -movflags faststart -c:v libx264 -ac 6 -ar 48000 -b:a 768k -c:a aac -c:s copy -crf 23 "${0/x265/x264}"' {} \;
find . -depth -name '*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s:0? -movflags faststart -c:v libx264 -ac 6 -ar 48000 -b:a 768k -c:a aac -c:s copy -crf 23 "${0/x265/x264}"' {} \;; find . -name '*x265*' -type f -delete
find . -depth -name '*x265*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s:0? -movflags faststart -c:v libx264 -c:a copy -c:s copy -crf 23 "${0/x265/x264}"' {} \;; find . -name '*x265*' -type f -delete
##### Convert H.265 > H.264 and convert 6CH AC3 audio to AAC and copy all subtitle streams
find . -depth -name '*x265*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s? -movflags faststart -c:v libx264 -ac 6 -ar 48000 -b:a 768k -c:a aac -c:s copy -crf 23 "${0/x265/x264}"' {} \;; find . -name '*x265*' -type f -delete
##### Convert H.265 > H.264 and retain original audio and all subtitles:
find . -depth -name '*x265*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s? -movflags faststart -c:v libx264 -preset slow -c:a copy -c:s copy -crf 23 "${0/x265/x264}"' {} \;; find . -name '*x265*' -type f -delete
##### Copy original video stream and convert 6CH AC3 audio to AAC and copy all subtitle streams:
find . -depth -name '*x265*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 384k -c:a aac -c:s copy "${0/x265/x264}"' {} \;; find . -name '*x265*' -type f -delete
##### Copy original video stream and convert 2CH AC3 audio to AAC and copy all subtitle streams:
find . -depth -name '*x265*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ar 48000 -b:a 384k -c:a aac -c:s copy "${0/x265/x264}"' {} \;; find . -name '*x265*' -type f -delete
##### Just strip all subtitles:
find . -depth -name '*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -map 0:v:0 -map 0:a:0 -c:v copy -c:a copy "${0/ (2000)/}"' {} \;; find . -name '*(2000)*' -type f -delete
##### Futurama Season 7 custom, 2-3 AC3 audio streams with the first having 6-channel and between 1-2 AC3 2-channel commentary tracks, a non-standard hdmv_pgs_subtitle subtitle track ususally at stream 0:3 requiring dropping and replacement with external .srt file
find . -depth -name '*.mkv' -type f -exec bash -c 'ffmpeg -i "$0" -f srt -i "${0/mkv/en.srt}" -map 0:v:0 -map 0:a:0 -map 0:a:1 -map 0:a:2? -map 1:0 -c:v copy -ac:0 6 -ac:1 2 -ac:2 2 -ar 48000 -c:a:0 aac -c:a:1 aac -c:a:2 aac -c:s srt ./working/"${0/DD5.1/AAC5.1}"' {} \;
##### Increase volume to 150% of original media
for f in *.mkv; do ffmpeg -i "$f" -map 0 -filter:a "volume=1.5" -c:v copy -c:a aac -c:s copy "../working/$f"; done
for f in /path/to/directory/*.mkv; do ffmpeg -i "$f" \
-map 0 -filter:a "volume=2.0" -c:v copy -c:a aac -c:s copy \
"/path/to/directory/.working/$(basename "$f")"; done
ffmpeg -i input.mp4 -map 0 -filter:a "volume=1.5" -c:v copy -c:a aac -c:s copy output.mp4
##### Remove data stream from MP4 container
1a) ffmpeg -i in.mp4 -c copy -dn -map_metadata:c -1 out.mp4
1b) for f in *.mp4; do ffmpeg -i "$f" -c copy -dn -map_metadata:c -1 "$f"; done
##### Remove chapters from the container
1a) ffmpeg -i input.mp4 -map 0:v -map 0:a -c:v copy -c:a copy -map_chapters -1 output.mp4
1b) for f in *.mp4; do ffmpeg -i "$f" -map 0:v -map 0:a -map 0:s? -c:v copy -c:a copy -c:s copy -map_chapters -1 "$f"; done
##### Remove closed captions (CC)
1a) ffmpeg -y -i input.mkv -map 0 -c copy -bsf:v "filter_units=remove_types=6" output.mkv
1b) for f in *.mkv; do ffmpeg -y -i "$f" -default_mode infer_no_subs -map 0:v -map 0:a -map 0:s? -c:v copy -c:a copy -c:s copy -bsf:v "filter_units=remove_types=6" "./.working/${f}"; done
##### Insert srt subtitle to mp4
ffmpeg -i 'I Am Legend (2007) - ALTERNATE ENDING 1080p BrRip x264.mp4' -i 'I Am Legend (2007) - ALTERNATE ENDING 1080p BrRip x264.en.srt' -metadata:s:s:0 language=eng -c:v copy -c:a copy -c:s mov_text 'I Am Legend (2007) - ALTERNATE ENDING 1080p BrRip x264_2.mp4'
##### Exports clean Subrip/srt subtitle file without annoying <font-face=blah; font-size=18px;> HTML tagging - Extract subtitle from mp4 (and mkv, maybe?) file in Subrip/srt format (Subtitle codec name "text" instead of srt/mov_text)
for f in *.mp4; do ffmpeg -y -i "$f" -map 0:s? -c:s text "${f/.mp4/.en.srt}"; done
##### Find directories with more than one media file
find . -regextype posix-extended -regex ".*mkv$|.*mp4$" -type f -printf '%h\n' | sort | uniq -d
##### Convert interlaced to progressive (1080i -> 1080p)
ffmpeg -i '/media/file1.mkv' -vf yadif -c:v libx264 -preset slow -crf 19 -c:a aac -b:a 192k -c:s srt -max_muxing_queue_size 400 /media/file2.mkv
ffmpeg -i "interlaced.mkv" -vf yadif=1 -movflags +faststart -y -preset fast -profile:v high -crf 20 -ac 2 -b:a 192k -strict experimental -c:v libx264 -c:a aac "progressive.mkv"
# yadif=0 is normally the preferred option when deinterlacing video as yadif=1 will double the frame-rate of the output video
ffmpeg -i "interlaced.mkv" -vf yadif=0 -y -preset fast -profile:v high -crf 20 -ac 2 -b:a 192k -strict experimental -c:v libx264 -c:a aac "progressive.mkv"
# H.264 interlaced BT709 > H.264 progressive BT709
ffmpeg -i "BBC.Van.Gogh.Painted.With.Words.1080i.HDTV.MVGroup.mkv" -default_mode infer_no_subs -map 0 -map_chapters -1 -dn -metadata title="BBC.Van.Gogh.Painted.With.Words.1080p.HDTV.mkv" -metadata:s:v:0 title= -metadata:s:a:0 title= -vf "yadif=0, colorspace=all=bt709:iall=bt601-6-625:fast=1" -colorspace 1 -color_primaries 1 -color_trc 1 -b:v 6M -bufsize 6M -minrate 3M -maxrate 10M -profile:v high -pix_fmt yuv420p -preset slow -channel_layout "5.1" -strict experimental -max_muxing_queue_size 400 -c:v libx264 -c:a aac -c:s copy "BBC.Van.Gogh.Painted.With.Words.1080p.HDTV.mkv"
##### Increase max muxing queue size
ffmpeg -i 'input.mkv' -max_muxing_queue_size 400 'output.mkv'
##### Remove subtitle and audio description/title and add english metadata
for f in *.mkv; do ffmpeg -y -i "$f" -codec copy -metadata:s:a:0 language=eng -metadata:s:a:0 title= -metadata:s:s:0 language=eng -metadata:s:s:0 title= ./working/"${f}"; done
##### Add text metadata to various sections of file
for f in *.mkv; do ffmpeg -y -i "$f" -codec copy -metadata comment="Matroska muxer also accepts free-form key/value metadata pairs" -metadata foo="bar" -metadata description="Matroska muxer description" -metadata:s:v:0 title="Video stream title/description" -metadata:s:a:0 title="Audio stream title/description" -metadata:s:s:0 language=eng -metadata:s:s:0 title="Subtitle stream title/description" ./working/"${f}"; done
ffmpeg -y -i input.mkv -codec copy -metadata comment="Matroska muxer also accepts free-form key/value metadata pairs" -metadata foo="bar" -metadata description="Matroska muxer description" -metadata:s:v:0 title="Video stream title/description" -metadata:s:a:0 title="Audio stream title/description" -metadata:s:s:0 language=eng -metadata:s:s:0 title="Subtitle stream title/description" output.mkv
##### Add Matroska Title metadata to the container while removing Title metadata from all of its streams (video, audio, subtitle)
ffmpeg -y -i input.mkv -f srt -i input.en.srt -map 0:v -map 0:a:1 -map 1:0 -movflags +faststart -metadata:s:v:0 language= -metadata:s:s:0 language=eng -metadata:s:v:0 Title= -metadata:s:a:0 Title= -metadata:s:s:0 Title= -metadata Title="Who Am I (1998)" -disposition 0 -disposition:s:1 default -c:v copy -c:a copy -c:s srt output.mkv
##### Transcode avi files into standard mp4 containers
for f in **/*.avi; do ffmpeg -i "$f" -map 0:v:0 -map 0:a -dn -map_chapters -1 \
-movflags faststart -profile:v high -pix_fmt yuv420p -metadata:s:a:0 language=eng \
-metadata:s:v:0 title= -metadata:s:a:0 title= -c:v libx264 -c:a aac \
"../.working/${f/.avi/.mp4}"; done
#################### Methods of Reducing file size with FFmpeg ####################
# https://trac.ffmpeg.org/wiki/EncodingForStreamingSites
##### Modify the bitrate, using:
ffmpeg -i $infile -b $bitrate $newoutfile
##### Vary the Constant Rate Factor, using:
ffmpeg -i $infile -vcodec libx264 -crf 23 $outfile
##### Change/scale the video screen-size (for example to 1080p or half its pixel size):
ffmpeg -i $infile -vf "scale=iw/2:ih/2" $outfile
# This method takes care of error: (libx264) "height not divisible by 2"
# https://stackoverflow.com/questions/20847674/ffmpeg-libx264-height-not-divisible-by-2
# https://superuser.com/questions/624563/how-to-resize-a-video-to-make-it-smaller-with-ffmpeg
ffmpeg -y -i "input.mp4" \
-map 0:v -map 0:a -dn -map_chapters -1 -filter:v scale="1920:trunc(ow/a/2)*2" \
-movflags faststart -profile:v high -pix_fmt yuv420p -metadata:s:a:0 language=eng \
-c:v libx264 -c:a copy "output.mp4"
##### Another one but different
ffmpeg -y -i "input.mp4" -map 0:v -map 0:a \
-dn -map_chapters -1 -metadata:s:v:0 handler_name= -metadata:s:a:0 handler_name= \
-vf pad=ceil(iw/2)*2:ceil(ih/2)*2 -movflags faststart -profile:v high -pix_fmt yuv420p \
-metadata:s:a:0 language=eng -c:v libx264 -c:a copy "output.mp4"
##### Change the H.264 profile to "baseline", using:
ffmpeg -i $infile -profile:v baseline $outfile
Use the default ffmpeg processing, using:
ffmpeg -i $infile $outfile
##### Bitrate Guidelines:
# Calculate the bitrate you need by dividing your target size (in bits) by the video length (in seconds). For example for a target size of 1 GB (one giga<em>byte</em>, which is 8 giga<em>bits</em>) and 10,000 seconds of video (2 h 46 min 40 s), use a bitrate of 800 000 bit/s (800 kbit/s):
ffmpeg -i input.mp4 -b 800k output.mp4
##### example 1:
# ffmpeg -i input.mkv -c:v libx264 -preset medium -b:v 3000k -maxrate 3000k -bufsize 6000k \
# -vf "scale=1280:-1,format=yuv420p" -g 50 -c:a aac -b:a 128k -ac 2 -ar 44100 file.flv
#
###################################################################################
##### Concatenation https://trac.ffmpeg.org/wiki/Concatenate
for f in ./*.mkv; do echo "file '$f'" >> mylist.txt; done
##### Note that these can be either relative or absolute paths. Then you can stream copy or re-encode your files:
ffmpeg -f concat -safe 0 -i "mylist.txt" "output.mkv"
##### Concatenate multiple media files
for f in ./*.mkv; do echo "file '$f'" >> mylist.txt; done
ffmpeg -f concat -safe 0 -i "mylist.txt" -b 4292k -c copy "Top.Gear.Patagonia.Special.1080p.mkv"
##### Map only English audio stream and English subtitle streams if it exists
for f in *.mkv; do ffmpeg -y -i "$f" -map 0:v:0 -map 0:a:m:language:eng -map 0:s:m:language:eng? -codec:v copy -codec:a copy -codec:s srt "../../../../temp/ffmpeg-vcodec/.working/${f/x265/x264}"; done
##### Dont set any subtitle streams as default or forced
for f in *.mkv; do ffmpeg -y -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a:0 -map 0:s:m:language:eng? -disposition:s 0 -codec copy "$f"; done
-default_mode
This option controls how the FlagDefault of the output tracks will be set. It influences which tracks players should play by default. The default mode is ‘infer’.
'infer'
In this mode, for each type of track (audio, video or subtitle), if there is a track with disposition default of this type, then the first such track (i.e. the one with the lowest index) will be marked as default; if no such track exists, the first track of this type will be marked as default instead (if existing). This ensures that the default flag is set in a sensible way even if the input originated from containers that lack the concept of default tracks.
'infer_no_subs'
This mode is the same as infer except that if no subtitle track with disposition default exists, no subtitle track will be marked as default.
'passthrough'
In this mode the FlagDefault is set if and only if the AV_DISPOSITION_DEFAULT flag is set in the disposition of the corresponding stream.
##### Sync multiple audios streams
for f in *.mkv; do ffmpeg -y -i "${f}" -i "${f/.mkv/.m4a}" \
-c:v copy -b:a:0 128k -filter_complex "[a:0]aresample=async=1000[a:0]" -movflags faststart -c:a:0 aac -c:a:1 copy -c:s copy \
-map 0:v:0 -map 1:0 -map 0:a:0 $(i=1; while [ $i -lt 28 ]; do echo -n "-map 0:s:$((i++)) "; done) \
-metadata:s:a:0 language=eng -disposition 0 -disposition:a:0 default -disposition:s:0 default -metadata:s:s:0 title= \
-metadata:s:a comment= -shortest "${f/.NF.WEB-DL.AAC5.1.x264-NTG.mkv/.ENG-SPA.WEB-DL.AAC5.1.x264.mkv}"; done
##### Insert arbitrary audio stream and alter the starttime offset with '-itsoffset' paramter.
ffmpeg -y -i 'Spider-Man.No.Way.Home.2021.HDTC.1080P.4GB.H264.CLEAR.AUDIO.AAC-DH18.mkv' -itsoffset -500ms \
-f aac -i 'Spider-Man.No.Way.Home.2021.720p.HDTC.(V3).x264.AAC.B4ND1T69.aac' -map 0:v -map 1:0 -map 0:a:0 \
-metadata title='Spider-Man: No Way Home (2021)' -metadata:s:a:0 title=B4ND1T69rip -map_metadata -1 -map_chapters -1 \
-disposition:a:0 default -disposition:a:1 0 -metadata:s:a:0 language=eng -metadata:s:a:1 language=eng \
-fflags +bitexact -flags:v +bitexact -flags:a +bitexact -ac 2 -c:v copy -c:a:0 aac -c:a:1 copy \
'Spider-Man.No.Way.Home.2021.HDTC.1080p.H264.CLEAREST.DUAL-AAC2.0-TFLX.mkv'
##### ffprobe #####
##### Output filename, audio codec name, and number of channels
find . -mount -depth -maxdepth 1 -regextype posix-extended -regex '.*\.mkv$|.*\.mp4$' -type f -exec bash -c 'echo "{}" $(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "{}")' \;
##### Output filename, and video codecs
find . -mount -depth -maxdepth 1 -regextype posix-extended -regex '.*\.mkv$|.*\.mp4$' -type f -exec bash -c 'echo "{}" $(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=noprint_wrappers=1:nokey=1 "{}")' \;
##### Output filename and video bit depth
find . -mount -depth -maxdepth 1 -regextype posix-extended -regex '.*\.mkv$|.*\.mp4$' -type f -exec bash -c 'echo "{}" $(ffprobe -loglevel error -select_streams v:0 -show_entries stream=bits_per_raw_sample -of default=nw=1:nk=1 "{}")' \;
############################ ############################
############################ FFmpeg Filtering ############################
############################ ############################
Filtering in FFmpeg is enabled through the libavfilter library
In libavfilter, a filter can have multiple inputs and multiple outputs. To illustrate the sorts of things that are possible, we consider the following filtergraph.
[main]
input --> split ---------------------> overlay --> output
| ^
|[tmp] [flip]|
+-----> crop --> vflip -------+
ffmpeg -i INPUT -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" OUTPUT
The result will be that the top half of the video is mirrored onto the bottom half of the output video.
Filters in the same linear chain are separated by commas, and distinct linear chains of filters are separated by semicolons. In our example, crop,vflip are in one linear chain, split and overlay are separately in another. The points where the linear chains join are labelled by names enclosed in square brackets. In the example, the split filter generates two outputs that are associated to the labels [main] and [tmp].
The stream sent to the second output of split, labelled as [tmp], is processed through the crop filter, which crops away the lower half part of the video, and then vertically flipped. The overlay filter takes in input the first unchanged output of the split filter (which was labelled as [main]), and overlay on its lower half the output generated by the crop,vflip filterchain.
Some filters take in input a list of parameters: they are specified after the filter name and an equal sign, and are separated from each other by a colon.
There exist so-called source filters that do not have an audio/video input, and sink filters that will not have audio/video output.
11.40 colormatrix
Convert color matrix.
The filter accepts the following options:
src
dst
Specify the source and destination color matrix. Both values must be specified.
The accepted values are:
‘bt709’
BT.709
‘fcc’
FCC
‘bt601’
BT.601
‘bt470’
BT.470
‘bt470bg’
BT.470BG
‘smpte170m’
SMPTE-170M
‘smpte240m’
SMPTE-240M
‘bt2020’
BT.2020
For example to convert from BT.601 to SMPTE-240M, use the command:
colormatrix=bt601:smpte240m
11.41 colorspace
Convert colorspace, transfer characteristics or color primaries. Input video needs to have an even size.
The filter accepts the following options:
all
Specify all color properties at once.
The accepted values are:
‘bt470m’
BT.470M
‘bt470bg’
BT.470BG
‘bt601-6-525’
BT.601-6 525
‘bt601-6-625’
BT.601-6 625
‘bt709’
BT.709
‘smpte170m’
SMPTE-170M
‘smpte240m’
SMPTE-240M
‘bt2020’
BT.2020
space
Specify output colorspace.
The accepted values are:
‘bt709’
BT.709
‘fcc’
FCC
‘bt470bg’
BT.470BG or BT.601-6 625
‘smpte170m’
SMPTE-170M or BT.601-6 525
‘smpte240m’
SMPTE-240M
‘ycgco’
YCgCo
‘bt2020ncl’
BT.2020 with non-constant luminance
trc
Specify output transfer characteristics.
The accepted values are:
‘bt709’
BT.709
‘bt470m’
BT.470M
‘bt470bg’
BT.470BG
‘gamma22’
Constant gamma of 2.2
‘gamma28’
Constant gamma of 2.8
‘smpte170m’
SMPTE-170M, BT.601-6 625 or BT.601-6 525
‘smpte240m’
SMPTE-240M
‘srgb’
SRGB
‘iec61966-2-1’
iec61966-2-1
‘iec61966-2-4’
iec61966-2-4
‘xvycc’
xvycc
‘bt2020-10’
BT.2020 for 10-bits content
‘bt2020-12’
BT.2020 for 12-bits content
primaries
Specify output color primaries.
The accepted values are:
‘bt709’
BT.709
‘bt470m’
BT.470M
‘bt470bg’
BT.470BG or BT.601-6 625
‘smpte170m’
SMPTE-170M or BT.601-6 525
‘smpte240m’
SMPTE-240M
‘film’
film
‘smpte431’
SMPTE-431
‘smpte432’
SMPTE-432
‘bt2020’
BT.2020
‘jedec-p22’
JEDEC P22 phosphors
range
Specify output color range.
The accepted values are:
‘tv’
TV (restricted) range
‘mpeg’
MPEG (restricted) range
‘pc’
PC (full) range
‘jpeg’
JPEG (full) range
format
Specify output color format.
The accepted values are:
‘yuv420p’
YUV 4:2:0 planar 8-bits
‘yuv420p10’
YUV 4:2:0 planar 10-bits
‘yuv420p12’
YUV 4:2:0 planar 12-bits
‘yuv422p’
YUV 4:2:2 planar 8-bits
‘yuv422p10’
YUV 4:2:2 planar 10-bits
‘yuv422p12’
YUV 4:2:2 planar 12-bits
‘yuv444p’
YUV 4:4:4 planar 8-bits
‘yuv444p10’
YUV 4:4:4 planar 10-bits
‘yuv444p12’
YUV 4:4:4 planar 12-bits
fast
Do a fast conversion, which skips gamma/primary correction. This will take significantly less CPU, but will be mathematically incorrect. To get output compatible with that produced by the colormatrix filter, use fast=1.
dither
Specify dithering mode.
The accepted values are:
‘none’
No dithering
‘fsb’
Floyd-Steinberg dithering
wpadapt
Whitepoint adaptation mode.
The accepted values are:
‘bradford’
Bradford whitepoint adaptation
‘vonkries’
von Kries whitepoint adaptation
‘identity’
identity whitepoint adaptation (i.e. no whitepoint adaptation)
iall
Override all input properties at once. Same accepted values as all.
ispace
Override input colorspace. Same accepted values as space.
iprimaries
Override input color primaries. Same accepted values as primaries.
itrc
Override input transfer characteristics. Same accepted values as trc.
irange
Override input color range. Same accepted values as range.
The filter converts the transfer characteristics, color space and color primaries to the specified user values. The output value, if not specified, is set to a default value based on the "all" property. If that property is also not specified, the filter will log an error. The output color range and format default to the same value as the input color range and format. The input transfer characteristics, color space, color primaries and color range should be set on the input data. If any of these are missing, the filter will log an error and no conversion will take place.
For example to convert the input to SMPTE-240M, use the command:
colorspace=smpte240m
############################ ############################
############################ END FFmpeg Filtering ############################
############################ ############################
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected aac audio streams\nPreparing to copy english audio stream' ; sleep 4
ffmpeg -i "$f" -map 0:v:0 -map 0:a:m:language:ger -map 0:a:m:language:eng -map 0:s:m:language:eng -movflags faststart -c:v libx264 -crf 23 -c:a copy -c:s copy "${f/x265/x264}"
else
echo -e '\nffprobe detectable audio streams not equal to aac\nPreparing to transcode with aac' ; sleep 4
ffmpeg -i "$f" -map 0:v:0 -map 0:a:m:language:ger -map 0:a:m:language:eng -map 0:s:m:language:eng -movflags faststart -c:v libx264 -crf 23 -c:a aac -c:s copy "${f/x265/x264}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mkv/.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s srt "./working/${f/X264/X264.AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mkv/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 0 -c:s srt "./working/${f/.mkv/.x264.AAC.mkv}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 640k -c:a aac -disposition:s:0 default -c:s copy "./working/${f/DDP/AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 640k -c:a aac "./working/${f/DDP/AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected aac audio streams\nPreparing to copy english audio stream' ; sleep 4
ffmpeg -i "$f" -map 0:v:0 -map 0:a:m:language:ger -map 0:a:m:language:eng -map 0:s:m:language:eng -movflags faststart -c:v libx264 -crf 23 -c:a copy -c:s copy "${f/x265/x264}"
else
echo -e '\nffprobe detectable audio streams not equal to aac\nPreparing to transcode with aac' ; sleep 4
ffmpeg -i "$f" -map 0:v:0 -map 0:a:m:language:ger -map 0:a:m:language:eng -map 0:s:m:language:eng -movflags faststart -c:v libx264 -crf 23 -c:a aac -c:s copy "${f/x265/x264}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mkv/.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s srt "./working/${f/X264/X264.AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mkv/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 0 -c:s srt "./working/${f/.mkv/.x264.AAC.mkv}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 640k -c:a aac -disposition:s:0 default -c:s copy "./working/${f/DDP/AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 640k -c:a aac "./working/${f/DDP/AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mkv/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 768k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s srt "./working/${f/DTS-JYK/AAC5.1}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\n\tffprobe detected '$audioformat' in the default audio stream a:0, while it expected aac.\n\tPreparing to convert default audio stream codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 256k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s copy "./working/${f/.mkv/.AAC.mkv}"
fi
done
for f in *.mp4; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mp4/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 640k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -c:s mov_texSystems Administratort "../working/${f/1040p.BluRay.5.1.x264 . NVEE.mp4/1080p.BluRay.AAC.x264.mp4}"
fi
done
for f in *.mp4; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mp4/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 448k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -c:s mov_texSystems Administratort "../working/${f/.mp4/.AAC.mp4}"
fi
done
for f in *.mp4; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mp4/.en.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 2 -ar 48000 -b:a 192k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -c:s mov_texSystems Administratort "../working/${f/.mp4/.AAC.mp4}"
fi
done
for f in *.mp4; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 0 -c:s copy "./working/${f/.mp4/ AAC x264.mp4}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -f srt -i "${f/.mkv/.srt}" -map 0:v:0 -map 0:a:0 -map 1:0 -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s srt "./working/${f/x264.mkv/AAC.x264.mkv}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 640k -metadata:s:a:0 language=eng -c:a aac -c:s copy "./working/${f/DDP/AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 768k -metadata:s:a:0 language=eng -c:a aac -c:s copy "./working/${f/DDP/AAC}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 384k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s copy "./working/${f/AC3-EVO/AAC51}"
fi
done
for f in *.mkv; do
audioformat=$(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f")
if ! [ "$audioformat" = "aac" ]; then
echo -e '\nffprobe detected '$audioformat' in the default audio stream a:0\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac 6 -ar 48000 -b:a 192k -metadata:s:a:0 language=eng -c:a aac -metadata:s:s:0 language=eng -disposition:s:0 default -c:s copy "./working/${f/AC3-EVO/AAC51}"
fi
done
ffprobe -v error -select_streams a:0 -show_entries stream=channels,bit_rate -of default=noprint_wrappers=1:nokey=1 video.mp4
shopt -s globstar
for f in **/*.mp4; do
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -c:v copy -ac ${AUDIOFORMAT[1]} -ar 48000 -metadata:s:a:0 language=eng -c:a aac -sn "/mnt/pool0/p0ds0smb/temp/ffmpeg/working/${f}"
fi
done
shopt -s globstar
for f in **/*.mkv; do
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\nPreparing to convert audio codec to AAC...\n' ; sleep 1
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac ${AUDIOFORMAT[1]} -ar 48000 -metadata:s:a:0 language=eng -c:a aac -disposition:s:0 default -c:s srt "/mnt/pool0/p0ds0smb/temp/ffmpeg/working/${f/h264/aac.h264}"
fi
done
##### MKV
# Remember to include trailing slash in TEMPDIR
TEMPDIR='/mnt/pool0/p0ds0smb/temp/ffmpeg/working/'
shopt -s globstar
for f in **/*.mkv; do
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\nPreparing to convert audio codec to AAC...\n' ; sleep 2
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac ${AUDIOFORMAT[1]} -ar 48000 -metadata:s:a:0 language=eng -c:a aac -c:s copy "$TEMPDIR$(basename "${f}")"
echo -e '\nMoving '$(basename "${f}")' back to source directory name '$(dirname "${f}")'\n'; sleep 2
mv -ufv "$TEMPDIR$(basename "${f}")" "$(dirname "${f}")"
fi
done
##### MP4
# Remember to include trailing slash in TEMPDIR
TEMPDIR='/mnt/pool0/p0ds0smb/temp/ffmpeg/working/'
shopt -s globstar
for f in **/*.mp4; do
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\nPreparing to convert audio codec to AAC...\n' ; sleep 2
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac ${AUDIOFORMAT[1]} -ar 48000 -metadata:s:a:0 language=eng -c:a aac -c:s copy "$TEMPDIR$(basename "${f}")"
echo -e '\nMoving '$(basename "${f}")' back to source directory name '$(dirname "${f}")'\n'; sleep 2
mv -ufv "$TEMPDIR$(basename "${f}")" "$(dirname "${f}")"
fi
done
##### MP4 in current dir
TEMPDIR='/mnt/pool0/p0ds0smb/temp/ffmpeg/working/'
shopt -s globstar
for f in *.mp4; do
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\nPreparing to convert audio codec to AAC...\n' ; sleep 2
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac ${AUDIOFORMAT[1]} -ar 48000 -metadata:s:a:0 language=eng -c:a aac -c:s copy "$TEMPDIR$(basename "${f}")" || exit 1
echo -e '\nMoving '$(basename "${f}")' back to source directory name '$(dirname "${f}")'\n'; sleep 2
mv -ufv "$TEMPDIR$(basename "${f}")" "$(dirname "${f}")"
fi
done
##### MKV and MP4
# Remember to include trailing slash in TEMPDIR
TEMPDIR='/mnt/pool0/p0ds0smb/temp/ffmpeg/working/'
shopt -s globstar
for f in **/*.mkv **/*.mp4; do
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\nPreparing to convert audio codec to AAC...\n' ; sleep 2
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -c:v copy -ac ${AUDIOFORMAT[1]} -ar 48000 -metadata:s:a:0 language=eng -c:a aac -c:s copy "$TEMPDIR$(basename "${f}")"
echo -e '\nMoving '$(basename "${f}")' back to source directory name '$(dirname "${f}")'\n'; sleep 2
mv -ufv "$TEMPDIR$(basename "${f}")" "$(dirname "${f}")"
fi
done
##### Nvidia hardware acceleration
TEMPDIR='/media/visualblind/p0ds0smb/temp/ffmpeg/working/'
shopt -s globstar
for f in *.mkv; do
VIDEOFORMAT=($(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f"))
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
echo -e '\nffprobe detected '${VIDEOFORMAT[0]}' in the default video stream v:0 \n\n\tPreparing to convert video codec to H264...\n\n'
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\n\tPreparing to convert audio codec to AAC...\n' ; sleep 3
ffmpeg -vsync 0 -hwaccel cuvid -hwaccel_output_format cuda -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s? -movflags +faststart -ac ${AUDIOFORMAT[1]} -ar 48000 -c:v h264_nvenc -c:a aac -metadata:s:a:0 language=eng -metadata:s:s:0 language=eng -disposition:s:0 default -c:s copy "$TEMPDIR$(basename "${f/ WEB-DL x265 ImE/ x264}")" || break
echo -e '\nMoving '$(basename "${f}")' back to source directory name '$(dirname "${f}")'\n'
mv -ufv "$TEMPDIR$(basename "${f}")" "$(dirname "${f}")"; sleep 2
fi
done
##### H.264/AAC/SRT
TEMPDIR='/mnt/pool0/p0ds0smb/temp/ffmpeg/working/'
shopt -s globstar
for f in *.mkv; do
#VIDEOFORMAT=($(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f"))
AUDIOFORMAT=($(ffprobe -loglevel error -select_streams a:0 -show_entries stream=codec_name,channels -of default=nw=1:nk=1 "$f"))
if ! [ "${AUDIOFORMAT[0]}" = "aac" ]; then
# echo -e '\nffprobe detected '${VIDEOFORMAT[0]}' in the default video stream v:0 \n\n\tPreparing to convert video codec to H264...\n\n'
echo -e '\nffprobe detected '${AUDIOFORMAT[0]}' in the default audio stream a:0 with '${AUDIOFORMAT[1]}' channels\n\n\tPreparing to convert audio codec to AAC...\n' ; sleep 3
ffmpeg -i "$f" -map 0:v:0 -map 0:a:0 -map 0:s -movflags +faststart -ac ${AUDIOFORMAT[1]} -ar 48000 -c:v libx264 -c:a aac -metadata:s:a:0 language=eng -metadata:s:s:0 language=eng -disposition:s:0 default -c:s copy "$TEMPDIR$(basename "${f}")" || break
echo -e '\nMoving '$(basename "${f}")' back to source directory name '$(dirname "${f}")'\n'
mv -ufv "$TEMPDIR$(basename "${f}")" "$(dirname "${f}")"
fi
done
##### HEVC > AVC (libx264)
TEMPDIR='/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working'
shopt -s globstar
for f in *.mkv; do
VFORMAT=($(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f"))
if ! [[ "${VFORMAT[0]}" == 'avc' ]]; then
echo -e '\n---> '$(basename "$f")': detected '${VFORMAT[0]}' in the default video stream\n---> Preparing to convert video codec accelerated with h264_nvenc (nVidia) to H264...\n\n'
NEWNAME="${f/x265/x264}"
ffmpeg -i "$f" -default_mode infer_no_subs -map 0:v:0 -map 0:a:0 -map "0:s?" -disposition:v:0 default -disposition:a:0 default -map_chapters -1 -dn -map_metadata -1 -bsf:v "filter_units=remove_types=6" -preset slow -profile:v high -pix_fmt yuv420p -c:v libx264 -metadata:s:a:0 language=eng -c:a copy -c:s copy "$TEMPDIR/$NEWNAME" || break
echo -e '\n---> Moving '$(basename "$f")' back to source directory name '$(pwd)'\n'
mv -ufv "$TEMPDIR/$NEWNAME" "$(dirname "$f")"
fi
done
##### HEVC > AVC (h264_nvenc) NVIDIA Accelerated
TEMPDIR='/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working'
shopt -s globstar
for f in *.mkv; do
VFORMAT=($(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f"))
if ! [[ "${VFORMAT[0]}" == 'avc' ]]; then
echo -e '\n---> '$(basename "$f")': detected '${VFORMAT[0]}' in the default video stream\n---> Preparing to convert video codec accelerated with h264_nvenc (nVidia) to H264...\n\n'
NEWNAME="${f/x265/x264}"
/usr/bin/ffmpeg-424 -vsync 0 -hwaccel cuda -i "$f" -map 0:v:0 -map 0:a:0 -map "0:s?" -disposition:v:0 default -disposition:a:0 default -map_chapters -1 -dn -map_metadata -1 -bsf:v "filter_units=remove_types=6" -preset slow -profile:v high -pix_fmt yuv420p -c:v h264_nvenc -metadata:s:a:0 language=eng -c:a copy -c:s copy "$TEMPDIR/$NEWNAME" || break
echo -e '\n---> Moving '$(basename "$f")' back to source directory name '$(pwd)'\n'
mv -ufv "$TEMPDIR/$NEWNAME" "$(dirname "$f")"
fi
done
##### HEVC > AVC (h264_nvenc) NVIDIA Accelerated + External Subtitle
TEMPDIR='/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working'
shopt -s globstar
for f in *.mkv; do
VFORMAT=($(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f"))
if ! [[ "${VFORMAT[0]}" == 'avc' ]]; then
echo -e '\n---> '$(basename "$f")': detected '${VFORMAT[0]}' in the default video stream\n---> Preparing to convert video codec accelerated with h264_nvenc (nVidia) to H264...\n\n'
NEWNAME="${f/x265/x264}"
/usr/bin/ffmpeg-424 -vsync 0 -hwaccel cuda -i "$f" -f srt -i "./Subs/${f/mkv/en.srt}" -map 0:v:0 -map 0:a:m:language:eng -map 1:0 -disposition:v:0 default -disposition:a:0 default -disposition:s:0 0 -map_chapters -1 -dn -bsf:v "filter_units=remove_types=6" -preset slow -profile:v high -pix_fmt yuv420p -c:v h264_nvenc -metadata:s:a:0 language=eng -metadata:s:s:0 language=eng -c:a copy -c:s srt "$TEMPDIR/$NEWNAME" || break
echo -e '\n---> Moving '$(basename "$f")' back to source directory name '$(pwd)'\n'
mv -ufv "$TEMPDIR/$NEWNAME" "$(dirname "$f")"
fi
done
##### HEVC > AVC (h264_nvenc) NVIDIA Accelerated - NO Subtitles
TEMPDIR='/media/visualblind/p0ds0smb/temp/ffmpeg-vcodec/.working'
shopt -s globstar
for f in *.mkv; do
VFORMAT=($(ffprobe -loglevel error -select_streams v:0 -show_entries stream=codec_name -of default=nw=1:nk=1 "$f"))
if ! [[ "${VFORMAT[0]}" == 'avc' ]]; then
echo -e '\n---> '$(basename "$f")': detected '${VFORMAT[0]}' in the default video stream\n---> Preparing to convert video codec accelerated with h264_nvenc (nVidia) to H264...\n\n'
NEWNAME="${f/x265/x264}"
/usr/bin/ffmpeg-424 -vsync 0 -hwaccel cuda -i "$f" -map 0:v:0 -map 0:a:m:language:eng -disposition:v:0 default -disposition:a:0 default -map_chapters -1 -dn -bsf:v "filter_units=remove_types=6" -preset slow -profile:v high -pix_fmt yuv420p -c:v h264_nvenc -metadata:s:a:0 language=eng -c:a copy "$TEMPDIR/$NEWNAME" || break
echo -e '\n---> Moving '$(basename "$f")' back to source directory name '$(pwd)'\n'
mv -ufv "$TEMPDIR/$NEWNAME" "$(dirname "$f")"
fi
done
# Jellyfin Video Codec Compatibility/Support
| Sorted by efficency | Chrome | Edge | Firefox | Safari | Anroid | Android TV | iOS | SwiftFin (iOS) | Roku | Kodi | Desktop |
|---------------------|--------|------|---------|--------|--------|------------|-----|----------------|------|------|---------|
| MPEG-4 Part 2/SP | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ✅ |
| MPEG-4 Part 2/ASP | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | ✅ | ✅ |
| H.264 8Bit | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| H.264 10Bit | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ | ✅ |
| H.265 8Bit | 🔶8 | ✅7 | ❌ | 🔶1 | 🔶2 | ✅5 | 🔶1 | ✅6 | 🔶9 | ✅ | ✅ |
| H.265 10Bit | 🔶8 | ✅7 | ❌ | 🔶1 | 🔶2 | 🔶5 | 🔶1 | ✅6 | 🔶9 | ✅ | ✅ |
| VP9 | ✅ | ✅ | ✅ | ❌ | ✅3 | 🔶3 | ❌ | ❌ | ✅ | ✅ | ✅ |
| AV1 | ✅ | ✅ | ✅ | ❌ | ✅ | 🔶4 | ❌ | ❌ | ✅ | ✅ | ✅ |
1HEVC is only supported in MP4, M4V, and MOV containers.
2Android playback is currently broken. Client reports that HEVC is supported and attempts to Direct Stream.
3May be (partially) dependent on Hardware support (can be compensated with CPU decoding on Android). Most new Android phones in the higher price range and many "4K" Android TV devices have VP9 hardware decoding support. Refer to you manufacturer for supported codecs.
4Needs atleast Android TV 10.
5As of version 0.12, HEVC is enabled on all devices running Android 5.0+, but early generations of the Amazon Fire may not work yet. 10Bit may be supported depending on your device. Before Client 0.12, HEVC support was enabled on specific devices.
6HEVC decoding is supported on Apple devices with the A8X chip or newer and at least iOS 14.
7HEVC decoding is only supported on Windows 10 with the HEVC Video Extension from the Microsoft store.
8Chromium 104 does support HEVC decoding when launched with --enable-features=PlatformHEVCDecoderSupport argument. For more informations please look at enable-chromium-hevc-hardware-decoding.
9HEVC decoding is only supported on 4K devices.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment