HaveAGitGat / Tdarr_Plugins

Tdarr Plugins
GNU General Public License v3.0
140 stars 158 forks source link

Using a flow to convert large video files to AV1 causes the output file to always be of terrible, poor quality #677

Open ampersandru opened 4 months ago

ampersandru commented 4 months ago

Describe the bug

Similar to what this person reported a few months ago: https://www.reddit.com/r/Tdarr/comments/1b98ooj/convert_to_av1/

The flow I set up will use my A310 for AV1 hardware encoding, but the output file is always 4-10% the size of the original file and is extremely low-quality, no matter what I set the FFmpeg Quality to (I could set it to 0, which should be lossless and it would still come out an extremely low-quality and blurry video, and the exact same size.)

I updated to 2.21.01 today, but happened with the previous version also

Here is the flow

{
  "name": "MyAV1",
  "description": "MyAV1",
  "tags": "",
  "flowPlugins": [
    {
      "name": "Input File",
      "sourceRepo": "Community",
      "pluginName": "inputFile",
      "version": "1.0.0",
      "id": "_YTuyCZg3",
      "position": {
        "x": 924.360747488415,
        "y": -283.6943731031359
      }
    },
    {
      "name": "Replace Original File",
      "sourceRepo": "Community",
      "pluginName": "replaceOriginalFile",
      "version": "1.0.0",
      "id": "RQzydYbay",
      "position": {
        "x": 1132.6414874261588,
        "y": 138.5703698939895
      }
    },
    {
      "name": "Begin Command",
      "sourceRepo": "Community",
      "pluginName": "ffmpegCommandStart",
      "version": "1.0.0",
      "id": "gDJQmuCwi",
      "position": {
        "x": 924.956026653017,
        "y": -96.03592710368505
      }
    },
    {
      "name": "Execute",
      "sourceRepo": "Community",
      "pluginName": "ffmpegCommandExecute",
      "version": "1.0.0",
      "id": "24zCqexcm",
      "position": {
        "x": 1131.3591217741448,
        "y": 58.106944889712395
      }
    },
    {
      "name": "Remove Subtitles",
      "sourceRepo": "Community",
      "pluginName": "ffmpegCommandRemoveSubtitles",
      "version": "1.0.0",
      "id": "Gci51ubzk",
      "position": {
        "x": 925.9315131773437,
        "y": 28.901107198115795
      }
    },
    {
      "name": "Set Video Encoder",
      "sourceRepo": "Community",
      "pluginName": "ffmpegCommandSetVideoEncoder",
      "version": "1.0.0",
      "inputsDB": {
        "outputCodec": "av1",
        "hardwareType": "auto",
        "ffmpegQuality": "7",
        "ffmpegPreset": "medium",
        "forceEncoding": "false",
        "hardwareDecoding": "false",
        "hardwareEncoding": "true"
      },
      "id": "GQuxlzj_K",
      "position": {
        "x": 925.3194666151709,
        "y": -31.02872189648903
      }
    },
    {
      "name": "Check File Extension",
      "sourceRepo": "Community",
      "pluginName": "checkFileExtension",
      "version": "1.0.0",
      "id": "sUmHxRwVP",
      "position": {
        "x": 923.8164123032839,
        "y": -223.9283297038153
      }
    },
    {
      "name": "Check Video Codec",
      "sourceRepo": "Community",
      "pluginName": "checkVideoCodec",
      "version": "1.0.0",
      "inputsDB": {
        "codec": "av1"
      },
      "id": "pHUJmlX44",
      "position": {
        "x": 899.7964443936237,
        "y": -163.80600029372036
      }
    },
    {
      "name": "Set Container",
      "sourceRepo": "Community",
      "pluginName": "ffmpegCommandSetContainer",
      "version": "1.0.0",
      "id": "g2V2Q89K_",
      "position": {
        "x": 926.1341026254609,
        "y": 96.54120353302125
      },
      "inputsDB": {
        "container": "mp4"
      }
    },
    {
      "name": "Custom Arguments",
      "sourceRepo": "Community",
      "pluginName": "ffmpegCommandCustomArguments",
      "version": "1.0.0",
      "inputsDB": {
        "inputArguments": "",
        "outputArguments": ""
      },
      "id": "UikfZ4t5H",
      "position": {
        "x": 1131.6175693990558,
        "y": -21.351149619454816
      }
    }
  ],
  "flowEdges": [
    {
      "source": "gDJQmuCwi",
      "sourceHandle": "1",
      "target": "GQuxlzj_K",
      "targetHandle": null,
      "id": "kaeqFngHv"
    },
    {
      "source": "GQuxlzj_K",
      "sourceHandle": "1",
      "target": "Gci51ubzk",
      "targetHandle": null,
      "id": "IissnDSku"
    },
    {
      "source": "_YTuyCZg3",
      "sourceHandle": "1",
      "target": "sUmHxRwVP",
      "targetHandle": null,
      "id": "ohtDv23Li"
    },
    {
      "source": "24zCqexcm",
      "sourceHandle": "1",
      "target": "RQzydYbay",
      "targetHandle": null,
      "id": "RbkTtMjZ3"
    },
    {
      "source": "sUmHxRwVP",
      "sourceHandle": "1",
      "target": "pHUJmlX44",
      "targetHandle": null,
      "id": "zE_gF88_b"
    },
    {
      "source": "pHUJmlX44",
      "sourceHandle": "2",
      "target": "gDJQmuCwi",
      "targetHandle": null,
      "id": "T598G-hMq"
    },
    {
      "source": "Gci51ubzk",
      "sourceHandle": "1",
      "target": "g2V2Q89K_",
      "targetHandle": null,
      "id": "xLii_YWnS"
    },
    {
      "source": "UikfZ4t5H",
      "sourceHandle": "1",
      "target": "24zCqexcm",
      "targetHandle": null,
      "id": "s6aJhy39c"
    },
    {
      "source": "g2V2Q89K_",
      "sourceHandle": "1",
      "target": "UikfZ4t5H",
      "targetHandle": null,
      "id": "DpDn7qjID"
    }
  ]
}

