user2927: I need to validate if a video file (HEVC encoded) is or is not an HDR video. I know that there are many HDR standards, but I did not find a way to identify it using mediainfo or ffprobe.
The need is because I have an API that receives several video profiles (different bitrates, dimensions and codecs) for a single video, which are used to deliver to users the best match based on their devices and connection speed. So now I want to allow them to select HDR profile but to achieve this I need first to validate the ingest files.
Do you know how to handle this?

user33107: Checking color_primaries is the right approach. I use ffprobe to get the JSON output. Then you can parse the JSON output instead of searching for a string in the normal output.
$ ffprobe -v error -show_streams -select_streams v:0 -of json -i test.mp4
{
    "streams": [
        {
            "index": 0,
            "codec_name": "hevc",
            "codec_long_name": "H.265 / HEVC (High Efficiency Video Coding)",
            "color_transfer": "arib-std-b67",
            "color_primaries": "bt2020",
            "refs": 1,
            // …
       }
    ]
}


user2927: I've found how to get this information from color primaries attribute. Considering color primaries BT.2020 as a HDR video.
mediainfo video.mp4 --Inform="Video;%colour_primaries%"

In this example above, if the return of the command is BT.2020 so I consider the video as HDR. 
Otherwise SDR.

user26140: Well, and yeah, all answers are wrong here. HDR is only the new transfer function, PQ or HLG. So that means you need to look into that, PQ is SMPTE 2084 and HLG is ARIB STD-B67.
Yes, 8 bit file tagged as PQ will be played as HDR.
Yes, 10 bit files tagged as BT.2020 transfer are SDR, because BT.2020 transfer is the same as BT.709 and BT.601. Moreover Rec. BT.2020 is SDR only spec., HDR was defined in BT.2100. Master files of Hollywood used 10 bit in SDR for a long time.
Yes, you need to color manage BT.2020 primaries to your primaries. Just as before PAL primaries were supposed to be color managed to what display primaries are.
Yes, it is 0.0001 to 10000 nits, not 0.001 to 4000 in PQ. Yes, 65 Y' is actually 0.00005 nits and 64 Y' is 0.000000 nits. Black body.
Yes, BT.2390 EETF dynamical tone mapper is mandatory unless the master display is full 10000 nits.
Yes, almost all movies are inside P3-D65 inside BT.2020, only Planet Earth 2 and Matrix are not and some others. That changed in 2022, since Netflix allowed to use BT.2020 primaries for their JPEG2000 masters.
Yes, film cameras supported HDR back in 1970s and they are nowadays converted to PQ and image format .pcd (Photo CD) supported HDR and WCG.

user37209: This answer relies on but simplifies the answer by Валерий Заподовников who seems to know his stuff.
ffprobe -v quiet -show_streams -select_streams v:0 video.mp4 | grep ^color_transfer=

IF color_transfer EQUALS arib-std-b67 OR smpte2084 THEN the video is HDR

