I am launching a series of videos to Youtube. These videos have a black background and lots of colored gradient changes. 4k, 60fps.

Unfortunately this picture style is causing terrible banding issues in H264.

Accordingly I want to upload my videos to Youtube in 10bit - is this possible?

If so, which codec would you recommend?

  • 2
    Why not give it a test? YouTube is a bit of a black box, the best answer might be found by experimentation
    – stib
    Commented Mar 6, 2019 at 20:50
  • I can tell you definitively that YouTube does accept 10-bit, as 10-bit is a prerequisite for HDR (different can of worms, but do-able). Whether or not it'll fix your banding problem is a different matter. Like Stib said, try a test upload. Keep it short so you can iterate quickly. Also, check the results on a few different screens, because the banding could be happening there. If you can do H.265 fast enough, that's a good candidate. It's pretty slow on macs at the moment. NVIDIA GPUs can supposedly handle it pretty well, though. Commented Mar 6, 2019 at 22:34

2 Answers 2


Youtube converts files in two main containers, flv and MPEG-4 AVC (or h.264). For everything below 720p, youtube usually switches to flv, for everything above it uses h.264.

Your file will get compressed by youtube's own bitrate indeed, but upping the bitrate in the encoder will still give you vast improvements in image-quality. You need to keep in mind that the file will get compressed about three times in your case. When the camera records the image, it compresses it according to the filetype and codec it is set to. Then, after editing, the file will get rendered and compressed furthermore. And at last, youtube will also convert and compress your file.

So, to minimize loss of quality, it's worth considering upping your bitrate of the encoder you use (Adobe Media Encoder, Premiere, After Effects, etc.), since this is the only thing you could change as of now. A bitrate of 25-30 should be what you want. If file-size is not to be considered, I would even recommend pumping it up to about 50. Also, make sure to tick the "use maximum render-quality" when you're using adobe's encoders.

The only limit youtube has for uploading is 124gb file-size if I remember correctly. It's a value videos should never reach tho.

  • 2
    This doesn't actually answer the question, maybe you could improve it by addressing the issue of bit depth, and codec compatibility
    – stib
    Commented Mar 6, 2019 at 20:48

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.

  • Thank you for sharing. Do you do the transcoding in ffmpeg? If so, could you share your recipe for H265 (NUT and ts)?
    – T1000
    Commented Mar 9, 2019 at 9:03
  • I updated the answer. Upload some samples and compare the results. Tossing '-movflags +faststart' in ur command is recommended by youtube but I saw no difference in upload or performance and it only increases render times. I could be wrong though, I didn't test that part much. '-vframes 500' after your input will limit the output to the first 500 frames assuming your input is an image strip.
    – kite
    Commented Mar 12, 2019 at 5:13
  • Thank you. I've been trying to get h265 to work, however the output seems to have dropped frames and is very laggy. I uploaded it to Vimeo, and same result. The original footage is 10bit DNXHR HQX and it transcodes to h264 without problem.
    – T1000
    Commented Mar 15, 2019 at 9:05
  • I'm not familiar with DNXHR HQX you might need an additional library to convert properly or maybe it's just your command. When you say dropped frames is this after uploading to youtube or before? Confirm if there is any problems in ffplay. If its saying dropped frames while its rendering via ffmpeg, next to the speed, then its dropping frames. This is likely due to your command, write it out and let me see or take a screenshot of it in action so I can see the error messages if any. If in doubt convert a bit of your video to an image strip and confirm that this works and then backtrack.
    – kite
    Commented Mar 15, 2019 at 14:57
  • If its during the ffmpeg operation that frames are being dropped you can try adding "-f rawvideo" after the input. This tells FFmpeg to pass the video stream as raw video data without remuxing. This step is what ensures the survival of embedded metadata versus a standard rewrap. i.e. ffmpeg -i input -f rawvideo -c copy output should not have any dropped frames. h.264 10 bit is possible too in ffmpeg. All the info for that is in the answer alrdy, just libx264 and ~17 crf imo.
    – kite
    Commented Mar 16, 2019 at 9:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.