To Reproduce Steps to reproduce the behavior: Use the above flow to encode any file into AV1 with an Arc card

Expected behavior File size and quality should change based on the chosen ffmpeg quality.

Screenshots image image

OS: Unraid OS version: 6.12.10 with custom kernel: https://github.com/thor2002ro/unraid_kernel/releases CPU: Intel Core i5-1235U GPU: Intel Arc A310 Docker version: 2.21.01 Device model: Ugreen DXP6800 Pro Browser/OS: Chrome

dennix85 commented 4 months ago

Use handbrake, as ffmpeg doesn't yield for me personally good quality too, tried also many combinations of commands as well, also make sure your vpl and driver binaries updated as Intel states them self too, av1 control is locked behind vpl, without it only basic stuff will work. You can create a preset in the gui, and use that preset in tdarr, or if you know your way around the cli commands use these :) Or use the boosh av1 plugin, you can find that one in the Plugin sections of the official tdarr discord. Works very well, works by the logic of 50% of bitrate for the output in av1 % is adjustable. For more control over the process I suggest u use handbrake.

michio884 commented 3 months ago

There is currently a bug that uses the -qp parameter with intel QSV but it has to use -global_quality instead, thus always resulting in shit quality when using QSV in a flow. It's more or less a one liner to fix in the plugin or use vaapi instead for now.

MNTLe-DMGD commented 2 months ago

I've been working on this issue, and have come up with a reasonable fix.

Here's my Flow: https://pastebin.com/qFxd3wqd

If you look at the "Added AV1 Config" node, and the "Set Video Encoder" node, you will see, I've added multiple redundant options for -global_quality:v and -crf. Which one is doing the work, I don't know, but adjusting them all to be the value you want, seems to solve the problem. Output is clean enough at about 24. Just remember to change all of them to the same value. You could probably remove the -crf option, I only threw it in there as a hail mary pass.

