Atm a 10 bit h.265 in NUT container is the best of what I've tried. Depending on how popular ur channel is, rather whether you'll get vp9 encoding or not, u should scale to 2k or 4k. But ur doing 4k anyways so its irrelevant u should get good treatment on youtube. So give it a test at:
10 bit h.265 NUT (.nut) @ 4k .wav audio
use a perceptually lossless setting, so fairly high bitrate but not insane. an h.265 crf of 19 is my recommendation, no more no less.
alternatively as a lossey option to save on filesize u can do h.265 10 bit .ts with opus. You'll get a nicer kick with .wav, assuming the audio is any good to begin with. Even just transcoding to wav and using that is gonna show some difference when uploaded to youtube.
If you go mkv as your container, expect problems @ 10 bit. Similar with other containers...they don't work over 8 bit or have very poor results on youtube.
If file size is irrelevant you could just do an image format stored in an mkv. 16 bit png or higher in an mkv..it's insane but its pretty. They've uploaded fine in the past, haven't done it recently though so do a small test first. If I had to choose between the three for just image quality I'd go .ts, for some reason that container looks really nice on youtube. Containers influence the final picture quality on youtube...cause reasons.
Further Information for ffmpeg rendering (quickstart guide):
****Generally in my case things are pumped out as an image strip from whatever video editor I use; use a high bit depth. Then in the folder the pictures are stored in, where the starting picture is called 21.png and the subsequent images are sequentially increasing by 1..22.png...23.png etc; Further naming convention data can be found on the wiki. Sometimes commands start at 0 sometimes at 1, so I suggest you specify the start_number so you don't have to care****
ffmpeg -framerate 24000/1001 -start_number 21 -i %d.png -vf "scale=3840:-1" -c:v libx265 -crf 19 -pix_fmt yuv422p10le 4k_output.nut
After ffmpeg is called up each argument is started with a "-" known as a flag, with the exception of the output.* Where -framerate is expressed as an integer (24, 30, 60 etc); -start_number just sets the start point as noted above; -i signals the input you are gonna do stuff to. In this case it's an image strip so %d is the generic callup for image strips, the .png is the format of the image (most formats supported, .exr may have problems); -vf "scale" is included incase you need to upscale/downscale (you don't tho), in ur case take it out, if you are dealing with jpg you either use -2 or specify the height numerically i.e. "3840:2160". Alternatively you can specify the algorithm used for the scale with -vf scale=3840x2160:flags=lanczos -v 40; where you change lanczos with whatever you want...'neighbour'...'experimental' by default its bicubic which is fine; specified is libx265 which is just h.265, libx264 is h.264 etc; crf 19 is the quality, for h.265 you would use a value +2 higher than the value u use for h.264 (i.e. 17 crf in h.264 = 19 crf in h.265), the value shown is generally labelled as 'perceptually lossless'; pix_fmt specified the bit depth...in this case we want yuv422p10le for 10 bit, yuv480p for 8 bit, yuv422p12le for 12 bit (requires custom build), rgb48be for 16 bit png etc; the output is custom named, in this case I chose "4k_output". Note: the file extension of output/input are labelled accordingly, .nut = NUT. You can stick a '-preset veryfast' or '-preset slow' after you specify h.265, depending on the file size desired otherwise it'll do the normal speed/size.
I generally recommend a separate command for combining ur audio with video to prevent problems.
ffmpeg -i 4k_output.nut -i audio.wav -c copy final_upload.nut
Where '-c copy' is a command that signals to copy the audio and video streams over so that no re-encoding takes place. You should check the streams information which will be displayed right after you initiate the command and right before it goes frame by frame encoding, this will tell you what is happening to each stream. Look for (copy) to be displayed to confirm where no re-encoding takes place.
For opus you can convert your audio using:
ffmpeg -i audio.wav -c:a libopus -b:a 510000 opus.ogg
Where -b specifies the bit rate, with opus u need to write it out,but otherwise u could write 510k I believe for aac and others. Although I would use 384k for aac. And someone reading this would suggest 128k...but whatever. So this would be 3 separate commands, but if you are confident in your computer (and luck) you could do it all in a single command. I'll leave that to you to figure out, just mix and match in an order where reading it left to right makes sense. And for transport stream just use .ts instead of .nut. It's the same command as with .nut, just .ts can't store lossless audio.
You can preview your video using ffplay (included in same folder as ffmpeg.exe), .nut doesn't play well in many video players.
ffplay final_upload.nut -fs
The format is the same between ffplay and ffmpeg, but the -i is optional, and the inputs are specified at the end of the argument...i always do -fs at the end where its used tho. -fs just signals full screen; it'll fix any zoomed display problems, alternatively you can specify the window size with the scale filter.
i.e.) ffplay -vf "scale=1280:-1,unsharp=lx=10:ly=10:la=2.0" final_upload.nut
filters and effects can be tested in ffplay before rendering, similarly you can play ur entire image sequence in ffplay if ur computer can handle it just re-arrange the commands given and realize you don't have to specify codecs. I really like unsharp so I included it here, it functions as a sharpener when you use positive values.
Worth noting to anyone using command prompt: control+c (3 times in a row is hardstop) will stop any command including ffplay. The 'Pause' key will pause any render operation; control+z will resume any paused operation.
If you wanted to store the images in an mkv video you could use the ffmpeg command originally specified but include a '-c:v copy' and change the output file extension to .mkv. If successful (check the streams as mentioned above) this will ignore all ur video codec settings and simply copy it into the container. ffmpeg reads left to right, so generally you can just specify your copy command anywhere after the input, certain things are better specified before the input but you can research that yourself. If dealing with video you can use '-r' instead of '-framerate', be careful where you place your framerate though. Note 1's and l's look the same but they can make or break ur command. If you have multiple streams in ur video (subfiles, information, fonts, multiple audio/video) specify '-map 0' after the input and this will bring all the streams over to the output. If things are specified, presets will be applied based on stuff like output container chosen. So if I could do ffmpeg -i input.avi output.mkv; and this will automatically carry over the single best quality audio and video stream, re-encoding them to vorbis and h.264. The copy commands in general are (the newer notation):
-c:v copy
-c:a copy
-c:s copy
-c copy
Where v is video streams, a is audio stream, s is subtitle stream. c copy is a short form for saying copy ALL streams. If you specify -map 0 and need to re-encode video you would do -c:a copy and -c:s copy in ur command. Otherwise using -c copy you'd overwrite any video codec settings applied in most cases.
As well be careful not to include spaces where there shouldn't be any. If doing spaces in your notation enclose the argument with a " ", same with input and output names. i.e. -i "my video".mkv. I included quotes with the filter command up top just cause I generally put spaces after each filter (separated by a ,) and elsewhere just to see better etc. And make sure when your command is running through the frames its not displaying a "frames dropped" display...that would be bad, make sure fps is in the right place. it should display the speed while it's working and that's it.
If you need more help see the official documentation. If you can't read it, it's kinda hard, use https://amiaopensource.github.io/ffmprovisr/ first then reference the command information on the docs/wiki. The wiki pages, where offered, are easier to understand.