• Login
  • Register
  • Login Register
    Login
    Username/Email:
    Password:
    Or login with a social network below
  • Forum
  • Website
  • GitHub
  • Status
  • Translation
  • Features
  • Team
  • Rules
  • Help
  • Feeds
User Links
  • Login
  • Register
  • Login Register
    Login
    Username/Email:
    Password:
    Or login with a social network below

    Useful Links Forum Website GitHub Status Translation Features Team Rules Help Feeds
    Jellyfin Forum Off Topic General Discussion Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...)

    Pages (12): « Previous 1 … 3 4 5 6 7 … 12 Next »
     

     
    • 0 Vote(s) - 0 Average

    Encoding Discussion Megathread (ffmpeg, Handbrake, AV1, etc...)

    Bring your resources, guides, questions, suggestions, cluelessness. All is welcome.
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #41
    2023-09-16, 09:36 PM (This post was last modified: 2023-09-16, 09:39 PM by TheDreadPirate. Edited 2 times in total.)
    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"
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    bitmap
    Offline

    Community Moderator

    Posts: 766
    Threads: 9
    Joined: 2023 Jul
    Reputation: 24
    #42
    2023-09-16, 10:07 PM
    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
    Jellyfin 10.10.7 LSIO Docker | Ubuntu 24.04 LTS | i7-13700K | Arc A380 6 GB | 64 GB RAM | 79 TB Storage

    [Image: AIL4fc84QG6uSnTDEZiCCtosg7uAA8x9j1myFaFs...qL0Q=w2400]
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #43
    2023-09-17, 06:44 AM
    (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!

       
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    bitmap
    Offline

    Community Moderator

    Posts: 766
    Threads: 9
    Joined: 2023 Jul
    Reputation: 24
    #44
    2023-09-20, 07:24 AM
    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
    Jellyfin 10.10.7 LSIO Docker | Ubuntu 24.04 LTS | i7-13700K | Arc A380 6 GB | 64 GB RAM | 79 TB Storage

    [Image: AIL4fc84QG6uSnTDEZiCCtosg7uAA8x9j1myFaFs...qL0Q=w2400]
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #45
    2023-09-20, 01:59 PM (This post was last modified: 2023-09-20, 01:59 PM by TheDreadPirate.)
    Can you do 2 pass encoding with HEVC QSV?
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    bitmap
    Offline

    Community Moderator

    Posts: 766
    Threads: 9
    Joined: 2023 Jul
    Reputation: 24
    #46
    2023-09-20, 02:53 PM
    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).
    Jellyfin 10.10.7 LSIO Docker | Ubuntu 24.04 LTS | i7-13700K | Arc A380 6 GB | 64 GB RAM | 79 TB Storage

    [Image: AIL4fc84QG6uSnTDEZiCCtosg7uAA8x9j1myFaFs...qL0Q=w2400]
    TheDreadPirate
    Offline

    Community Moderator

    Posts: 15,375
    Threads: 10
    Joined: 2023 Jun
    Reputation: 460
    Country:United States
    #47
    2023-09-20, 03:09 PM
    Yes, please. I was all about 2-pass/VBR back in the day before NVENC/QSV was a thing.
    Jellyfin 10.10.7 (Docker)
    Ubuntu 24.04.2 LTS w/HWE
    Intel i3 12100
    Intel Arc A380
    OS drive - SK Hynix P41 1TB
    Storage
        4x WD Red Pro 6TB CMR in RAIDZ1
    [Image: GitHub%20Sponsors-grey?logo=github]
    bitmap
    Offline

    Community Moderator

    Posts: 766
    Threads: 9
    Joined: 2023 Jul
    Reputation: 24
    #48
    2023-09-21, 07:20 PM (This post was last modified: 2023-09-22, 06:45 PM by bitmap. Edited 2 times in total.)
    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.
    Jellyfin 10.10.7 LSIO Docker | Ubuntu 24.04 LTS | i7-13700K | Arc A380 6 GB | 64 GB RAM | 79 TB Storage

    [Image: AIL4fc84QG6uSnTDEZiCCtosg7uAA8x9j1myFaFs...qL0Q=w2400]
    bitmap
    Offline

    Community Moderator

    Posts: 766
    Threads: 9
    Joined: 2023 Jul
    Reputation: 24
    #49
    2023-10-03, 06:35 PM
    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...
    Jellyfin 10.10.7 LSIO Docker | Ubuntu 24.04 LTS | i7-13700K | Arc A380 6 GB | 64 GB RAM | 79 TB Storage

    [Image: AIL4fc84QG6uSnTDEZiCCtosg7uAA8x9j1myFaFs...qL0Q=w2400]
    manu98
    Offline

    Junior Member

    Posts: 3
    Threads: 0
    Joined: 2023 Oct
    Reputation: 0
    #50
    2023-10-04, 10:35 PM
    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.
    Pages (12): « Previous 1 … 3 4 5 6 7 … 12 Next »
     

    « Next Oldest | Next Newest »

    Users browsing this thread: 1 Guest(s)


    • View a Printable Version
    • Subscribe to this thread
    Forum Jump:

    Home · Team · Help · Contact
    © Designed by D&D - Powered by MyBB
    L


    Jellyfin

    The Free Software Media System

    Linear Mode
    Threaded Mode