1907121.html (1560B)
1 <!DOCTYPE html> 2 <script> 3 function rgb2yuv(r, g, b) { 4 let y = r * .299000 + g * .587000 + b * .114000 5 let u = r * -.168736 + g * -.331264 + b * .500000 + 128 6 let v = r * .500000 + g * -.418688 + b * -.081312 + 128 7 8 y = Math.round(y); 9 u = Math.round(u); 10 v = Math.round(v); 11 return { y, u, v } 12 } 13 14 function ceilingOfHalf(value) { 15 return (value + 1) / 2; 16 } 17 18 function makeI420Frame(width, height, rgbColor) { 19 const yuvColor = rgb2yuv(rgbColor.r, rgbColor.g, rgbColor.b); 20 21 const ySize = width * height; 22 const uSize = ceilingOfHalf(width) * ceilingOfHalf(height); 23 const vSize = uSize; 24 25 const buffer = new Uint8Array(ySize + uSize + vSize); 26 buffer.fill(yuvColor.y, 0, ySize); 27 buffer.fill(yuvColor.u, ySize, ySize + uSize); 28 buffer.fill(yuvColor.v, ySize + uSize, ySize + uSize + vSize); 29 30 const colorSpace = { matrix: "rgb" }; 31 const init = { 32 format: 'I420', 33 timestamp: 0, 34 codedWidth: width, 35 codedHeight: height, 36 colorSpace: colorSpace, 37 }; 38 return new VideoFrame(buffer, init); 39 } 40 41 document.addEventListener("DOMContentLoaded", async () => { 42 const width = 4; 43 const height = 2; 44 const red = {r: 0xFF, g: 0x00, b: 0x00}; 45 46 const frame = makeI420Frame(width, height, red); 47 48 const options = { 49 rect: { x: 0, y: 0, width: width, height: height }, 50 format: "RGBX", 51 }; 52 const bufferSize = frame.allocationSize(options); 53 const buffer = new Uint8Array(bufferSize); 54 await frame.copyTo(buffer, options); 55 }) 56 </script>