user26600: Assuming your file is ${F}, the below is an efficient means I have been able to create:
COLORS=$(ffprobe -show_streams -v error "${F}" |egrep "^color_transfer|^color_space=|^color_primaries=" |head -3)
for C in $COLORS; do
        if [[ "$C" = "color_space="* ]]; then
                COLORSPACE=${C##*=}
        elif [[ "$C" = "color_transfer="* ]]; then
                COLORTRANSFER=${C##*=}
        elif [[ "$C" = "color_primaries="* ]]; then
                COLORPRIMARIES=${C##*=}
        fi      
done    
if [ "${COLORSPACE}" = "bt2020nc" ] && [ "${COLORTRANSFER}" = "smpte2084" ] && [ "${COLORPRIMARIES}" = "bt2020" ]; then 
        echo ${F}
fi

I use this inside a looping function to know when to use https://github.com/Fmstrat/ffmkv to create an SDR version of a video on one of the presets.

2927: <p>I need to validate if a video file (HEVC encoded) is or is not an HDR video. I know that there are many HDR standards, but I did not find a way to identify it using <code>mediainfo</code> or <code>ffprobe</code>.</p>

<p>The need is because I have an API that receives several video profiles (different bitrates, dimensions and codecs) for a single video, which are used to deliver to users the best match based on their devices and connection speed. So now I want to allow them to select HDR profile but to achieve this I need first to validate the ingest files.</p>

<p>Do you know how to handle this?</p>
 33107: <p>Checking <code>color_primaries</code> is the right approach. I use <code>ffprobe</code> to get the JSON output. Then you can parse the JSON output instead of searching for a string in the normal output.</p>
<pre><code>$ ffprobe -v error -show_streams -select_streams v:0 -of json -i test.mp4
{
    &quot;streams&quot;: [
        {
            &quot;index&quot;: 0,
            &quot;codec_name&quot;: &quot;hevc&quot;,
            &quot;codec_long_name&quot;: &quot;H.265 / HEVC (High Efficiency Video Coding)&quot;,
            &quot;color_transfer&quot;: &quot;arib-std-b67&quot;,
            &quot;color_primaries&quot;: &quot;bt2020&quot;,
            &quot;refs&quot;: 1,
            // …
       }
    ]
}
</code></pre>
 2927: <p>I've found how to get this information from color primaries attribute. Considering color primaries BT.2020 as a HDR video.</p>

<pre><code>mediainfo video.mp4 --Inform="Video;%colour_primaries%"
</code></pre>

<p>In this example above, if the return of the command is <strong>BT.2020</strong> so I consider the video as HDR. 
Otherwise SDR.</p>
 26140: <p>Well, and yeah, all answers are wrong here. HDR is only the new transfer function, PQ or HLG. So that means you need to look into that, PQ is SMPTE 2084 and HLG is ARIB STD-B67.</p>
<p>Yes, 8 bit file tagged as PQ will be played as HDR.</p>
<p>Yes, 10 bit files tagged as BT.2020 transfer are SDR, because BT.2020 transfer is the same as BT.709 and BT.601. Moreover Rec. BT.2020 is SDR only spec., HDR was defined in BT.2100. Master files of Hollywood used 10 bit in SDR for a long time.</p>
<p>Yes, you need to color manage BT.2020 primaries to your primaries. Just as before PAL primaries were supposed to be color managed to what display primaries are.</p>
<p>Yes, it is 0.0001 to 10000 nits, not 0.001 to 4000 in PQ. Yes, 65 Y' is actually 0.00005 nits and 64 Y' is 0.000000 nits. Black body.</p>
<p>Yes, BT.2390 EETF dynamical tone mapper is mandatory unless the master display is full 10000 nits.</p>
<p>Yes, almost all movies are inside P3-D65 inside BT.2020, only Planet Earth 2 and Matrix are not and some others. That changed in 2022, since Netflix allowed to use BT.2020 primaries for their JPEG2000 masters.</p>
<p>Yes, film cameras supported HDR back in 1970s and they are nowadays converted to PQ and image format .pcd (Photo CD) supported HDR and WCG.</p>
 37209: <p>This answer relies on but simplifies the answer by Валерий Заподовников who seems to know his stuff.</p>
<pre><code>ffprobe -v quiet -show_streams -select_streams v:0 video.mp4 | grep ^color_transfer=
</code></pre>
<p>IF color_transfer EQUALS <code>arib-std-b67</code> OR <code>smpte2084</code> THEN the video is HDR</p>
 26600: <p>Assuming your file is <code>${F}</code>, the below is an efficient means I have been able to create:</p>

<pre><code>COLORS=$(ffprobe -show_streams -v error "${F}" |egrep "^color_transfer|^color_space=|^color_primaries=" |head -3)
for C in $COLORS; do
        if [[ "$C" = "color_space="* ]]; then
                COLORSPACE=${C##*=}
        elif [[ "$C" = "color_transfer="* ]]; then
                COLORTRANSFER=${C##*=}
        elif [[ "$C" = "color_primaries="* ]]; then
                COLORPRIMARIES=${C##*=}
        fi      
done    
if [ "${COLORSPACE}" = "bt2020nc" ] &amp;&amp; [ "${COLORTRANSFER}" = "smpte2084" ] &amp;&amp; [ "${COLORPRIMARIES}" = "bt2020" ]; then 
        echo ${F}
fi
</code></pre>

<p>I use this inside a looping function to know when to use <a href="https://github.com/Fmstrat/ffmkv" rel="noreferrer">https://github.com/Fmstrat/ffmkv</a> to create an SDR version of a video on one of the presets.</p>