Disregard the rest of the junk I've got in the flow, it's still a work in progress.

tomerh2001 commented 2 months ago

I've been working on this issue, and have come up with a reasonable fix.

Here's my Flow: https://pastebin.com/qFxd3wqd

If you look at the "Added AV1 Config" node, and the "Set Video Encoder" node, you will see, I've added multiple redundant options for -global_quality:v and -crf. Which one is doing the work, I don't know, but adjusting them all to be the value you want, seems to solve the problem. Output is clean enough at about 24. Just remember to change all of them to the same value. You could probably remove the -crf option, I only threw it in there as a hail mary pass.

Disregard the rest of the junk I've got in the flow, it's still a work in progress.

Hey, man, I noticed you included your Sonarr API key in the flow, you might want to remove it.

Unrelated - Can I use that flow to encode my library to AV1 using my nvidia GPU?

MNTLe-DMGD commented 2 months ago

I've been working on this issue, and have come up with a reasonable fix. Here's my Flow: https://pastebin.com/qFxd3wqd If you look at the "Added AV1 Config" node, and the "Set Video Encoder" node, you will see, I've added multiple redundant options for -global_quality:v and -crf. Which one is doing the work, I don't know, but adjusting them all to be the value you want, seems to solve the problem. Output is clean enough at about 24. Just remember to change all of them to the same value. You could probably remove the -crf option, I only threw it in there as a hail mary pass. Disregard the rest of the junk I've got in the flow, it's still a work in progress.

Hey, man, I noticed you included your Sonarr API key in the flow, you might want to remove it.

Unrelated - Can I use that flow to encode my library to AV1 using my nvidia GPU?

Woops! Missed that, thanks. Fixed now, I can't delete the paste, so regenerated the API key. Thanks for pointing out my screw up!

As for your question about using the nVidia card and my flow - I don't think it would work, purely because most of the ffmpeg flags are specific to the Intel ARC series of cards. I did work on the nVidia settings at one point, but I gifted the card when I got the ARC card for my Plex Server. It took me ages to figure out the ARC ffmpeg flags, because they're not well documented. As far as I know, the "Set Video Encoder" flow node should work with nVidia cards. The AV1 and nVidia card is listed there, but I don't know how good it will be.

If I get my hands on another nVidia card that is capable of AV1, I will post an update. Best of luck mate!

Nielmor commented 1 month ago

Trying to use your flow above and have encountered an issue that I am trying to work around but I can't get my head around.

Some information on my setup Tdarr is running as a container on TrueNas. The system only has an Intel ARC GPU

https://pastebin.com/0Q8EdGxY

On line 45 it looks like ffmpeg is attempting to use nvenc to decode the source file, however there is no nvidia media encoder available so it is failing. Most of my media is already HEVC however some is still varios other codecs, do you have a change that I can make to force it to use QSV for the decoding as well?

dennix85 commented 1 month ago

If using in docker enviroment, it doesnt play nicely with the arc gpu as of yet. In an LXC container or baremetall they play nicely, the ffmpeg flow plugin has still some issues, but with custom arguments or with handbrake it works correctly I have mine gpu's running under windows atm, for dovi compatibility but im testing it in linux enviroments right now too, Ubuntu, Arch, Fedora have all needed packages build in their repositories (latest versions only, older ones you need to install and compile them manually)

Nielmor commented 1 month ago

It is a docker on TrueNAS that I am using. If I could at least tell it to not use nvenc that would likely solve the issue. I tried editing the configuration for ffmpeg in the docker but when I try disable nvenc I get an error that the option was not found A migration to a VM is simply not an option right now as I have plex running and playing nicely with the ARC GPU as a docker, I don't really want to migrate that at this stage to a VM.

dennix85 commented 1 month ago

I have no experience with truenas but if it is possible to run an LXC container on it, you can use the gpu in docker as well in LXC simultaneously.

AV1 needs VPL libraries which are not correctly present in the official docker container. If you really must use docker you can alternativle build your own container. You can do it with a dockerfile if you have the knowledge, otherwise you can create a base container, execute in to it, and build it from the command line.

