Jellyfin Forum
Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - Printable Version

+- Jellyfin Forum (https://forum.jellyfin.org)
+-- Forum: Off Topic (https://forum.jellyfin.org/f-off-topic)
+--- Forum: General Discussion (https://forum.jellyfin.org/f-general-discussion)
+--- Thread: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) (/t-encoding-discussion-megathread-ffmpeg-handbrake-av1-etc)

Pages: 1 2 3 4 5 6 7 8 9 10


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - TheDreadPirate - 2023-09-16

How do I use ffmpeg to encode with HEVC Main10/10-bit? This parameter is supposed to work, but I know that placement within the command is important and I don't know where that is.

Code:
-profile:v main10

Code:
/usr/lib/jellyfin-ffmpeg/ffmpeg \
                -init_hw_device vaapi=va:,driver=iHD,kernel_driver=i915 \
                -init_hw_device qsv=qs@va \
                -filter_hw_device qs \
                -hwaccel qsv \
                -hwaccel_output_format qsv \
                -i "$inputFile" \
                -map 0:v \
                -map 0:a \
                -map 0:s \
                -map_chapters 0 \
                -c:v hevc_qsv \
                -preset slower \
                $hdrProfile \   <------ profile:v main10 goes here if I run my script and specify it is HDR.
                -pix_fmt nv12 \
                -c:a copy \
                -c:s copy \
                -ss $startTime \
                -to $endTime \
                -global_quality:v $quality \
                -vf "$filters" \
                "$outputFile"



RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - bitmap - 2023-09-16

In my experience, the placement matters for certain things, less for others. The profile never seemed to matter as long as it was in the correct block. If you're getting errors, try changing your pixel format.

The pixel format you have, nv12 is the qsv equivalent of yuv420p, which is 8-bit. The qsv equivalent of 10-bit (yuv420p10le) is p010le. Change these two lines:

Code:
-profile:v main10
-pix_fmt p010le



RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - TheDreadPirate - 2023-09-17

(2023-09-16, 10:07 PM)bitmap Wrote: In my experience, the placement matters for certain things, less for others. The profile never seemed to matter as long as it was in the correct block. If you're getting errors, try changing your pixel format.

The pixel format you have, nv12 is the qsv equivalent of yuv420p, which is 8-bit. The qsv equivalent of 10-bit (yuv420p10le) is p010le. Change these two lines:

Code:
-profile:v main10
-pix_fmt p010le

That was it.  Thanks!

   


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - bitmap - 2023-09-20

Okay so I did something I think is cool? Maybe it's stupid, but I can see some pretty interesting applications for just converting older media, which I have a lot of at this point.

I created a script, which I'm transforming into a program at the moment, that does adaptive video bitrate deduction using ffprobe to match the bitrate of your video and sacrifice as little quality as possible during encoding. I was trying to throw together something that could scrape HUGE series I have (I'm archiving some educational content) and encode them all at once. I made this great script that was working and when I finally threw it against one of my series, I was turning 250 MB episodes into 900 MB bloated nightmares and dropping thousands of frames every which way.

It sucks because I'm stuck using constant bitrate and the compromise is to run two-pass encodes. So I thought...can I get the existing bitrate? Surely ffprobe can give me that information and I can steal it in a usable way? Well...seven hours later, here I am, running this script with reasonable results that I think are within a) expectations, b) margins of error, and c) some bloat expected from likely poor quality audio.

Things that do work:
* Set a fallback/ceiling video bitrate
* If video's bitrate exceeds ceiling, fallback bitrate is used
* Script hunts for all video within subdirectories
* Copies chapters (but not explicitly...)
* Turn on/off adaptive video bitrate
* All audio currently set to OPUS, easily changed
* Ability to map up to two audio streams
* Duplicate primary audio into a downmixed stereo stream
* Specify bitrate for primary stereo downmix
* Change your container (but why?)
* Change your preset
* Cleaning of filenames to set metadata and rename output files (regex-like bash parameter expansion)
* Set basic metadata


Things I don't have implemented, but want to:
* Video filters (de-interlacing, scaling, maybe others)
* Support for more than just bitrate control (I hate it)
* Easier options -- building the program it's pretty monstrous, but I'm not certain how to make it simpler
* Pixel formats (i.e., setting for 10-bit encoding, as AV1 doesn't allow for this)
* Choose your own encoder -- this is harder since they're all so different
* Pick your codecs and bit rates more easily
* Pick your streams more easily
* Interactive terminal choices (take a sample file from a dir, simplify ffprobe/mediainfo, offer choices, select best options, go)

Anyway, I'm having fun. Maybe this will go somewhere, maybe not. At the very least, somebody can steal the ffprobe and awk functions I'm throwing around. Here are a few results I've gotten:

Code:
Attempting to find adaptive bit rate for mixed media...
Bit rate to be used with ffmpeg: 994.119 kbps...
Beginning first encoding pass for XYZ (1900) - S00E00 - The Great Great Great Great. Starting file size: 429MB
[...]
    frame=98258 fps=1372 q=-0.0 Lsize=  372212kB time=00:54:38.54 bitrate= 930.0kbits/s speed=45.8x    
First pass complete, beginning second encoding pass...
[...]
    frame=98258 fps=1169 q=-0.0 Lsize=  414444kB time=00:54:38.58 bitrate=1035.5kbits/s speed=  39x    
Finished encoding XYZ (1900) - S00E00 - The Great Great Great Great. Final file size: 425MB

The idea wasn't really to minify these episodes, but to convert them to AV1 with as little quality loss as possible for older episodes, with space savings coming for the higher quality episodes. Here's another:

Code:
Attempting to find adaptive bit rate for mixed media...
Bit rate to be used with ffmpeg: 588.209 kbps...
Beginning first encoding pass for XYZ (1900) - S00E00 - Radio Radio Radio. Starting file size: 270MB
[...]
    frame=104452 fps=1456 q=-0.0 Lsize=  229741kB time=00:58:01.80 bitrate= 540.5kbits/s speed=48.5x    
First pass complete, beginning second encoding pass...
[...]
    frame=104452 fps=1232 q=-0.0 Lsize=  270798kB time=00:58:01.90 bitrate= 637.1kbits/s speed=41.1x    
Finished encoding XYZ (1900) - S00E00 - Radio Radio Radio. Final file size: 278MB

Okay, so enough of my BS. Here's the code. It's not commented yet as I just finished putting it together in working fashion. I'm still working on the program version of it. Once I have anything more than just something you can copy and paste into a terminal, I'll throw it on Github.

Code:
# Adaptive AV1_QSV script for use in the terminal with entire series within subfolders

ADAPT=0 && \
ACODEC="libopus" && \
IPATH="" && \
OPATH="" && \
CLEAN="\ \[*\]-*.m[kop4][gv4]" && \
PRAUD="0" && \
SEAUD="" && \
PRSUB="0" && \
SESUB="" && \
TRSUB="" && \
VRATE="4500" && \
VMAX="9000" && \
VBUF="18000" && \
PRESET="slower" && \
ABIT="192k" && \
AFLTR="pan=stereo|FL<FC+0.30*FL+0.30*BL|FR<FC+0.30*FR+0.30*BR" && \
EXT="mkv" && \
QUAL="WEBRip" && \
RES="1080p" && \
LNG="EN" && \
SUBS="EN" && \
GRP="bitmap" && \
shopt -s globstar && \
mkdir -p "${OPATH}/import" && \
clear && \
BV="${VRATE}" && \
MRATE=$"{VMAX}" && \
BSIZE="${VBUF}" && \
for MEDIA in "${IPATH}"/**/*.m[kp][4v]; do
    if [[ $ADAPT -eq 1 ]]; then
        echo "Attempting to find adaptive bit rate for mixed media..." && \
        FFP=$(ffprobe -v error -select_streams v:0 -show_entries format=bit_rate -of default=nw=1:nk=1 "${MEDIA}") && \
        if [[ $FFP != "N/A" ]]; then
            VCON=$(awk "BEGIN { print $FFP*0.00095 }") && \
            SLCT=$(awk "BEGIN { print ($VCON < $VRATE) }") && \
            if [[ $SLCT == 1 ]]; then
                echo "Bit rate to be used with ffmpeg: $VCON kbps..."
                MCON=$(awk "BEGIN { print $VCON*2 }") && \
                BCON=$(awk "BEGIN { print $VCON*4 }") && \
                BV="${VCON}k" && \
                MRATE="${MCON}k" && \
                BSIZE="${BCON}k" && \
                ABIT="128k"
            else
                echo "Identified rate exceeds ${VRATE} kbps, falling back..."
            fi
        else
            echo "FFprobe could not identify a bit rate, falling back to ${VRATE} kbps."
        fi
    else
        echo "Global bit rate for session locked at ${VRATE} kbps..."
    fi
    ISIZE=$(du -BMB "${MEDIA}" | cut -f -1) && \
    FNAME=$(basename "${MEDIA%${CLEAN}}") && \
    OFILE="${OPATH}/${FNAME}-[${QUAL}-${RES}.AV1.OPUS.2.0][${LNG}][${SUBS}]-${GRP}.${EXT}" && \
    echo "Beginning first encoding pass for ${FNAME}. Starting file size: ${ISIZE}" && \
    ffmpeg -y -hide_banner -loglevel warning -v quiet -stats \
    -hwaccel qsv -hwaccel_output_format qsv -qsv_device /dev/dri/renderD129 \
    -i "${MEDIA}" -pass 1 -map_metadata 0 -map 0:v:0 \
    -c:v av1_qsv -preset "${PRESET}" -look_ahead 1 -look_ahead_depth 100 \
    -b:v "${BV}" -maxrate:v "${MRATE}" -bufsize:v "${BSIZE}" \
    -an -sn \
    "${OFILE}" && \
    echo "First pass complete, beginning second encoding pass..." && \
    ffmpeg -y -hide_banner -loglevel warning -v quiet -stats \
    -hwaccel qsv -hwaccel_output_format qsv -qsv_device /dev/dri/renderD129 \
    -i "${MEDIA}" -pass 2 -map_metadata 0 -map 0:v:0 \
    -map 0:a:"${PRAUD}" \
    #-map 0:a:"${PRAUD}" \
    #-map 0:a:"${SEAUD}" \
    #-map 0:a \
    -map 0:s:"${PRSUB}" \
    #-map 0:s:"${SESUB}" \
    #-map 0:s:"${TRSUB}" \
    #-map 0:s \
    #-map 0:t? \
    -c:v av1_qsv -preset "${PRESET}" -look_ahead 1 -look_ahead_depth 100 \
    -b:v "${BV}" -maxrate:v "${MRATE}" -bufsize:v "${BSIZE}" \
    -c:a "${ACODEC}" -ac:a:0 2 -b:a:0 "${ABIT}" -filter:a:0 "${AFLTR}" \
    #-ac:a:1 6 -b:a:1 256k \
       -c:s copy \
       -metadata title="${FNAME} | ${GRP}" \
       -metadata:s:v:0 title='AV1 encoding by nAV1s' \
    -metadata:s:a:0 title='English OPUS Stereo' \
    -metadata:s:s:0 title='English' \
    #-metadata:s:s:1 title='English (SDH)' \
    #-metadata:s:s:2 title='English (PGS)' \
       "${OFILE}"  && \
       ESIZE=$(du -BMB "${OFILE}" | cut -f -1) && \
       echo "Finished encoding ${FNAME}. Final file size: ${ESIZE}"; done



RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - TheDreadPirate - 2023-09-20

Can you do 2 pass encoding with HEVC QSV?


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - bitmap - 2023-09-20

Yup. I can test a bit later and provide a rough adaptation. You would essentially just change the video codec and add all the parameters related that you need for that to function properly (shouldn't be much other than the -c:v change but I need to look at the script again rather than just talking out my ass).


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - TheDreadPirate - 2023-09-20

Yes, please. I was all about 2-pass/VBR back in the day before NVENC/QSV was a thing.


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - bitmap - 2023-09-21

Okay, here we go @TheDreadPirate...

Made a few improvements and a lot of mistakes along the way. Testing consisted of six files, ranked from A-F based on bitrate over time and resolution (extremely subjective). Essentially: would I be satisfied with this media were I to have it in my collection. Spoilers, I do and, for the most part, the grades aren't good. I chose a variety of files to show how the new script works. *This test was completed using the hevc_qsv codec, CBR 4500 kbps (x2 for maxrate, x4 for bufsize), plus adaptive turned on.

Code:
user@server:encoding$ ls source_files/mixed_media/
total 7.7G
drwxrwxr-x 2 user group 4.0K Sep 21 10:52 .
drwxrwxr-x 3 user group 4.0K Sep 21 10:52 ..
-rw-rw-r-- 1 user group 4.1G Sep 21 02:03 A.27100kbps.AVC.21m40s.24FPS-1920x1080.mkv
-rw-r--r-- 1 user group 2.5G Sep 21 02:08 B.6385kbps.VP9.55m11s.30FPS-3840x2160.mkv
-rw-r--r-- 1 user group 484M Sep 21 02:08 C.1236kbps.VP9.54m40s.30FPS-1280x720.mkv
-rw-rw-r-- 1 user group 274M Sep 21 02:08 D.707kbps.AVC.54m5s.30FPS-640x480.mp4
-rw-r--r-- 1 user group 119M Sep 21 02:08 F.304kbps.VP9.54m29s.30FPS-468x360.mkv
-rw-rw-r-- 1 user group 194M Sep 21 02:00 F.482kbps.HEVC.56m2s.24FPS-640x480.mkv

They go from very high bitrate to very low bitrate. The revised script handles files in this way:

  1. Set your options. Easily available user-set options are: adaptive bitrate, QSV device, audio codec (encode), video codec (encode), bitrate reduction factor (percentage), bitrate floor (kbps), paths, streams, desired CBR, output file extension, primary audio stream bitrate, and video encoder preset. Note that many other options can be set, but some may cause unexpected behavior (e.g., CLEAN or AFLTR) and others may break the script entirely (e.g., setting audio or sub streams that do not exist in target file sets). Many of the parameters are optional, but until I get a way to un-scriptify this project, you just have a delete what you don't want.

  2. Determine if adaptive bit rate is enabled. If so, use ffprobe (must be in PATH) to determine bitrate ($FFVR bps --> $CKVR kbps). Note that this works with MOST files. The ffprobe command used here works even with files that store this in the main header of the file (e.g., older HEVC MKVs or poorly encoded files), but many will return the overall bitrate, not just video bitrate. I recommend taking this into account when deciding on $VMIN as well as $REDX and accounting for the possibility of audio being included in the value returned.

  3. If the media's bitrate falls below $VMIN, set the adaptive bitrate to the measured bitrate of the original media. If the media's bitrate exceeds the user-specified maximum desired video bitrate ($VRATE), set the bitrate for
    encoding to $VRATE. You can do large batches, ensuring crap-quality files are adapted and kept near original bitrate while larger files are reduced to your desired size/quality profile based on the guard rails that you set.

  4. Solidify the encoding options and run through ffmpeg with the first pass using ONLY video (you don't need two-pass audio). Verify that existing options map or refer to the correct data in the correct order, uncomment any mappings for streams needed in your encode, and remove any lines, maps, or metadata not necessary to complete the encoding process. Understand that the wider net you cast, the more opportunity for error presents itself, particularly when running batch operations. This is also where you should set any metadata you want present. You can review metadata with ffprobe and/or mediainfo.

  5. Pass one feeds into pass two, which maps all the other streams requested and finishes the process, then loops back until no more media is found.

Here's the script in action. I can't figure out how to suppress the libva output...if anybody knows how, let me know...

Code:
Attempting to find adaptive bit rate for mixed media...
Bit rate over specified limit, reverting to 4500 kbps...
Beginning first encoding pass for A.27100kbps.AVC.21m40s.24FPS-1920x1080. Starting file size: 4402MB...
[...]
    frame=31187 fps=179 q=-0.0 Lsize=  603953kB time=00:21:40.59 bitrate=3804.1kbits/s speed=7.47x   
First pass complete, beginning second encoding pass...
[...]
    frame=31187 fps=163 q=-0.0 Lsize=  631850kB time=00:21:40.75 bitrate=3979.3kbits/s speed=6.78x   
Finished encoding A.27100kbps.AVC.21m40s.24FPS-1920x1080. Final file size: 648MB
***
Attempting to find adaptive bit rate for mixed media...
Bit rate over specified limit, reverting to 4500 kbps...
Beginning first encoding pass for B.6385kbps.VP9.55m11s.30FPS-3840x2160. Starting file size: 2644MB...
[...]
    frame=99354 fps= 69 q=-0.0 Lsize= 1786053kB time=00:55:11.66 bitrate=4418.1kbits/s speed=2.31x   
First pass complete, beginning second encoding pass...
[...]
    frame=99354 fps= 66 q=-0.0 Lsize= 1865920kB time=00:55:11.82 bitrate=4615.5kbits/s speed=2.19x   
Finished encoding B.6385kbps.VP9.55m11s.30FPS-3840x2160. Final file size: 1911MB
***
Attempting to find adaptive bit rate for mixed media...
Bit rate will be reduced to 90% of original...
Bit rate set for encoding: 1112.62 kbps...
Beginning first encoding pass for C.1236kbps.VP9.54m40s.30FPS-1280x720. Starting file size: 507MB...
[...]
    frame=98308 fps=387 q=-0.0 Lsize=  429457kB time=00:54:40.07 bitrate=1072.6kbits/s speed=12.9x   
First pass complete, beginning second encoding pass...
[...]
    frame=98308 fps=359 q=-0.0 Lsize=  479925kB time=00:54:40.20 bitrate=1198.6kbits/s speed=  12x   
Finished encoding C.1236kbps.VP9.54m40s.30FPS-1280x720. Final file size: 492MB
***
Attempting to find adaptive bit rate for mixed media...
Bit rate will be reduced to 90% of original...
Bit rate set for encoding: 636.508 kbps...
Beginning first encoding pass for D.707kbps.AVC.54m5s.30FPS-640x480. Starting file size: 287MB...
[...]
    frame=97269 fps=711 q=-0.0 Lsize=  242347kB time=00:54:05.40 bitrate= 611.7kbits/s speed=23.7x   
First pass complete, beginning second encoding pass...
[...]
    frame=97269 fps=629 q=-0.0 Lsize=  293114kB time=00:54:05.63 bitrate= 739.8kbits/s speed=  21x   
Finished encoding D.707kbps.AVC.54m5s.30FPS-640x480. Final file size: 301MB
***
Attempting to find adaptive bit rate for mixed media...
Bit rate too low, not reducing further...
Bit rate set for encoding: 303.592 kbps...
Beginning first encoding pass for F.304kbps.VP9.54m29s.30FPS-468x360. Starting file size: 125MB...
[...]
    frame=97994 fps=988 q=-0.0 Lsize=  114260kB time=00:54:29.59 bitrate= 286.3kbits/s speed=  33x   
First pass complete, beginning second encoding pass...
[...]
    frame=97994 fps=774 q=-0.0 Lsize=  166591kB time=00:54:29.74 bitrate= 417.4kbits/s speed=25.8x   
Finished encoding F.304kbps.VP9.54m29s.30FPS-468x360. Final file size: 171MB
***
Attempting to find adaptive bit rate for mixed media...
Bit rate too low, not reducing further...
Bit rate set for encoding: 482.033 kbps...
Beginning first encoding pass for F.482kbps.HEVC.56m2s.24FPS-640x480. Starting file size: 203MB...
[...]
    frame=78235 fps=641 q=-0.0 Lsize=  194150kB time=00:56:02.08 bitrate= 473.1kbits/s speed=27.6x   
First pass complete, beginning second encoding pass...
[...]
    frame=78235 fps=562 q=-0.0 Lsize=  237283kB time=00:56:02.08 bitrate= 578.2kbits/s speed=24.1x   
Finished encoding F.482kbps.HEVC.56m2s.24FPS-640x480. Final file size: 243MB
***

Minimal informational output that delays slightly for readability. Here's the end result of the same files as above:

Code:
user@server:encoding$ ls batch_output/hevc_qsv/
total 3.6G
drwxrwxr-x 2 user group 4.0K Sep 21 12:07  .
drwxrwxr-x 3 user group 4.0K Sep 21 03:01  ..
-rw-rw-r-- 1 user group 618M Sep 21 11:00 'A.27100kbps.AVC.21m40s.24FPS-1920x1080-[AV1.OPUS.2.0].mkv'
-rw-rw-r-- 1 user group 1.8G Sep 21 11:49 'B.6385kbps.VP9.55m11s.30FPS-3840x2160-[AV1.OPUS.2.0].mkv'
-rw-rw-r-- 1 user group 469M Sep 21 11:58 'C.1236kbps.VP9.54m40s.30FPS-1280x720-[AV1.OPUS.2.0].mkv'
-rw-rw-r-- 1 user group 287M Sep 21 12:03 'D.707kbps.AVC.54m5s.30FPS-640x480-[AV1.OPUS.2.0].mkv'
-rw-rw-r-- 1 user group 163M Sep 21 12:07 'F.304kbps.VP9.54m29s.30FPS-468x360-[AV1.OPUS.2.0].mkv'
-rw-rw-r-- 1 user group 232M Sep 21 12:11 'F.482kbps.HEVC.56m2s.24FPS-640x480-[AV1.OPUS.2.0].mkv'

And now the script. I'm probably close to the text limit...

Code:
# Adaptive two-pass for HEVC_QSV

ADPT=1 && \ # set whether to use adaptive bit rate
DEV="/dev/dri/renderD129" && \
ACODEC="libopus" && \
VCODEC="hevc_qsv" && \
REDX="90" && \ # percentage of original
VMIN=500 && \ # minimum acceptable video bitrate (do not go below)
CLEAN=".m[kp][4v]" && \ # removes extensions and other extraneous filename info
IPATH="/home/bitmap/testbed/encoding/source_files/mixed_media" && \ # input path
OPATH="/home/bitmap/testbed/encoding/batch_output/hevc_qsv" && \ # output path
PRAUD="0" && \ # primary audio stream index
SEAUD="" && \
PRSUB="0?" && \ # primary subtitle stream index
SESUB="" && \
TRSUB="" && \
VRATE="4500" && \ # desired video bitrate
VMAX="9000" && \ # maximum desired video bitrate
VBUF="18000" && \ # video buffer size
PRESET="slower" && \ # encoder preset
ABIT="192k" && \ # default audio bitrate
AFLTR="pan=stereo|FL<FC+0.30*FL+0.30*BL|FR<FC+0.30*FR+0.30*BR" && \
EXT="mkv" && \ # output file extension
QUAL="WEBRip" && \ # quality -- only used for file naming
shopt -s globstar && \
clear && \
# start it up -- use extreme caution editing below this comment
BV="${VRATE}k" && \ # set fallbacks
MRATE="${VMAX}k" && \
BSIZE="${VBUF}k" && \
for MEDIA in "${IPATH}"/**/*.m[kp][4v]; do
    # reset flags
    ENCD=0
    ROVER=0
    RUNDER=0
    if [[ $ADPT == 1 ]]; then
        printf "Attempting to find adaptive bit rate for mixed media" && \
        printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
        sleep 0.5 && printf "\n" && \
        # ffprobe to check existing bitrate
        FFVR=$(ffprobe -v error -select_streams v:0 -show_entries format=bit_rate -of default=nw=1:nk=1 "${MEDIA}") && \
        if [[ $FFVR != "N/A" ]]; then
            KBVR=$(awk "BEGIN { print $FFVR*0.001 }") && \ # extract bitrate as kbps
            ROVER=$(awk "BEGIN { print ($KBVR > $VRATE) }") && \ # check if bitrate over desired
            RUNDR=$(awk "BEGIN { print ($KBVR < $VMIN) }") # check if bitrate under min
            if [[ $RUNDER == 1 ]]; then
                RDXD=0.001 && \ # set encode bitrate to 100% if under min
                ENCD=1 # go ahead with modified encoding settings
                printf "Bit rate too low, not reducing further" && \
                printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
                sleep 0.5 && printf "\n"
            elif [[ $ROVER == 1 ]]; then
                printf "Bit rate over specified limit, reverting to %s kbps" "${VRATE}" && \
                printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
                sleep 0.5 && printf "\n"
            else
                RDXD=$(awk "BEGIN { print $REDX/100000 }") && \
                ENCD=1 && \
                printf "Bit rate will be reduced to %s%% of original" "${REDX}" && \
                printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
                sleep 0.5 && printf "\n"
            fi
            INVR=$(awk "BEGIN { print $FFVR*$RDXD }") && \
            if [[ $ENCD == 1 ]]; then
            printf "Bit rate set for encoding: %s kbps" "${INVR}" && \
                printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
                sleep 0.5 && printf "\n"
            MCON=$(awk "BEGIN { print $INVR*2 }") && \
            BCON=$(awk "BEGIN { print $INVR*4 }") && \
            BV="${INVR}k" && \
            MRATE="${MCON}k" && \
            BSIZE="${BCON}k" && \
            ABIT="128k"
            fi
        else
            printf "FFprobe could not identify a bit rate, falling back to %s kbps" "${VRATE}" && \
            printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
            sleep 0.5 && printf "\n" && \
        fi
    else
        echo "Video bit rate for all session files locked at %s kbps" "${VRATE}" && \
        printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
        sleep 0.5 && printf "\n" && \
    fi
    ISIZE=$(du -BMB "${MEDIA}" | cut -f -1) && \
    FNAME=$(basename "${MEDIA%${CLEAN}}") && \
    OFILE="${OPATH}/${FNAME}-[AV1.OPUS.2.0].${EXT}" && \
    printf "Beginning first encoding pass for %s. Starting file size: %s" "${FNAME}" "${ISIZE}" && \
    printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
    sleep 0.5 && printf "\n" && \
    ffmpeg -y -hide_banner -loglevel warning -v quiet -stats -qsv_device "${DEV}" \
    -i "${MEDIA}" -pass 1 \
    -map_metadata 0 -map 0:v:0 \
    -c:v "${VCODEC}" -preset "${PRESET}" \
    -b:v "${BV}" -maxrate:v "${MRATE}" -bufsize:v "${BSIZE}" \
    -an -sn \
    "${OFILE}" && \
    printf "First pass complete, beginning second encoding pass" && \
    printf "." && sleep 0.5 && printf "." && sleep 0.5 && printf "." && \
    sleep 0.5 && printf "\n" && \
    ffmpeg -y -hide_banner -loglevel warning -v quiet -stats -qsv_device "${DEV}" \
    -i "${MEDIA}" -pass 2 \
    -map_metadata 0 -map 0:v:0 \
    -map 0:a:"${PRAUD}" \
    #-map 0:a:"${PRAUD}" \
    #-map 0:a:"${SEAUD}" \
    #-map 0:a \
    -map 0:s:"${PRSUB}" \
    #-map 0:s:"${SESUB}" \
    #-map 0:s:"${TRSUB}" \
    #-map 0:s \
    #-map 0:t? \
    -c:v "${VCODEC}" -preset "${PRESET}" \
    #-extbrc 1 -look_ahead 1 -look_ahead_depth 100 \ # should work, haven't tested
    -b:v "${BV}" -maxrate:v "${MRATE}" -bufsize:v "${BSIZE}" \
-c:a "${ACODEC}" -ac:a:0 2 -b:a:0 "${ABIT}" -filter:a:0 "${AFLTR}" \
#-ac:a:1 6 -b:a:1 256k \
  -c:s copy \
  -metadata title="${FNAME} | ${GRP}" \
  -metadata:s:v:0 title='Fill in the Blank' \
    -metadata:s:a:0 title='English OPUS Stereo' \
    -metadata:s:s:0 title='English' \
    #-metadata:s:s:1 title='English (SDH)' \
    #-metadata:s:s:2 title='English (PGS)' \
  "${OFILE}"  && \
  ESIZE=$(du -BMB "${OFILE}" | cut -f -1) && \
  printf "Finished encoding %s. Final file size: %s" "${FNAME}" "${ESIZE}"; done


Hope this helps along the way!

EDIT: Missed a bug. Bitrate was not calculated correctly because I was relying on an unset variable. Caught that in a new terminal today. Fixed it in the above. Have better ideas of how to handle a few things as well. Will start working on an actual script and program version soon. This is absolutely just hacked together to paste into your terminal.


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - bitmap - 2023-10-03

Oh my god. I've been so wrong about how I've gone about this. I had a fundamental misunderstanding about how to use MAP as well as how to create multiple copies of single streams. I also figured out how to get around a lot of the errors I encountered with different video streams, explicit mappings, etc...

I need to provide an update and a better script. The one I've thrown up there is good theory, but garbage on the ffmpeg side...sorry...


RE: Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...) - manu98 - 2023-10-04

I have an issue with my ffmpeg command.
When using preset 5, I am unable to seek through the movie in jellyfin. It only shows 5 seconds in length, which extends while playing.

But when using preset 6 or higher, the movie plays perfectly fine.
Here is the command:
Code:
ffmpeg -i in.mkv -map 0 -c:s copy -c:v libsvtav1 -pix_fmt yuv420p10le -svtav1-params tune=0:irefresh-type=2:enable-overlays=1:scd=1 -g 240 -movflags +faststart -preset 5  -ac 6 -c:a libopus -b:a 256k -crf 30 out.mkv

I tried both jellyfin-ffmpeg and the latest build from github.
Does anyone have suggestions? I would be very thankful.