├── .gitignore ├── mimes.js ├── codecs-video-vp9.js ├── index.css ├── codecs-video-hevc.js ├── codecs-audio.js ├── index.html ├── codecs-video-avc.js ├── codecs-video-av1.js ├── index.js ├── mediacapabilities.html ├── mediacapabilities.js └── codecs.js /.gitignore: -------------------------------------------------------------------------------- 1 | .* 2 | 3 | !.gitignore 4 | -------------------------------------------------------------------------------- /mimes.js: -------------------------------------------------------------------------------- 1 | var MIMES = [ 2 | "video/mp4", 3 | "video/3gpp", 4 | "video/3gpp2", 5 | "video/quicktime", 6 | "audio/mp4", 7 | "audio/3gpp", 8 | "audio/3gpp2", 9 | "application/mp4", 10 | "application/mp21", 11 | ]; 12 | -------------------------------------------------------------------------------- /codecs-video-vp9.js: -------------------------------------------------------------------------------- 1 | function getAllVP9Codecs() { 2 | // TODO generate all possible profiles 3 | // vp09...[.....] 4 | 5 | return [ 6 | { codec: "vp09.00.51.08.01.01.01.01.00", description: "VP9 YouTube 8K" }, 7 | { codec: "vp09.00.50.08", description: "VP9, Profile 0, Level 5, 8-bit"} 8 | ]; 9 | } -------------------------------------------------------------------------------- /index.css: -------------------------------------------------------------------------------- 1 | body { 2 | max-width: 800px; 3 | margin: auto; 4 | font-family: sans-serif; 5 | } 6 | 7 | table { 8 | border-collapse:collapse; 9 | width:100%; 10 | max-width:700px; 11 | min-width:400px; 12 | text-align:center; 13 | } 14 | 15 | table, th, td { 16 | border: 1px solid gray; 17 | } 18 | 19 | th, td { 20 | height: 24px; 21 | padding:4px; 22 | vertical-align:middle; 23 | } 24 | 25 | .ok { 26 | background-color: green; 27 | } 28 | 29 | .maybe { 30 | background-color: orange; 31 | } 32 | 33 | .fail { 34 | background-color: red; 35 | } 36 | -------------------------------------------------------------------------------- /codecs-video-hevc.js: -------------------------------------------------------------------------------- 1 | function getAllHEVCCodecs() 2 | { 3 | var HEVC_PROFILES_DESC = [ 4 | { profile_idc: 1, description: "Main" }, 5 | { profile_idc: 2, description: "Main 10"}, 6 | { profile_idc: 3, description: "Main Still Picture" }, 7 | { profile_idc: 4, description: "Range extensions profiles" }, 8 | { profile_idc: 5, description: "High throughput profiles" }, 9 | { profile_idc: 6, description: "Multiview Main profile" }, 10 | { profile_idc: 7, description: "Scalable Main profile" }, 11 | { profile_idc: 8, description: "3D Main profile" }, 12 | { profile_idc: 9, description: "Screen content coding extensions profiles" }, 13 | { profile_idc: 10, description: "Scalable format range extensions profile" }, 14 | ]; 15 | 16 | var HEVC_LEVELS = [ 10, 20, 21, 30, 31, 40, 41, 50, 51, 52, 60, 61, 62 ]; 17 | 18 | // TODO generate profiles 19 | 20 | return [ 21 | { codec: "hev1.1.6.L93.B0", description: "HEVC progressive, non-packed stream, Main Profile, Main Tier, Level 3.1"}, 22 | { codec: "hev1.2.4.L120.B0", description: "HEVC Main10 Profile, Main Tier, Level 4.0"} 23 | ]; 24 | } -------------------------------------------------------------------------------- /codecs-audio.js: -------------------------------------------------------------------------------- 1 | 2 | var AUDIO_CODECS = [ 3 | { codec: "mp4a.40", description: "MPEG-4 AAC"}, 4 | { codec: "mp4a.40.1", description: "MPEG-4 AAC Main"}, 5 | { codec: "mp4a.40.2", description: "MPEG-4 AAC-LC"}, 6 | { codec: "mp4a.40.3", description: "MPEG-4 AAC-SSR"}, 7 | { codec: "mp4a.40.4", description: "MPEG-4 AAC-LTP"}, 8 | { codec: "mp4a.40.5", description: "MPEG-4 AAC-SBR"}, 9 | { codec: "mp4a.40.6", description: "MPEG-4 AAC-Scalable"}, 10 | { codec: "mp4a.40.7", description: "MPEG-4 TWIN VQ"}, 11 | { codec: "mp4a.40.8", description: "MPEG-4 CELP"}, 12 | { codec: "mp4a.40.9", description: "MPEG-4 HVCX"}, 13 | { codec: "mp4a.40.12", description: "MPEG-4 TTSI"}, 14 | { codec: "mp4a.40.13", description: "MPEG-4 Main Synthetic"}, 15 | { codec: "mp4a.40.14", description: "MPEG-4 Wavetable Synthetis"}, 16 | { codec: "mp4a.40.15", description: "MPEG-4 General Midi"}, 17 | { codec: "mp4a.40.16", description: "MPEG-4 ALGO_SYNTH_AUDIO_FX"}, 18 | { codec: "mp4a.40.17", description: "MPEG-4 ER_AAC_LC"}, 19 | { codec: "mp4a.40.19", description: "MPEG-4 ER_AAC_LTP"}, 20 | { codec: "mp4a.40.20", description: "MPEG-4 ER_AAC_SCALABLE"}, 21 | { codec: "mp4a.40.21", description: "MPEG-4 ER_TWINVQ"}, 22 | { codec: "mp4a.40.22", description: "MPEG-4 ER_BSAC"}, 23 | { codec: "mp4a.40.23", description: "MPEG-4 ER_AAC_LD"}, 24 | { codec: "mp4a.40.24", description: "MPEG-4 ER_CELP"}, 25 | { codec: "mp4a.40.25", description: "MPEG-4 ER_HVXC"}, 26 | { codec: "mp4a.40.26", description: "MPEG-4 ER_HILN"}, 27 | { codec: "mp4a.40.27", description: "MPEG-4 ER_PARAMETRIC"}, 28 | { codec: "mp4a.40.28", description: "MPEG-4 SSC"}, 29 | { codec: "mp4a.40.29", description: "MPEG-4 AAC_PS"}, 30 | { codec: "mp4a.40.32", description: "MPEG-4 LAYER1"}, 31 | { codec: "mp4a.40.33", description: "MPEG-4 LAYER2"}, 32 | { codec: "mp4a.40.34", description: "MPEG-4 LAYER3"}, 33 | { codec: "mp4a.40.35", description: "MPEG-4 DST"}, 34 | { codec: "mp4a.40.36", description: "MPEG-4 ALS"}, 35 | { codec: "mp4a.66", description: "MPEG-2 AAC Main Profile"}, 36 | { codec: "mp4a.67", description: "MPEG-2 AAC Low Complexity Profile"}, 37 | { codec: "mp4a.68", description: "MPEG-2 AAC Scalable Sampling Rate Profile"}, 38 | { codec: "mp4a.69", description: "MPEG-2 Audio Part 3"}, 39 | { codec: "mp4a.6B", description: "MPEG-1 Part 3"}, 40 | { codec: ".mp3", description: "MPEG-1/2 Part 3 - QuickTime File Format"}, 41 | { codec: "mp3", description: "MPEG-1/2 Part 3 - QuickTime File Format"}, 42 | ]; 43 | 44 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Media MIME Support 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Support for ISOBMFF-based MIME types in Browsers

18 |

This page allows you to check if a given ISOBMFF-based MIME type is supported in your browser. Given the wide variety of ISOBMFF files, it is sometimes difficult to know in advance if a MIME type will be supported. This page shows test results using the HTMLMediaElement.canPlayType and MediaSource.isTypeSupported methods for various versions of ISOBMFF MIME types, in particular for codecs as registered on the MP4 Registration Authority.

19 |

You can check General MIME Types, General track codecs, Audio codecs and Video codecs, in particular all AVC profiles, AV1 profiles or other video codecs such as VP9, HEVC or test your own codec.

20 |
21 |
22 | 23 | 24 |
25 |
26 |
27 |
28 |

This other page is dedicated to testing the Media Capabilities API. 29 |

The code for this page is hosted on GitHub here. If you see any mistake, please file an issue or submit a pull request.

30 |
31 |
32 | 33 | 34 | -------------------------------------------------------------------------------- /codecs-video-avc.js: -------------------------------------------------------------------------------- 1 | function getAllAVCCodecs() 2 | { 3 | var AVC_PROFILES_DESC = [ 4 | //{ constrained_set0_flag: true }, 5 | //{ constrained_set1_flag: true }, 6 | //{ constrained_set2_flag: true }, 7 | { profile_idc: 66, description: "Baseline" }, 8 | { profile_idc: 66, description: "Constrained Baseline", constrained_set1_flag: true}, 9 | { profile_idc: 77, description: "Main" }, 10 | { profile_idc: 77, description: "Constrained Main", constrained_set1_flag: true}, 11 | { profile_idc: 88, description: "Extended" }, 12 | { profile_idc: 100, description: "High", constrained_set4_flag: false }, 13 | { profile_idc: 100, description: "High Progressive", constrained_set4_flag: true }, 14 | { profile_idc: 100, description: "Constrained High", constrained_set4_flag: true, constrained_set5_flag: true }, 15 | { profile_idc: 110, description: "High 10" }, 16 | { profile_idc: 110, description: "High 10 Intra", constrained_set3_flag: true }, 17 | { profile_idc: 122, description: "High 4:2:2" }, 18 | { profile_idc: 122, description: "High 4:2:2 Intra", constrained_set3_flag: true }, 19 | { profile_idc: 244, description: "High 4:4:4 Predictive" }, 20 | { profile_idc: 244, description: "High 4:4:4 Intra", constrained_set3_flag: true }, 21 | { profile_idc: 44, description: "CAVLC 4:4:4 Intra" } 22 | ]; 23 | 24 | var AVC_PROFILES_IDC = [ 66, 77, 88, 100, 110, 122, 244, 44]; 25 | var AVC_CONSTRAINTS = [ 0, 4, 8, 16, 32, 64, 128 ]; 26 | var AVC_LEVELS = [ 10, 11, 12, 13, 20, 21, 22, 30, 31, 32, 40, 41, 42, 50, 51, 52]; 27 | 28 | var sj, sk, sl; 29 | var mimes = []; 30 | for (var j in AVC_PROFILES_IDC) { 31 | var sj = AVC_PROFILES_IDC[j].toString(16); 32 | if (sj.length == 1) sj = "0"+sj; 33 | for (var k in AVC_CONSTRAINTS) { 34 | sk = AVC_CONSTRAINTS[k].toString(16); 35 | if (sk.length == 1) sk = "0"+sk; 36 | 37 | var desc = ""; 38 | for (i in AVC_PROFILES_DESC) { 39 | if (AVC_PROFILES_IDC[j] == AVC_PROFILES_DESC[i].profile_idc) { 40 | var c = ((AVC_PROFILES_DESC[i].constrained_set0_flag ? 1 : 0) << 7) | 41 | ((AVC_PROFILES_DESC[i].constrained_set1_flag ? 1 : 0) << 6) | 42 | ((AVC_PROFILES_DESC[i].constrained_set2_flag ? 1 : 0) << 5) | 43 | ((AVC_PROFILES_DESC[i].constrained_set3_flag ? 1 : 0) << 4) | 44 | ((AVC_PROFILES_DESC[i].constrained_set4_flag ? 1 : 0) << 3) | 45 | ((AVC_PROFILES_DESC[i].constrained_set5_flag ? 1 : 0) << 2); 46 | if (c === AVC_CONSTRAINTS[k]) { 47 | desc = AVC_PROFILES_DESC[i].description; 48 | break; 49 | } 50 | } 51 | } 52 | if (desc.length > 0) { 53 | for (var l in AVC_LEVELS) { 54 | sl = AVC_LEVELS[l].toString(16); 55 | if (sl.length == 1) sl = "0"+sl; 56 | mimes.push({ 57 | codec: 'avc1.'+sj+sk+sl, 58 | description: "AVC "+desc+" Level "+ AVC_LEVELS[l]/10 59 | }); 60 | } 61 | } 62 | } 63 | } 64 | return mimes; 65 | } -------------------------------------------------------------------------------- /codecs-video-av1.js: -------------------------------------------------------------------------------- 1 | function getAllAV1Codecs() 2 | { 3 | var PROFILES_VALUES = [ 0, 1, 2 ]; 4 | var PROFILES_NAMES = [ 'Main', 'High', 'Professional' ]; 5 | var LEVEL_VALUES = [ 0, 1, 2, 3, 6 | 4, 5, 6, 7, 7 | 8, 9, 10, 11, 8 | 12, 13, 14, 15, 9 | 16, 17, 18, 19, 10 | 20, 21, 22, 23, 11 | 31]; 12 | var LEVEL_NAMES = [ '2.0', '2.1', '2.2', '2.3', 13 | '3.0', '3.1', '3.2', '3.3', 14 | '4.0', '4.1', '4.2', '4.3', 15 | '5.0', '5.1', '5.2', '5.3', 16 | '6.0', '6.1', '6.2', '6.3', 17 | '7.0', '6.1', '7.2', '7.3', 18 | 'Max' ]; 19 | var TIER_VALUES = [ 'M', 'H' ]; 20 | var TIER_NAMES = [ 'Main', 'High' ]; 21 | var DEPTH_VALUES = [ 8, 10, 12]; 22 | var MONOCHROME_VALUES = [ null ];//, 0, 1 ]; 23 | var CHROMA_SUBSAMPLING_VALUES = [ '000', '001', '010', '011', '100', '101', '110', '111' ]; 24 | var COLOR_PRIMARIES_VALUES = [ 0, 1, 2];//, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; 25 | var TRANSER_CHARACTERISTICS_VALUES = [ 0, 1, 2];//, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; 26 | var MATRIX_COEFFICIENT_VALUES = [ 0, 1, 2];//, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; 27 | var VIDEO_FULL_RANGE_FLAG_VALUES = [ 0, 1 ]; 28 | 29 | var allValues = []; 30 | for (var profile in PROFILES_VALUES) { 31 | for (var level in LEVEL_VALUES) { 32 | var levelString = ''+LEVEL_VALUES[level]; 33 | if (levelString.length == 1) levelString = "0"+levelString; 34 | 35 | for (var tier in TIER_VALUES) { 36 | for (var depth in DEPTH_VALUES) { 37 | var depthString = ''+DEPTH_VALUES[depth]; 38 | if (depthString.length == 1) depthString = "0"+depthString; 39 | for (var mono in MONOCHROME_VALUES) { 40 | if (MONOCHROME_VALUES[mono]!= null) { 41 | for (var chroma in CHROMA_SUBSAMPLING_VALUES) { 42 | for (var colorPrimary in COLOR_PRIMARIES_VALUES) { 43 | for (var transfer in TRANSER_CHARACTERISTICS_VALUES) { 44 | for (var matrix in MATRIX_COEFFICIENT_VALUES) { 45 | for (var range in VIDEO_FULL_RANGE_FLAG_VALUES) { 46 | allValues.push({ 47 | codec: 'av01.'+PROFILES_VALUES[profile]+ 48 | '.'+levelString+ 49 | ''+TIER_VALUES[tier]+ 50 | '.'+depthString+ 51 | '.'+MONOCHROME_VALUES[mono]+ 52 | '.'+CHROMA_SUBSAMPLING_VALUES[chroma]+ 53 | '.'+COLOR_PRIMARIES_VALUES[colorPrimary]+ 54 | '.'+TRANSER_CHARACTERISTICS_VALUES[transfer]+ 55 | '.'+MATRIX_COEFFICIENT_VALUES[matrix]+ 56 | '.'+VIDEO_FULL_RANGE_FLAG_VALUES[range], 57 | description: '' 58 | }); 59 | } 60 | } 61 | } 62 | } 63 | } 64 | } else { 65 | allValues.push({ 66 | codec: 'av01.'+PROFILES_VALUES[profile]+ 67 | '.'+levelString+ 68 | ''+TIER_VALUES[tier]+ 69 | '.'+depthString, 70 | description: 'AV1 '+PROFILES_NAMES[profile]+' Profile, level '+LEVEL_NAMES[level]+', '+TIER_NAMES[tier]+ ' tier, '+DEPTH_VALUES[depth]+' bits' 71 | }); 72 | } 73 | } 74 | } 75 | } 76 | } 77 | } 78 | return allValues; 79 | } -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | function addMimeChecks(table,mime,desc) { 2 | var video = document.createElement("video"); 3 | var tr; 4 | var video_result; 5 | var mediasource_result; 6 | video_result = video.canPlayType(mime); 7 | try { 8 | mediasource_result = MediaSource.isTypeSupported(mime); 9 | } catch (e) { 10 | mediasource_result = e.message; 11 | } 12 | tr = document.createElement("tr"); 13 | tr.innerHTML = ""+desc+""+mime+""+(video_result.length > 0 ? video_result : "no")+""+mediasource_result+""; 14 | table.appendChild(tr); 15 | } 16 | 17 | function createTableHeader(div) { 18 | var t = document.createElement("table"); 19 | div.appendChild(t); 20 | var content = ""; 21 | content += ""; 22 | content += "Description"; 23 | content += "MIME"; 24 | content += "HTMLMediaElement.canPlayType"; 25 | content += "MediaSource.isTypeSupported"; 26 | content += ""; 27 | t.innerHTML = content; 28 | return t; 29 | } 30 | 31 | function addParagraph(div, id, msg) { 32 | var p = document.createElement("p"); 33 | p.setAttribute("id", id); 34 | p.innerHTML = msg; 35 | div.appendChild(p); 36 | } 37 | 38 | window.onload = function() { 39 | var results = document.getElementById("results"); 40 | var table, i; 41 | 42 | addParagraph(results, "general_mimes", "Checking support for MIME types registered in RFC6381"); 43 | table = createTableHeader(results); 44 | for(i in MIMES) { 45 | addMimeChecks(table,MIMES[i], ""); 46 | } 47 | addParagraph(results, "general_codecs", "Checking support for codecs registered in MP4RA"); 48 | table = createTableHeader(results); 49 | for(i in CODECS) { 50 | var codec = CODECS[i].codec; 51 | addMimeChecks(table,'video/mp4; codecs="'+codec+'"', CODECS[i].description); 52 | } 53 | addParagraph(results, "audio_codecs", "Checking support for audio codecs with parameters"); 54 | table = createTableHeader(results); 55 | for(i in AUDIO_CODECS) { 56 | var codec = AUDIO_CODECS[i].codec; 57 | addMimeChecks(table, 'audio/mp4; codecs="'+codec+'"', AUDIO_CODECS[i].description); 58 | } 59 | addParagraph(results, "avc_codecs", "Checking support for AVC codecs with parameters"); 60 | table = createTableHeader(results); 61 | addChecks(getAllAVCCodecs, addMimeChecks, table); 62 | 63 | addParagraph(results, "av1_codecs", "Checking support for AV1 codecs with parameters"); 64 | table = createTableHeader(results); 65 | addChecks(getAllAV1Codecs, addMimeChecks, table); 66 | 67 | addParagraph(results, "other_video_codecs", "Checking support for other codecs such as VP9, HEVC"); 68 | table = createTableHeader(results); 69 | addChecks(getAllVP9Codecs, addMimeChecks, table); 70 | addChecks(getAllHEVCCodecs, addMimeChecks, table); 71 | }; 72 | 73 | function addOwnTest(id, v) { 74 | var results = document.getElementById(id); 75 | results.innerHTML=''; 76 | table = createTableHeader(results); 77 | addMimeChecks(table, 'video/mp4; codecs="'+v+'"', ""); 78 | } 79 | 80 | function addChecks(getAllCodecs, add,table) 81 | { 82 | getAllCodecs().forEach(e => add(table, 'video/mp4; codecs="'+e.codec+'"', e.description)); 83 | } 84 | 85 | -------------------------------------------------------------------------------- /mediacapabilities.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Testing Media Capabilities 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

Testing Media Capabilities

14 |

This page is dedicated to testing the Media Capabilities API. Checkout this other page, if you're interested in ISOBMFF MIME types.

15 | 16 |
17 | Configuration options: 18 | 19 | 23 |
24 | 25 | 28 |
29 | 30 | 36 |
37 | 38 | 44 |
45 | 46 | 52 |
53 | 54 | 61 |
62 | 63 | 64 |
65 | 66 | 72 |
73 | 74 | 80 |
81 | 82 | 88 |
89 |
90 |

Media Capabilities Results:

91 | 92 |
93 | 94 |
95 | 96 |
97 |
98 | 99 |
100 |

The following image shows the results of queries to the Media Capabilities API, for some resolutions from 0x0 to the selected max resolution. Each rectangle represents a given resolution. The rectangle color is the RGB combination of: Supported, PowerEfficient, and Smooth. Hover over a rectangle to see the details of the results.

101 | 102 | 103 | -------------------------------------------------------------------------------- /mediacapabilities.js: -------------------------------------------------------------------------------- 1 | function addCodecsGroup(select, desc, getter) { 2 | if(getter) { 3 | var group = document.createElement("optgroup"); 4 | group.label = desc; 5 | select.appendChild(group); 6 | getter().forEach(function(e) { 7 | var opt = document.createElement("option"); 8 | opt.value = e.codec; 9 | opt.innerHTML = e.description + " ("+e.codec+")"; 10 | group.appendChild(opt); 11 | }); 12 | } 13 | } 14 | 15 | window.onload = function() { 16 | const sourceselector = document.getElementById("source-select"); 17 | const mimeselector = document.getElementById("mime-select"); 18 | const codecsselector = document.getElementById("codecs-select"); 19 | addCodecsGroup(codecsselector, "VP9 codecs", getAllVP9Codecs); 20 | addCodecsGroup(codecsselector, "AV1 codecs", getAllAV1Codecs); 21 | addCodecsGroup(codecsselector, "AVC codecs", getAllAVCCodecs); 22 | addCodecsGroup(codecsselector, "AVC codecs", getAllHEVCCodecs); 23 | const fpsselector = document.getElementById("fps-select"); 24 | const bitrateeselector = document.getElementById("bitrate-select"); 25 | const dimensionselector = document.getElementById("maxdimension-select"); 26 | const hdrselector = document.getElementById("hdr-select"); 27 | const colorselector = document.getElementById("color-select"); 28 | const tranferselector = document.getElementById("transfer-select"); 29 | const alphaCheckbox = document.getElementById("alpha"); 30 | const supportedCheckbox = document.getElementById("supported"); 31 | const smoothCheckbox = document.getElementById("smooth"); 32 | const powerEfficientCheckbox = document.getElementById("powerEfficient"); 33 | 34 | const ctx = {}; 35 | ctx.svg = document.getElementById('s'); 36 | 37 | function run() { 38 | const sourcevalue = sourceselector.value; 39 | const mime = mimeselector.value; 40 | const codecs = codecsselector.value; 41 | const fps = fpsselector.value; 42 | const bitrate = bitrateeselector.value; 43 | const dimension = dimensionselector.value; 44 | const hdrvalue = hdrselector.value; 45 | const colorvalue = colorselector.value; 46 | const transfervalue = tranferselector.value; 47 | 48 | ctx.width_min = 0; 49 | ctx.height_min = 0; 50 | ctx.width_max = +(dimension.substring(0, dimension.indexOf('x'))); 51 | ctx.height_max = +(dimension.substring(dimension.indexOf('x')+1, dimension.length)); 52 | ctx.stepw = ctx.width_max >> 4; 53 | ctx.steph = ctx.height_max >> 4; 54 | ctx.svg.setAttribute("viewBox","0 0 "+ctx.width_max+" "+ctx.height_max); 55 | while (ctx.svg.firstChild) { 56 | ctx.svg.removeChild(ctx.svg.firstChild); 57 | } 58 | 59 | for (let w = ctx.stepw; w <= ctx.width_max; w+=ctx.stepw) { 60 | for (let h = ctx.steph; h <= ctx.height_max; h+=ctx.steph) { 61 | testConfig(sourcevalue, mime, codecs, 62 | w, h, bitrate, fps, 63 | alphaCheckbox.checked, 64 | hdrvalue, colorvalue, transfervalue, 65 | ctx, 66 | supportedCheckbox.checked, 67 | powerEfficient.checked, 68 | smoothCheckbox.checked); 69 | } 70 | } 71 | } 72 | const runbutton = document.getElementById('runbutton'); 73 | runbutton.onclick = run; 74 | } 75 | 76 | function testConfig(sourcevalue, mime, codecs, vw, vh, b, fps, 77 | alpha, hdr, color, transfer, 78 | ctx, wantsSupported, wantsPowerEfficient, wantsSmooth) { 79 | const fullmime = mime+';codecs='+codecs; 80 | //const fullmime = 'video/mp4;codecs=avc1.640028'; 81 | let configuration = { 82 | type: sourcevalue, 83 | video: { 84 | contentType: fullmime, 85 | width: vw, 86 | height: vh, 87 | bitrate: b, 88 | framerate: fps, 89 | } 90 | }; 91 | configuration.video.hasAlphaChannel = alpha; 92 | if (hdr) configuration.video.hdrMetadataType = hdr; 93 | if (color) configuration.video.colorGamut = color; 94 | if (transfer) configuration.video.transferFunction = transfer; 95 | 96 | navigator.mediaCapabilities.decodingInfo(configuration) 97 | .then((result) => { 98 | drawValue(ctx, configuration, vw, vh, 99 | result.supported && wantsSupported, 100 | result.powerEfficient && wantsPowerEfficient, 101 | result.smooth && wantsSmooth); 102 | }) 103 | .catch((err) => { 104 | console.error(err, ' caused decodingInfo to reject'); 105 | }); 106 | } 107 | 108 | function drawValue(ctx, configuration, w, h, supported, powerEfficient, smooth) { 109 | const scalew = ctx.stepw*.9; 110 | const offsetw = ctx.stepw*.05-ctx.stepw; 111 | const scaleh = ctx.steph*.9; 112 | const offseth = ctx.steph*.05-ctx.steph; 113 | let rect = document.createElementNS("http://www.w3.org/2000/svg","rect"); 114 | rect.setAttribute("x",w+offsetw+""); 115 | rect.setAttribute("y",h+offseth+""); 116 | rect.setAttribute("width",scalew+""); 117 | rect.setAttribute("height",scaleh+""); 118 | rect.setAttribute("fill", "rgb("+supported*255+","+powerEfficient*255+","+smooth*255+")"); 119 | let tooltip = document.createElementNS("http://www.w3.org/2000/svg","title"); 120 | let tooltipString = (""+w+"x"+h+":"); 121 | tooltipString += ("\nsupported:"+supported); 122 | tooltipString += ("\npowerEfficient:"+powerEfficient); 123 | tooltipString += ("\nsmooth:"+smooth); 124 | tooltipString += ("\nconfiguration:"+JSON.stringify(configuration)); 125 | tooltip.textContent = tooltipString; 126 | rect.appendChild(tooltip); 127 | ctx.svg.appendChild(rect); 128 | } -------------------------------------------------------------------------------- /codecs.js: -------------------------------------------------------------------------------- 1 | var CODECS = [ 2 | { codec: "3gvo", description: "3GPP Video Orientation", type: "Metadata" }, 3 | { codec: "a3d1", description: "Multiview Video Coding", type: "Video" }, 4 | { codec: "a3d2", description: "Multiview Video Coding", type: "Video" }, 5 | { codec: "a3d3", description: "Multiview Video Coding", type: "Video" }, 6 | { codec: "a3d4", description: "Multiview Video Coding", type: "Video" }, 7 | { codec: "a3ds", description: "Auro-Cx 3D audio", type: "Audio" }, 8 | { codec: "ac-3", description: "AC-3 audio", type: "Audio" }, 9 | { codec: "ac-4", description: "AC-4 audio", type: "Audio" }, 10 | { codec: "alac", description: "Apple lossless audio codec", type: "Audio" }, 11 | { codec: "alaw", description: "a-Law", type: "Audio" }, 12 | { codec: "av01", description: "AV1 video", type: "Video" }, 13 | { codec: "avc1", description: "Advanced Video Coding", type: "Video" }, 14 | { codec: "avc2", description: "Advanced Video Coding", type: "Video" }, 15 | { codec: "avc3", description: "Advanced Video Coding", type: "Video" }, 16 | { codec: "avc4", description: "Advanced Video Coding", type: "Video" }, 17 | { codec: "avcp", description: "Advanced Video Coding Parameters", type: "Video" }, 18 | { codec: "dra1", description: "DRA Audio", type: "Audio" }, 19 | { codec: "drac", description: "Dirac Video Coder", type: "Video" }, 20 | { codec: "dts+", description: "Enhancement layer for DTS layered audio", type: "Audio" }, 21 | { codec: "dts-", description: "Dependent base layer for DTS layered audio", type: "Audio" }, 22 | { codec: "dtsc", description: "DTS Coherent Acoustics audio", type: "Audio" }, 23 | { codec: "dtse", description: "DTS Express low bit rate audio, also known as DTS LBR", type: "Audio" }, 24 | { codec: "dtsh", description: "DTS-HD High Resolution Audio", type: "Audio" }, 25 | { codec: "dtsl", description: "DTS-HD Master Audio", type: "Audio" }, 26 | { codec: "dtsx", description: "DTS:X", type: "Audio" }, 27 | { codec: "dvav", description: "AVC-based “Dolby Vision”", type: "Video" }, 28 | { codec: "dvhe", description: "HEVC-based “Dolby Vision”", type: "Video" }, 29 | { codec: "ec-3", description: "Enhanced AC-3 audio", type: "Audio" }, 30 | { codec: "enca", description: "Encrypted/Protected audio", type: "Audio" }, 31 | { codec: "encf", description: "Encrypted/Protected font", type: "Systems" }, 32 | { codec: "encm", description: "Encrypted/Protected metadata stream", type: "Systems"}, 33 | { codec: "encs", description: "Encrypted Systems stream", type: "Systems"}, 34 | { codec: "enct", description: "Encrypted Text", type: "Text" }, 35 | { codec: "encv", description: "Encrypted/protected video", type: "Video" }, 36 | { codec: "fdp ", description: "File delivery hints", type: "Hint" }, 37 | { codec: "g719", description: "ITU-T Recommendation G.719 (2008)", type: "Audio" }, 38 | { codec: "g726", description: "ITU-T Recommendation G.726 (1990)", type: "Audio" }, 39 | { codec: "hev1", description: "High Efficiency Video Coding", type: "Video" }, 40 | { codec: "hvc1", description: "High Efficiency Video Coding", type: "Video" }, 41 | { codec: "hvt1", description: "High Efficiency Video Coding", type: "Video" }, 42 | { codec: "ixse", description: "DVB Track Level Index Track", type: "Metadata" }, 43 | { codec: "lhv1", description: "Layered High Efficiency Video Coding", type: "Video" }, 44 | { codec: "lhe1", description: "Layered High Efficiency Video Coding", type: "Video" }, 45 | { codec: "lht1", description: "Layered High Efficiency Video Coding", type: "Video" }, 46 | { codec: "m2ts", description: "MPEG-2 transport stream for DMB", type: "Hint" }, 47 | { codec: "m4ae", description: "MPEG-4 Audio Enhancement MP4v1", type: "Audio" }, 48 | { codec: "m4ae", description: "MPEG-4 Audio Enhancement MP4v2", type: "Audio" }, 49 | { codec: "mett", description: "Text timed metadata that is not XML", type: "Metadata" }, 50 | { codec: "metx", description: "XML timed metadata", type: "Metadata" }, 51 | { codec: "mha1", description: "MPEG-H Audio (single stream, uncapsulated)", type: "Audio" }, 52 | { codec: "mha2", description: "MPEG-H Audio (multi-stream, unencapsulated)", type: "Audio" }, 53 | { codec: "mhm1", description: "MPEG-H Audio (single stream, MHAS encapsulated)", type: "Audio" }, 54 | { codec: "mhm2", description: "MPEG-H Audio (multi-stream, MHAS encapsulated)", type: "Audio" }, 55 | { codec: "mjp2", description: "Motion JPEG 2000", type: "Video" }, 56 | { codec: "mlix", description: "DVB Movie level index track", type: "Metadata" }, 57 | { codec: "mlpa", description: "MLP Audio", type: "Audio" }, 58 | { codec: "mp4a", description: "MPEG-4 Audio", type: "Audio" }, 59 | { codec: "mp4s", description: "MPEG-4 Systems", type: "Systems" }, 60 | { codec: "mp4v", description: "MPEG-4 Visual", type: "Video" }, 61 | { codec: "mvc1", description: "Multiview coding", type: "Video" }, 62 | { codec: "mvc2", description: "Multiview coding", type: "Video" }, 63 | { codec: "mvc3", description: "Multiview coding", type: "Video" }, 64 | { codec: "mvc4", description: "Multiview coding", type: "Video" }, 65 | { codec: "mvd1", description: "Multiview coding", type: "Video" }, 66 | { codec: "mvd2", description: "Multiview coding", type: "Video" }, 67 | { codec: "mvd3", description: "Multiview coding", type: "Video" }, 68 | { codec: "mvd4", description: "Multiview coding", type: "Video" }, 69 | { codec: "oksd", description: "OMA Keys", type: "Metadata" }, 70 | { codec: "Opus", description: "Opus audio coding", type: "Audio" }, 71 | { codec: "pm2t", description: "Protected MPEG-2 Transport", type: "Hint" }, 72 | { codec: "prtp", description: "Protected RTP Reception", type: "Hint" }, 73 | { codec: "raw ", description: "Uncompressed audio", type: "Audio" }, 74 | { codec: "resv", description: "Restricted Video", type: "Video" }, 75 | { codec: "rm2t", description: "MPEG-2 Transport Reception", type: "Hint" }, 76 | { codec: "rrtp", description: "RTP reception", type: "Hint" }, 77 | { codec: "rsrp", description: "SRTP Reception", type: "Hint" }, 78 | { codec: "rtmd", description: "Real Time Metadata Sample Entry(XAVC Format)", type: "Systems" }, 79 | { codec: "rtp ", description: "RTP Hints", type: "Hint" }, 80 | { codec: "s263", description: "ITU H.263 video (3GPP format)", type: "Video" }, 81 | { codec: "samr", description: "Narrowband AMR voice", type: "Audio" }, 82 | { codec: "sawb", description: "Wideband AMR voice", type: "Audio" }, 83 | { codec: "sawp", description: "Extended AMR-WB (AMR-WB+)", type: "Audio" }, 84 | { codec: "sevc", description: "EVRC Voice", type: "Audio" }, 85 | { codec: "sm2t", description: "MPEG-2 Transport Server", type: "Hint" }, 86 | { codec: "sqcp", description: "13K Voice", type: "Audio" }, 87 | { codec: "srtp", description: "SRTP Hints", type: "Hint" }, 88 | { codec: "ssmv", description: "SMV Voice", type: "Audio" }, 89 | { codec: "stpp", description: "Subtitles (Timed Text)", type: "Text" }, 90 | { codec: "STGS", description: "Subtitle Sample Entry (HMMP)", type: "Text" }, 91 | { codec: "svc1", description: "Scalable Video Coding", type: "Video" }, 92 | { codec: "svc2", description: "Scalable Video Coding", type: "Video" }, 93 | { codec: "svcM", description: "SVC Metadata", type: "Metadata" }, 94 | { codec: "tc64", description: "64 bit timecode samples", type: "Timecode" }, 95 | { codec: "tmcd", description: "32 bit timecode samples", type: "Timecode" }, 96 | { codec: "twos", description: "Uncompressed 16-bit audio", type: "Audio" }, 97 | { codec: "tx3g", description: "Timed Text stream", type: "Text" }, 98 | { codec: "ulaw", description: "Samples have been compressed using uLaw 2:1.", type: "Audio" }, 99 | { codec: "unid", description: "Dynamic Range Control (DRC) data", type: "Metadata" }, 100 | { codec: "urim", description: "Binary timed metadata identified by URI", type: "Metadata" }, 101 | { codec: "vc-1", description: "SMPTE VC-1", type: "Video" }, 102 | { codec: "vp08", description: "VP8 video", type: "Video" }, 103 | { codec: "vp09", description: "VP9 video", type: "Video" }, 104 | { codec: "wvtt", description: "WebVTT", type: "Text" }, 105 | ]; 106 | --------------------------------------------------------------------------------