Nielmor commented 1 month ago

No option of LXC containers as of yet, it is on the roadmap however. I might need to look at using handbrake instead of ffmpeg if there is no other solution.

AV1 needs VPL libraries which are not correctly present in the official docker container.

CPU Transcoding works, I tested and had a look at some files, the quality is about as good as the source file and I confirmed with VLC the output file is AV1. The CPU transcode file is also about 1/3 the size of a HEVC file as well.

MNTLe-DMGD commented 1 month ago

Trying to use your flow above and have encountered an issue that I am trying to work around but I can't get my head around.

Some information on my setup Tdarr is running as a container on TrueNas. The system only has an Intel ARC GPU

https://pastebin.com/0Q8EdGxY

On line 45 it looks like ffmpeg is attempting to use nvenc to decode the source file, however there is no nvidia media encoder available so it is failing. Most of my media is already HEVC however some is still varios other codecs, do you have a change that I can make to force it to use QSV for the decoding as well?

ENCODER : Lavc60.3.100 hevc_nvenc

Line 45 is only telling you the way the source video was encoded. It's saying that the source video is encoded using hevc_nvenc. Just below that on line 54, you can see:

ENCODER : Lavc60.3.100 ac3

Indicating that the source audio was encoded using ac3.

FFMPEG is being told to convert it to AV1 on line 58:

2024-09-28T15:14:45.815Z Stream #0:0 -> #0:0 (hevc (native) -> av1 (av1_qsv))

See the input is hevc and the output is av1_qsv

2024-09-28T15:14:45.815Z Stream #0:1 -> #0:2 (ac3 (native) -> opus (libopus))

And the audio to libopus, on line 60.

If it's of any help, here is my docker config that I've setup with the Intel ARC A310: https://pastebin.com/geYq6rpw

Nielmor commented 1 month ago

ENCODER : Lavc60.3.100 hevc_nvenc

Line 45 is only telling you the way the source video was encoded. It's saying that the source video is encoded using hevc_nvenc. Just below that on line 54, you can see:

100% accurate, file would have been encoded on tdarr using either an nVidia GT1050 in my old NAS or the 3060TI in my desktop which I previously had configured as a node.

If it's of any help, here is my docker config that I've setup with the Intel ARC A310: https://pastebin.com/geYq6rpw

Currently not of any help as the custom app function is blocked on TrueNAS. This is because I am running Beta1 of the 24.10 release, it might be available in RC1 due next week and I can try get this running. I just migrated to TrueNAS less than a month ago so I went for the beta so I didn't need to migrate my containers later with the docker migration happening.

Does anyone know if the docker has Handbrake already installed in it? I might try switching over to Handbrake, worst case scenario an official handbrake docker image is available and I can install that to give it a try.

dennix85 commented 1 month ago

Yes handbrake is built in There are also flow and custom Plugins You can also make a preset with a gui version And import it to tdarr or go with cli commands if you know you're way around handbrake

Nielmor commented 1 month ago

Yes handbrake is built in There are also flow and custom Plugins

Perfect, hopefully it doesn't have the same issues but I guess I will find out in time.

You can also make a preset with a gui version And import it to tdarr or go with cli commands if you know you're way around handbrake

The plan was to create and test a preset and then import it into tdarr before creating a flow to use the preset for transcoding.

taltamir commented 4 days ago

this might be related to #707 set video does not set a crf value, and uses invalid syntax for presets. currently the workaround I found is to use custom ffmpeg command instead.

MNTLe-DMGD commented 3 days ago

I've updated my flow: https://pastebin.com/TJfWHycH

I've added fixes for common issues with certain file types and codecs that are incompatible with the Intel ARC GPU decoder/encoder hardware. I've also added fixes for common ffmpeg/container issues.

I'm pretty crap at notations, but I've added a few comments to explain what each part is doing and why.

I've also broken down the ffmpeg command so that it is easier to understand and tweak to your liking.

I hope someone else finds it useful. :)