WebCodecs VideoFrameãæŽ»çšããŠãWebãã©ãŠã¶äžã§é«åºŠãªãªã¢ã«ã¿ã€ã ãããªæäœãå®çŸããŸãããããã®æ©èœãšã°ããŒãã«ãªå¿çšã«ã€ããŠåŠã³ãŸãã
WebCodecs VideoFrameåŠçïŒãã©ãŠã¶ã§ã®ãã¬ãŒã ã¬ãã«ã®ãããªæäœã®å®çŸ
ãŠã§ãããŒã¹ã®ãããªã®ç¶æ³ã¯ãè¿å¹Žãå€é©çãªé²åãéããŠããŸãããåçŽãªåçããè€éãªã€ã³ã¿ã©ã¯ãã£ããªäœéšãŸã§ããããªã¯çŸåšãããžã¿ã«äžçã®äžå¯æ¬ ãªèŠçŽ ãšãªã£ãŠããŸããããããããæè¿ãŸã§ããã©ãŠã¶å
ã§çŽæ¥ãé«åºŠãªãã¬ãŒã ã¬ãã«ã®ãããªæäœãå®è¡ããããšã¯å€§ããªèª²é¡ã§ãããå€ãã®å ŽåããµãŒããŒåŽã®åŠçãŸãã¯ç¹æ®ãªãã©ã°ã€ã³ãå¿
èŠã§ãããããã¯ãã¹ãŠãWebCodecsãç¹ã«ãã®åŒ·åãªVideoFrameãªããžã§ã¯ãã®ç»å Žã«ãã£ãŠå€ãããŸããã
WebCodecsã¯ãã¡ãã£ã¢ãšã³ã³ãŒããŒããã³ãã³ãŒããŒãžã®ããŒã¬ãã«ã¢ã¯ã»ã¹ãæäŸããéçºè
ããã©ãŠã¶å
ã§çŽæ¥ã髿§èœã§ã«ã¹ã¿ãã€ãºãããã¡ãã£ã¢åŠçãã€ãã©ã€ã³ãæ§ç¯ã§ããããã«ããŸãããã®äžå¿ã«ããVideoFrameãªããžã§ã¯ãã¯ãåã
ã®ãããªãã¬ãŒã ãžã®çŽæ¥çãªçªãæäŸãããªã¢ã«ã¿ã€ã ã®ã¯ã©ã€ã¢ã³ãåŽã®ãããªæäœã®å¯èœæ§ãåºããŸãããã®å
æ¬çãªã¬ã€ãã§ã¯ãVideoFrameåŠçãäœã§ãããããã®èšãç¥ããªãå¯èœæ§ãäžçäžã®å®çšçãªã¢ããªã±ãŒã·ã§ã³ãããã³ãã®èœåãæŽ»çšããããã®æè¡çãªè€éãã«ã€ããŠæãäžããŠèª¬æããŸãã
åºç€ïŒWebCodecsãšVideoFrameãªããžã§ã¯ãã®çè§£
VideoFrameã®èœåãçè§£ããã«ã¯ãWebCodecs APIå
ã§ã®ã³ã³ããã¹ããçè§£ããããšãäžå¯æ¬ ã§ããWebCodecsã¯ããŠã§ãã¢ããªã±ãŒã·ã§ã³ãããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ããããããªãšã³ã³ãŒããŒããã³ãŒããŒãªã©ããã©ãŠã¶ã®åºç€ãšãªãã¡ãã£ã¢ã³ã³ããŒãã³ããšå¯Ÿè©±ã§ããããã«ããJavaScript APIã®ã»ããã§ãããã®çŽæ¥ã¢ã¯ã»ã¹ã¯ã以åã¯ãŠã§ãäžã§å©çšã§ããªãã£ã倧å¹
ãªããã©ãŒãã³ã¹åäžãšè©³çްãªå¶åŸ¡ãæäŸããŸãã
WebCodecsãšã¯ïŒ
æ¬è³ªçã«ãWebCodecsã¯ãé«ã¬ãã«ã®HTML <video>èŠçŽ ãšäœã¬ãã«ã®ã¡ãã£ã¢ããŒããŠã§ã¢éã®ã®ã£ãããåããŸããVideoDecoderãVideoEncoderãAudioDecoderãAudioEncoderãªã©ã®ã€ã³ã¿ãŒãã§ãŒã¹ãå
¬éããéçºè
ãå§çž®ãããã¡ãã£ã¢ãçã®ãã¬ãŒã ã«ãã³ãŒãããããçã®ãã¬ãŒã ãå§çž®ãããã¡ãã£ã¢ã«ãšã³ã³ãŒããããããããšããã¹ãŠãŠã§ããã©ãŠã¶å
ã§å¯èœã«ããŸãããã®æ©èœã¯ãã«ã¹ã¿ã åŠçã圢åŒå€æããŸãã¯åçãªã¹ããªãŒã æäœãå¿
èŠãšããã¢ããªã±ãŒã·ã§ã³ã®åºç€ãšãªããŸãã
VideoFrameãªããžã§ã¯ãïŒãã¯ã»ã«ãžã®çª
VideoFrameãªããžã§ã¯ãã¯ããã¬ãŒã ã¬ãã«ã®ãããªæäœã®åºç€ã§ããããã¯ããããªã®åäžã®éå§çž®ãã¬ãŒã ã衚ãããã®ãã¯ã»ã«ããŒã¿ã寞æ³ã圢åŒãããã³ã¿ã€ã ã¹ã¿ã³ããžã®ã¢ã¯ã»ã¹ãæäŸããŸãããããªã¹ããªãŒã å
ã®ç¹å®ã®ç¬éã®å¿
èŠãªæ
å ±ããã¹ãŠä¿æããã³ã³ãããšèããŠãã ããã
VideoFrameã®äž»èŠãªããããã£ã«ã¯ã次ã®ãã®ããããŸãã
formatïŒãã¯ã»ã«åœ¢åŒïŒäŸïŒ'I420'ã'RGBA'ã'NV12'ïŒãèšè¿°ããŸããcodedWidth/codedHeightïŒãšã³ã³ãŒã/ãã³ãŒãããããããªãã¬ãŒã ã®å¯žæ³ãdisplayWidth/displayHeightïŒã¢ã¹ãã¯ãæ¯ãèæ ®ããŠããã¬ãŒã ã衚瀺ãã寞æ³ãtimestampïŒãã¬ãŒã ã®ãã¬ãŒã³ããŒã·ã§ã³ã¿ã€ã ã¹ã¿ã³ãïŒPTSïŒïŒãã€ã¯ãç§åäœïŒãåæã«äžå¯æ¬ ã§ããdurationïŒãã¬ãŒã ã®æéïŒãã€ã¯ãç§åäœïŒãalphaïŒãã¬ãŒã ã«ã¢ã«ãã¡ãã£ãã«ïŒéæåºŠïŒããããã©ããã瀺ããŸããdataïŒçŽæ¥çãªããããã£ã§ã¯ãããŸããããcopyTo()ãªã©ã®ã¡ãœããã䜿çšãããšãåºç€ãšãªããã¯ã»ã«ãããã¡ã«ã¢ã¯ã»ã¹ã§ããŸãã
VideoFrameãžã®çŽæ¥ã¢ã¯ã»ã¹ãéåžžã«é©æ°çãªã®ã¯ãªãã§ããïŒããã«ãããéçºè
ã¯æ¬¡ã®ããšãå¯èœã«ãªããŸãã
- ãªã¢ã«ã¿ã€ã åŠçã®å®è¡ïŒã©ã€ããããªã¹ããªãŒã ã«ãã£ã«ã¿ãŒã倿ãããã³AI/MLã¢ãã«ãé©çšããŸãã
- ã«ã¹ã¿ã ãã€ãã©ã€ã³ã®äœæïŒæšæºã®ãã©ãŠã¶æ©èœãè¶ ããç¬èªã®ãšã³ã³ãŒãããã³ãŒããããã³ã¬ã³ããªã³ã°ã¯ãŒã¯ãããŒãæ§ç¯ããŸãã
- ããã©ãŒãã³ã¹ã®æé©åïŒå¹ççãªããŒã¿åŠçã®ããã«ããŒãã³ããŒæäœãšããŒããŠã§ã¢ã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ã掻çšããŸãã
- ã€ã³ã¿ã©ã¯ãã£ãæ§ã®åäžïŒä»¥åã¯ãã€ãã£ãã¢ããªã±ãŒã·ã§ã³ã§ã®ã¿å¯èœã ã£ãããªããã§å¿çæ§ã®é«ããããªäœéšãæ§ç¯ããŸãã
ChromeãEdgeãFirefoxãªã©ã®ææ°ã®ãã©ãŠã¶ã§ã¯ãVideoFrameãå«ãWebCodecsã®ãã©ãŠã¶ãµããŒããå
ç¢ã§ããããã仿¥ãã°ããŒãã«å±éã«é©ãããã¯ãããžãŒãšãªã£ãŠããŸãã
ã³ã¢ã³ã³ã»ãããšã¯ãŒã¯ãããŒïŒVideoFrameã®åä¿¡ãåŠçãããã³åºå
VideoFrameã®æäœã«ã¯ããã¬ãŒã ã®åä¿¡ãããŒã¿ã®åŠçãããã³å€æŽããããã¬ãŒã ã®åºåãšãã3段éã®ãã€ãã©ã€ã³ãå«ãŸããŸãããã®ã¯ãŒã¯ãããŒãçè§£ããããšã¯ã广çãªãããªæäœã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã«éèŠã§ãã
1. VideoFrameã®åä¿¡
VideoFrameãªããžã§ã¯ããååŸããäž»ãªæ¹æ³ã¯ããã€ããããŸãã
-
MediaStreamTrackããïŒããã¯ãã©ã€ãã«ã¡ã©ãã£ãŒããç»é¢å ±æããŸãã¯WebRTCã¹ããªãŒã ã§äžè¬çã§ããMediaStreamTrackProcessorAPIã䜿çšãããšããããªãã©ãã¯ããçŽæ¥VideoFrameãªããžã§ã¯ãããã«ã§ããŸããããšãã°ããŠãŒã¶ãŒã®ãŠã§ãã«ã¡ã©ããã£ããã£ããŸãïŒ
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true }); const track = mediaStream.getVideoTracks()[0]; const processor = new MediaStreamTrackProcessor({ track }); const readableStream = processor.readable; // ããã§ã'readableStream'ããVideoFrameãèªã¿åãããšãã§ããŸã -
VideoDecoderããïŒå§çž®ããããããªããŒã¿ïŒããšãã°ãMP4ãã¡ã€ã«ãŸãã¯ãšã³ã³ãŒãããããã¬ãŒã ã®ã¹ããªãŒã ïŒãããå Žåã¯ãVideoDecoderã䜿çšããŠãåã ã®VideoFrameã«è§£åã§ããŸããããã¯ãé²ç»æžã¿ã®ã³ã³ãã³ãã®åŠçã«æé©ã§ãã
const decoder = new VideoDecoder({ output: frame => { /* 'frame'ãåŠç */ }, error: error => console.error(error) }); // ... ãšã³ã³ãŒãããããã£ã³ã¯ãdecoder.decode()ã«ãã£ãŒãããŸã -
çããŒã¿ããã®äœæïŒã¡ã¢ãªå
ã®çã®ãã¯ã»ã«ããŒã¿ããçŽæ¥
VideoFrameãæ§ç¯ã§ããŸããããã¯ããã¬ãŒã ãæé ã©ããã«çæããããä»ã®ãœãŒã¹ïŒããšãã°ãWebAssemblyã¢ãžã¥ãŒã«ïŒããã€ã³ããŒããããããå Žåã«åœ¹ç«ã¡ãŸãã
const rawData = new Uint8ClampedArray(width * height * 4); // RGBAããŒã¿ // ... rawDataã«å ¥åããŸã const frame = new VideoFrame(rawData, { format: 'RGBA', width: width, height: height, timestamp: Date.now() * 1000 // ãã€ã¯ãç§ });
2. VideoFrameã®åŠç
VideoFrameãååŸããããæäœã®æ¬åœã®åãå§ãŸããŸããäžè¬çãªåŠçææ³ãæ¬¡ã«ç€ºããŸãã
-
ãã¯ã»ã«ããŒã¿ãžã®ã¢ã¯ã»ã¹ïŒ
copyTo()ãtransferTo()ïŒïŒãã¯ã»ã«ããŒã¿ãèªã¿åããŸãã¯å€æŽããã«ã¯ãcopyTo()ãªã©ã®ã¡ãœããã䜿çšããŠãã¬ãŒã ããŒã¿ããããã¡ã«ã³ããŒããããtransferTo()ã䜿çšããŠãŒãã³ããŒæäœãè¡ããŸããç¹ã«ãWebã¯ãŒã«ãŒéããŸãã¯WebGPU/WebGLã³ã³ããã¹ãã«ããŒã¿ãæž¡ãå Žåãããã«ãããã«ã¹ã¿ã ã¢ã«ãŽãªãºã ãé©çšã§ããŸãã
const data = new Uint8Array(frame.allocationSize()); await frame.copyTo(data, { layout: [{ offset: 0, stride: frame.codedWidth * 4 }] }); // 'data'ã«ã¯ãçã®ãã¯ã»ã«æ å ±ïŒããšãã°ãäžè¬çãªåœ¢åŒã®RGBAïŒãå«ãŸããŠããŸã // ... 'data'ãæäœããŸã // 次ã«ãæäœãããããŒã¿ããæ°ããVideoFrameãäœæããŸã - ç»åæäœïŒãã¯ã»ã«ããŒã¿ãçŽæ¥å€æŽãããšããã£ã«ã¿ãŒïŒã°ã¬ãŒã¹ã±ãŒã«ãã»ãã¢ããŒããïŒããµã€ãºå€æŽãããªãã³ã°ãè²è£æ£ãããè€éãªã¢ã«ãŽãªãºã 倿ãªã©ãããŸããŸãªå¹æãåŸãããŸããã©ã€ãã©ãªãŸãã¯ã«ã¹ã¿ã ã·ã§ãŒããŒãããã§äœ¿çšã§ããŸãã
-
Canvasçµ±åïŒ
VideoFrameãåŠçããããã®éåžžã«äžè¬çã§ããã©ãŒãã³ã¹ã®é«ãæ¹æ³ã¯ãHTMLCanvasElementãŸãã¯OffscreenCanvasã«æç»ããããšã§ãããã£ã³ãã¹ã«æç»ãããã匷åãªCanvasRenderingContext2DAPIãå©çšããŠãæç»ããã¬ã³ããããã³ãã¯ã»ã«æäœïŒgetImageData()ãputImageData()ïŒãè¡ãããšãã§ããŸããããã¯ãã°ã©ãã£ã«ã«ãªãŒããŒã¬ã€ãé©çšããããè€æ°ã®ãããªãœãŒã¹ãçµåãããããå Žåã«ç¹ã«åœ¹ç«ã¡ãŸãã
const canvas = document.createElement('canvas'); canvas.width = frame.displayWidth; canvas.height = frame.displayHeight; const ctx = canvas.getContext('2d'); ctx.drawImage(frame, 0, 0, canvas.width, canvas.height); // ããã§ããã£ã³ãã¹ããŒã¹ã®å¹æãé©çšããããctx.getImageData()ãããã¯ã»ã«ããŒã¿ãååŸããŸã // ãã£ã³ãã¹ããæ°ããVideoFrameãäœæããå Žåã¯ã次ã®ããã«ãªããŸãïŒ const newFrame = new VideoFrame(canvas, { timestamp: frame.timestamp }); -
WebGPU/WebGLçµ±åïŒé«åºŠã«æé©åãããè€éãªèŠèŠå¹æã®ããã«ã
VideoFrameãWebGPUãŸãã¯WebGLãã¯ã¹ãã£ã«å¹ççã«è»¢éã§ããŸããããã«ãããé«åºŠãªãªã¢ã«ã¿ã€ã ã¬ã³ããªã³ã°ã3Dãšãã§ã¯ããããã³ãããŒã³ã³ãã¥ãŒãã£ã³ã°ã¿ã¹ã¯ã®ããã«ãGPUã·ã§ãŒããŒïŒãã©ã°ã¡ã³ãã·ã§ãŒããŒïŒã®åãè§£æŸãããŸããããã¯ãçã«æ ç»ã®ãããªãã©ãŠã¶ããŒã¹ã®ãšãã§ã¯ããå¯èœã«ãªãå Žæã§ãã -
èšç®ã¿ã¹ã¯ïŒAI/MLæšè«ïŒïŒ
VideoFrameããã®çã®ãã¯ã»ã«ããŒã¿ã¯ããªããžã§ã¯ãæ€åºãé¡èªèãããŒãºæšå®ããŸãã¯ãªã¢ã«ã¿ã€ã ã»ã°ã¡ã³ããŒã·ã§ã³ïŒããšãã°ãèæ¯ã®åé€ïŒãªã©ã®ã¿ã¹ã¯ã®ããã«ããã©ãŠã¶ããŒã¹ã®æ©æ¢°åŠç¿ã¢ãã«ïŒããšãã°ãTensorFlow.jsïŒã«çŽæ¥ãã£ãŒãã§ããŸãã
3. VideoFrameã®åºå
åŠçåŸãéåžžã倿ŽãããVideoFrameãã衚瀺ããšã³ã³ãŒãããŸãã¯ã¹ããªãŒãã³ã°ã®ããã«åºåããŸãã
-
VideoEncoderãžïŒãã¬ãŒã ã倿Žããããããåãšã³ã³ãŒãããå ŽåïŒããšãã°ããµã€ãºãçž®å°ãããã圢åŒã倿Žããããã¹ããªãŒãã³ã°ã®æºåããããããå ŽåïŒã¯ãããããVideoEncoderã«ãã£ãŒãã§ããŸããããã¯ãã«ã¹ã¿ã ãã©ã³ã¹ã³ãŒãã£ã³ã°ãã€ãã©ã€ã³ã«äžå¯æ¬ ã§ãã
const encoder = new VideoEncoder({ output: chunk => { /* ãšã³ã³ãŒãããããã£ã³ã¯ãåŠç */ }, error: error => console.error(error) }); // ... åŠçåŸãnewFrameããšã³ã³ãŒãããŸã encoder.encode(newFrame); -
ImageBitmapãžïŒè¡šç€ºçšïŒïŒãã£ã³ãã¹ãŸãã¯ç»åèŠçŽ ã«çŽæ¥è¡šç€ºããããã«ãVideoFrameãImageBitmapã«å€æã§ããŸããããã¯ãå®å šã«åãšã³ã³ãŒãããã«ãã¬ãŒã ãå¹ççã«ã¬ã³ããªã³ã°ããäžè¬çãªæ¹æ³ã§ãã
const imageBitmap = await createImageBitmap(frame); // ãã£ã³ãã¹ã«imageBitmapãæç»ããŠè¡šç€ºããŸã -
MediaStreamTrackãžïŒã©ã€ãã¹ããªãŒãã³ã°ã·ããªãªãç¹ã«WebRTCã§ã¯ãMediaStreamTrackGeneratorã䜿çšããŠã倿ŽãããVideoFrameãMediaStreamTrackã«æ»ãããšãã§ããŸããããã«ããããããªäŒè°ãŸãã¯ã©ã€ãæŸéã§ãªã¢ã«ã¿ã€ã ã®ãããªãšãã§ã¯ããå¯èœã«ãªããŸãã
const generator = new MediaStreamTrackGenerator({ kind: 'video' }); const processedStream = new MediaStream([generator]); // 次ã«ãåŠçã«ãŒãã§ïŒ const writableStream = generator.writable; const writer = writableStream.getWriter(); // ... ãã¬ãŒã ãnewFrameã«åŠçããŸã writer.write(newFrame);
å®çšçãªã¢ããªã±ãŒã·ã§ã³ãšãŠãŒã¹ã±ãŒã¹ïŒã°ããŒãã«ãªèŠç¹
VideoFrameåŠçã®æ©èœã¯ãWebãã©ãŠã¶å
ã§çŽæ¥ãã€ã³ã¿ã©ã¯ãã£ãã§ã€ã³ããªãžã§ã³ããªãããªäœéšã®æ°æä»£ãåãéãã倿§ãªæ¥çãšãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã«åœ±é¿ãäžããŸããããã€ãã®äŸã次ã«ç€ºããŸãã
1. é«åºŠãªãããªäŒè°ããã³ã³ãã¥ãã±ãŒã·ã§ã³ãã©ãããã©ãŒã
ãããªé話ã«äŸåããŠãã倧éžå
šäœã®çµç¹ãæè²è
ãããã³å人ã«ãšã£ãŠãVideoFrameã¯æ¯é¡ã®ãªãã«ã¹ã¿ãã€ãºãæäŸããŸãã
-
ãªã¢ã«ã¿ã€ã ã®èæ¯çœ®æïŒãŠãŒã¶ãŒã¯ãã°ãªãŒã³ã¹ã¯ãªãŒã³ã匷åãªããŒã«ã«ããŒããŠã§ã¢ãå¿
èŠãšããã«ãç©ççãªèæ¯ãä»®æ³çãªèæ¯ïŒç»åããããªããŒãã广ïŒã«çœ®ãæããããšãã§ããäžçäžã®ãªã¢ãŒãã¯ãŒã«ãŒã®ãã©ã€ãã·ãŒãšãããã§ãã·ã§ããªãºã ãåäžãããŸãã
äŸïŒã€ã³ãã®ãœãããŠã§ã¢éçºè ã¯ãããã®ãªãã£ã¹èæ¯ã§èªå® ããã°ããŒãã«ããŒã ããŒãã£ã³ã°ã«åå ã§ããŸãããŸãããã©ãžã«ã®æåž«ã¯ããªã³ã©ã€ã³ã¯ã©ã¹ã§é åçãªæè²èæ¯ã䜿çšã§ããŸãã
-
æ¡åŒµçŸå®ïŒARïŒãã£ã«ã¿ãŒãšãšãã§ã¯ãïŒä»®æ³ã¢ã¯ã»ãµãªãŒãã¡ã€ã¯ã¢ããããŸãã¯ãã£ã©ã¯ã¿ãŒãªãŒããŒã¬ã€ããªã¢ã«ã¿ã€ã ã§é¡ã«è¿œå ãããšã³ã²ãŒãžã¡ã³ããšããŒãœãã©ã€ãºã匷åããŸããããã¯ãäžçäžã®ãœãŒã·ã£ã«ã¡ãã£ã¢ããã³ãšã³ã¿ãŒãã€ã¡ã³ãã¢ããªã§äººæ°ããããŸãã
äŸïŒããŸããŸãªã¿ã€ã ãŸãŒã³ã§ãã£ããããŠããå人ã¯ã楜ããåç©ãã£ã«ã¿ãŒãŸãã¯ãã€ãããã¯ãã¹ã¯ã䜿çšããŠäŒè©±ãããŒãœãã©ã€ãºã§ããŸãããŸãããšãŒãããã®ä»®æ³ãã¡ãã·ã§ã³ã³ã³ãµã«ã¿ã³ãã¯ãã¢ãžã¢ã®ã¯ã©ã€ã¢ã³ãã®ã©ã€ããããªãã£ãŒãã§ã¢ã¯ã»ãµãªãŒããã¢ã³ã¹ãã¬ãŒã·ã§ã³ã§ããŸãã
-
ãã€ãºãªãã¯ã·ã§ã³ãšãããªãšã³ãã³ã¹ã¡ã³ãïŒäœç
§åºŠæ¡ä»¶ãŸãã¯çæ³çãšã¯èšããªãã«ã¡ã©ã»ããã¢ããããã®ãã€ãºã®å€ããããªãã£ãŒããã¯ãªãŒã³ã¢ããããããã«ãã£ã«ã¿ãŒãé©çšãããã¹ãŠã®åå è
ã®ãããªå質ãåäžãããŸãã
äŸïŒç §æãéãããŠãããªã¢ãŒããã±ãŒã·ã§ã³ããã¬ããŒãããŠãããžã£ãŒããªã¹ãã¯ããããªãã£ãŒããèªåçã«æãããªãããã€ãºãé€å»ãããŠãã°ããŒãã«ãªãã¥ãŒã¹ãªãŒãã£ãšã³ã¹ãžã®ããæç¢ºãªéä¿¡ãå¯èœã«ãªããŸãã
-
ã«ã¹ã¿ã ç»é¢å
±æãªãŒããŒã¬ã€ïŒãã¬ãŒã³ããŒã·ã§ã³äžã«ç¢å°ããã€ã©ã€ãããŸãã¯ã«ã¹ã¿ã ãã©ã³ãã®ã°ã©ãã£ãã¯ãå
±æç»é¢ã«ãªã¢ã«ã¿ã€ã ã§æ³šéãä»ããåœéããŒã ã®æçããšã³ãã¥ãã±ãŒã·ã§ã³ã匷åããŸãã
äŸïŒæ¥æ¬ã®ãããžã§ã¯ããããŒãžã£ãŒã忣ããŒã ã«æè¡å³ãæç€ºããå Žåãç¹å®ã®ã³ã³ããŒãã³ãã«ãªã¢ã«ã¿ã€ã ã§æ³šæãåŒãããšãã§ããŸããäžæ¹ãã«ããã®ãã¶ã€ããŒã¯ããªãŒã¹ãã©ãªã¢ã®ã¯ã©ã€ã¢ã³ããšUIã¢ãã¯ã¢ããã§å ±åäœæ¥ãè¡ããŸãã
2. ã€ã³ã¿ã©ã¯ãã£ãã¹ããªãŒãã³ã°ããã³ãããŒããã£ã¹ããã©ãããã©ãŒã
ã©ã€ãã¹ããªãŒããŒãã³ã³ãã³ãã¯ãªãšãŒã¿ãŒãããã³ãããŒããã£ã¹ã¿ãŒã«ãšã£ãŠãVideoFrameã¯ãããã§ãã·ã§ãã«ã°ã¬ãŒãã®å¶äœããŒã«ããã©ãŠã¶ã«ãããããŸãã
-
ãã€ãããã¯ãªãŒããŒã¬ã€ãšã°ã©ãã£ãã¯ïŒã©ã€ãããŒã¿ïŒããšãã°ãã¹ããŒãã®ã¹ã³ã¢ãéèãã£ãã«ãŒããœãŒã·ã£ã«ã¡ãã£ã¢ã®ã³ã¡ã³ãïŒãã€ã³ã¿ã©ã¯ãã£ããªæç¥šããŸãã¯ã«ã¹ã¿ã ãã©ã³ãã®ã°ã©ãã£ãã¯ãããµãŒããŒåŽã®ã¬ã³ããªã³ã°ãªãã§ã©ã€ããããªã¹ããªãŒã ã«éãåãããŸãã
äŸïŒã¢ããªã«ããã¹ããªãŒãã³ã°ããŠããã©ã€ãã¹ããŒã解説è ã¯ããšãŒãããããã³ã¢ã¡ãªã«å šäœã§èŠèŽããŠããèŠèŽè åãã«ããªã¢ã«ã¿ã€ã ã®ãã¬ãŒã€ãŒçµ±èšãšèŠèŽè ã®æç¥šçµæãã²ãŒã æ åã«çŽæ¥è¡šç€ºã§ããŸãã
-
ããŒãœãã©ã€ãºãããã³ã³ãã³ãé
ä¿¡ïŒèŠèŽè
ã®äººå£çµ±èšãå ŽæããŸãã¯ã€ã³ã¿ã©ã¯ã·ã§ã³ã«åºã¥ããŠããããªã³ã³ãã³ããŸãã¯åºåããªã¢ã«ã¿ã€ã ã§èª¿æŽããããé
åçã§é¢é£æ§ã®é«ããšã¯ã¹ããªãšã³ã¹ãæäŸããŸãã
äŸïŒeã³ããŒã¹ãã©ãããã©ãŒã ã¯ãããŸããŸãªå°åã®èŠèŽè åãã«ãã©ã€ã補åãã¢ã³ã¹ãã¬ãŒã·ã§ã³ãããªã«çŽæ¥åã蟌ãŸããããŒã«ã©ã€ãºããã補åããã¢ãŒã·ã§ã³ãŸãã¯é貚æ å ±ã衚瀺ã§ããŸãã
-
ã©ã€ãã¢ãã¬ãŒã·ã§ã³ãšæ€é²ïŒã©ã€ããããŒããã£ã¹ãäžã«äžé©åãªã³ã³ãã³ãïŒé¡ãç¹å®ã®ãªããžã§ã¯ããæ©å¯ç»åïŒãèªåçã«æ€åºããŠãŒãããããããã¯ããããã倿§ãªã°ããŒãã«ã³ã³ãã³ãåºæºãžã®æºæ ãä¿èšŒããŸãã
äŸïŒãŠãŒã¶ãŒçæã®ã©ã€ãã¹ããªãŒã ããã¹ããããã©ãããã©ãŒã ã¯ãæ©å¯æ§ã®é«ãå人æ å ±ãŸãã¯äžé©åãªã³ã³ãã³ããèªåçã«ãŒãããã°ããŒãã«ãªãŒãã£ãšã³ã¹ã«ãšã£ãŠå®å šãªèŠèŽç°å¢ãç¶æã§ããŸãã
3. ãã©ãŠã¶ããŒã¹ã®ã¯ãªãšã€ãã£ãããŒã«ãšãããªç·šé
äžçäžã®ã©ã®ããã€ã¹ããã§ãã¢ã¯ã»ã¹ã§ããã匷åãªç·šéæ©èœããã©ãŠã¶ã§çŽæ¥ã¯ãªãšã€ã¿ãŒãšãããã§ãã·ã§ãã«ã«æäŸããŸãã
-
ãªã¢ã«ã¿ã€ã ãã£ã«ã¿ãŒãšã«ã©ãŒã°ã¬ãŒãã£ã³ã°ïŒãã¹ã¯ããããããªç·šéãœãããŠã§ã¢ãšåæ§ã«ããããã§ãã·ã§ãã«ã°ã¬ãŒãã®è²è£æ£ãã·ãããã£ãã¯ãã£ã«ã¿ãŒããŸãã¯ã¹ã¿ã€ã«ã®ãšãã§ã¯ãããããªã¯ãªããã«ç¬æã«é©çšããŸãã
äŸïŒãã©ã³ã¹ã®æ ç»è£œäœè ã¯ããã©ãŠã¶ããŒã¹ã®ãšãã£ã¿ãŒã§æªå å·¥ã®æ åã®ããŸããŸãªã«ã©ãŒãã¬ããããã°ãããã¬ãã¥ãŒã§ããŸãããŸããéåœã®ã°ã©ãã£ãã¯ãã¶ã€ããŒã¯ãWebãããžã§ã¯ãã®ãããªèŠçŽ ã«èžè¡çãªãšãã§ã¯ããé©çšã§ããŸãã
-
ã«ã¹ã¿ã ãã©ã³ãžã·ã§ã³ãšèŠèŠå¹æïŒVFXïŒïŒç¬èªã®ãããªãã©ã³ãžã·ã§ã³ãå®è£
ããããè€éãªèŠèŠå¹æãåçã«çæãããããããšã§ãé«äŸ¡ãªãã¹ã¯ããããœãããŠã§ã¢ãžã®äŸåã軜æžããŸãã
äŸïŒã¢ã«ãŒã³ãã³ã®åŠçããã«ãã¡ãã£ã¢ãã¬ãŒã³ããŒã·ã§ã³ãäœæããå Žåã軜éã®WebããŒã«ã䜿çšããŠãããªã»ã°ã¡ã³ãéã«ã«ã¹ã¿ã ã¢ãã¡ãŒã·ã§ã³ãã©ã³ãžã·ã§ã³ãç°¡åã«è¿œå ã§ããŸãã
-
ãããªå
¥åããã®çæã¢ãŒãïŒã«ã¡ã©å
¥åããã¬ãŒã ããšã«åŠçãããŠãç¬èªã®ã°ã©ãã£ã«ã«åºåãçæãããæœè±¡çãªã¢ãŒããããžã¥ã¢ã©ã€ã¶ãŒããŸãã¯ã€ã³ã¿ã©ã¯ãã£ããªã€ã³ã¹ã¿ã¬ãŒã·ã§ã³ãäœæããŸãã
äŸïŒæ¥æ¬ã®ã¢ãŒãã£ã¹ãã¯ãã©ã€ãWebã«ã ãã£ãŒããæµãããããªæœè±¡çµµç»ã«å€æããã€ã³ã¿ã©ã¯ãã£ããªããžã¿ã«ã¢ãŒãäœåãäœæã§ããŸããããã¯ãWebãªã³ã¯ãä»ããŠäžçäžã§ã¢ã¯ã»ã¹ã§ããŸãã
4. ã¢ã¯ã»ã·ããªãã£ã®åäžã𿝿޿è¡
ãããªã³ã³ãã³ããã倿§ãªã°ããŒãã«ãªãŒãã£ãšã³ã¹ã«ãšã£ãŠããã¢ã¯ã»ã¹ããããå æ¬çã«ããŸãã
-
ãªã¢ã«ã¿ã€ã ã®æè©±èªè/ãªãŒããŒã¬ã€ïŒãããªãã£ãŒããåŠçããŠæè©±ãžã§ã¹ãã£ãæ€åºãã察å¿ããããã¹ãããŸãã¯èŽèŠé害ã®ãããŠãŒã¶ãŒåãã«ç¿»èš³ããããªãŒãã£ãªããªã¢ã«ã¿ã€ã ã§ãªãŒããŒã¬ã€ããŸãã
äŸïŒèŽèŠé害è ã¯ãã©ã€ãã®ãªã³ã©ã€ã³è¬çŸ©ãèŠãŠããå Žåãäžçäžã®ã©ãã«ããŠããç»é¢ã«è¡šç€ºãããæè©±éèš³ã®ãªã¢ã«ã¿ã€ã ããã¹ã翻蚳ãèŠãããšãã§ããŸãã
-
è²èŠç°åžžè£æ£ãã£ã«ã¿ãŒïŒããŸããŸãªåœ¢åŒã®è²èŠç°åžžã®ãããŠãŒã¶ãŒåãã«ããããªãã¬ãŒã ã«ãã£ã«ã¿ãŒããªã¢ã«ã¿ã€ã ã§é©çšããŠè²ã調æŽããèŠèŽäœéšãåäžãããŸãã
äŸïŒç·èµ€è²èŠç°åžžã®ãŠãŒã¶ãŒãèªç¶ããã¥ã¡ã³ã¿ãªãŒãèŠãŠããå Žåãè²ãã·ããããŠç·ãšèµ€ãããåºå¥ãããããããã©ãŠã¶ããŒã¹ã®ãã£ã«ã¿ãŒãæå¹ã«ããŠãæ¯è²ã®èªèãåäžãããããšãã§ããŸãã
-
æ¹åããããã£ãã·ã§ã³ãšåå¹ïŒãããªã³ã³ãã³ãã«çŽæ¥ã¢ã¯ã»ã¹ããŠãããåªããåæãŸãã¯ã³ã³ããã¹ãåæãè¡ãããšã«ãããããæ£ç¢ºã§åçãŸãã¯ããŒãœãã©ã€ãºããããã£ãã·ã§ã³ã·ã¹ãã ãéçºããŸãã
äŸïŒåŠç¿ãã©ãããã©ãŒã ã¯ãæè²ãããªã®ãªã¢ã«ã¿ã€ã ã§ç¿»èš³ããããã£ãã·ã§ã³ãæäŸãã倿§ãªèšèªçèæ¯ãæã€åŠçããã广çã«é¢äžã§ããããã«ããŸãã
5. ç£èŠãã¢ãã¿ãªã³ã°ãããã³ç£æ¥ã¢ããªã±ãŒã·ã§ã³
ããã€ã³ããªãžã§ã³ãã§ããŒã«ã©ã€ãºããããããªåæã®ããã«ãã¯ã©ã€ã¢ã³ãåŽã®åŠçãæŽ»çšããŸãã
-
ç°åžžæ€åºãšãªããžã§ã¯ã远跡ïŒãã¹ãŠã®çã®ãããªããŒã¿ãã¯ã©ãŠãã«éä¿¡ããã«ãç°åžžãªã¢ã¯ãã£ããã£ã®ãããªãã£ãŒãããªã¢ã«ã¿ã€ã ã§åæããããç¹å®ã®ãªããžã§ã¯ãã远跡ãããããŠããã©ã€ãã·ãŒãåäžããã垯åå¹
ãåæžããŸãã
äŸïŒãã€ãã®è£œé å·¥å Žã¯ããã©ãŠã¶ããŒã¹ã®ãããªåæã䜿çšããŠãçµã¿ç«ãŠã©ã€ã³ã®æ¬ é¥ãç°åžžãªåããããŒã«ã«ã§ç£èŠããã¢ã©ãŒããå³åº§ã«ããªã¬ãŒã§ããŸãã
-
ãã©ã€ãã·ãã¹ãã³ã°ïŒãããªã¹ããªãŒã å
ã®é¡ãŸãã¯æ©å¯é åããèšé²ãŸãã¯éä¿¡ããåã«èªåçã«ãŒãããããã¯ã»ã«åãããããŠãå
Œ
±ã¹ããŒã¹ãŸãã¯èŠå¶ãããæ¥çã§ã®ãã©ã€ãã·ãŒã®åé¡ã«å¯ŸåŠããŸãã
äŸïŒå ¬å ±ã®äŒå Žã®ã»ãã¥ãªãã£ã·ã¹ãã ã¯ããããªãã¢ãŒã«ã€ãããåã«ãããŒã¿ãã©ã€ãã·ãŒèŠå¶ã«æºæ ããããã«ãèšé²ãããæ åã®å芳è ã®é¡ãèªåçã«ãŒããããšãã§ããŸãã
æè¡çãªè©³çްãšãã¹ããã©ã¯ãã£ã¹
VideoFrameã®æäœã¯åŒ·åã§ãããããã©ãŒãã³ã¹ãã¡ã¢ãªãããã³ãã©ãŠã¶ã®æ©èœã«ã€ããŠæ
éã«æ€èšããå¿
èŠããããŸãã
ããã©ãŒãã³ã¹ã®èæ ®äºé
-
ãŒãã³ããŒæäœïŒå¯èœãªéããã³ã³ããã¹ãïŒã¡ã€ã³ã¹ã¬ãããWebã¯ãŒã«ãŒãWebGPUïŒéã§
VideoFrameããŒã¿ãç§»åãããšãã«ããŒãã³ããŒããŒã¿è»¢éãå¯èœã«ããã¡ãœããïŒããšãã°ãtransferTo()ïŒãå©çšããŸããããã«ããããªãŒããŒããããå€§å¹ ã«åæžãããŸãã -
Webã¯ãŒã«ãŒïŒå°çšã®Webã¯ãŒã«ãŒã§ãããŒãªãããªåŠçã¿ã¹ã¯ãå®è¡ããŸããããã«ãããã¡ã€ã³ã¹ã¬ããããèšç®ããªãããŒãããããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ã®å¿çæ§ãç¶æãããŸãã
OffscreenCanvasã¯ãç¹ã«ããã§åœ¹ç«ã¡ãŸããããã«ããããã£ã³ãã¹ã¬ã³ããªã³ã°ãã¯ãŒã«ãŒå ã§å®å šã«å®è¡ã§ããããã«ãªããŸãã -
GPUã¢ã¯ã»ã©ã¬ãŒã·ã§ã³ïŒWebGPUãWebGLïŒïŒèšç®è² è·ã®é«ãã°ã©ãã£ã«ã«ãšãã§ã¯ãã®å Žåã¯ãGPUãæŽ»çšããŸãã
VideoFrameãWebGPU/WebGLãã¯ã¹ãã£ã«è»¢éããã·ã§ãŒããŒã䜿çšããŠå€æãå®è¡ããŸããããã¯ãCPUããŒã¹ã®ãã£ã³ãã¹æäœããããã¯ã»ã«ã¬ãã«ã®æäœã«ã¯ããã«å¹ççã§ãã -
ã¡ã¢ãªç®¡çïŒ
VideoFrameã¯æ¯èŒç倧éã®ãªããžã§ã¯ãã§ããVideoFrameã®æäœãçµäºããããå¿ ãframe.close()ãåŒã³åºããŠãåºç€ãšãªãã¡ã¢ãªãããã¡ãè§£æŸããŸããããããªããšãç¹ã«é·æéå®è¡ãããã¢ããªã±ãŒã·ã§ã³ãã1ç§ããã倿°ã®ãã¬ãŒã ãåŠçããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã¡ã¢ãªãªãŒã¯ãããã©ãŒãã³ã¹ã®äœäžã«ã€ãªããå¯èœæ§ããããŸãã - ã¹ããããªã³ã°ãšãããŠã³ã¹ïŒãªã¢ã«ã¿ã€ã ã·ããªãªã§ã¯ãåŠçã§ãããããéããã¬ãŒã ãåä¿¡ããå ŽåããããŸããåŠçãã€ãã©ã€ã³ãå§åãããªãããã«ãã¹ããããªã³ã°ãŸãã¯ãããŠã³ã¹ã¡ã«ããºã ãå®è£ ããå¿ èŠã«å¿ããŠãã¬ãŒã ãæ£åžžã«ããããããŸãã
ã»ãã¥ãªãã£ãšãã©ã€ãã·ãŒ
-
æš©éïŒãŠãŒã¶ãŒã¡ãã£ã¢ïŒã«ã¡ã©ããã€ã¯ïŒãžã®ã¢ã¯ã»ã¹ã«ã¯ã
navigator.mediaDevices.getUserMedia()ãä»ããŠæç€ºçãªãŠãŒã¶ãŒæš©éãå¿ èŠã§ãããŠãŒã¶ãŒã®ã¡ãã£ã¢ã«ã¢ã¯ã»ã¹ãããšãã¯ãåžžã«ãŠãŒã¶ãŒã«æç¢ºãªã€ã³ãžã±ãŒã¿ãŒãæäŸããŸãã - ããŒã¿åŠçïŒç¹ã«ãŠãŒã¶ãŒã®ããã€ã¹ããé¢ããå Žåã¯ããããªããŒã¿ã®åŠçãä¿åããŸãã¯éä¿¡æ¹æ³ã«ã€ããŠééçã«ããŸããGDPRãCCPAãªã©ã察象èªè ã«é¢é£ããã°ããŒãã«ãªããŒã¿ä¿è·èŠå¶ãéµå®ããŠãã ããã
ãšã©ãŒåŠç
ãã¹ãŠã®WebCodecsã³ã³ããŒãã³ãïŒãã³ãŒããŒããšã³ã³ãŒããŒãããã»ããµãŒïŒã«å¯ŸããŠå ç¢ãªãšã©ãŒåŠçãå®è£ ããŸããã¡ãã£ã¢ãã€ãã©ã€ã³ã¯è€éã«ãªãå¯èœæ§ãããããµããŒããããŠããªã圢åŒãããŒããŠã§ã¢ã®å¶éããŸãã¯äžæ£ãªããŒã¿ãåå ã§ãšã©ãŒãçºçããå¯èœæ§ããããŸããåé¡ãçºçãããšãã«ããŠãŒã¶ãŒã«æå³ã®ãããã£ãŒãããã¯ãæäŸããŸãã
ãã©ãŠã¶ã®äºææ§ãšãã©ãŒã«ããã¯
WebCodecsã¯ååã«ãµããŒããããŠããŸãããæ©èœæ€åºïŒããšãã°ãif ('VideoFrame' in window) { ... }ïŒã䜿çšããŠãã©ãŠã¶ã®äºææ§ã確èªããããšã¯åžžã«è¯ãæ¹æ³ã§ããWebCodecsãå©çšã§ããªãå€ããã©ãŠã¶ãŸãã¯ç°å¢ã®å Žåã¯ããµãŒããŒåŽã®åŠçãŸãã¯ããåçŽãªã¯ã©ã€ã¢ã³ãåŽã®ã¢ãããŒãã䜿çšããŠãæ£åžžãªãã©ãŒã«ããã¯ãæ€èšããŠãã ããã
ä»ã®APIãšã®çµ±å
VideoFrameã®çã®åã¯ãå€ãã®å Žåãä»ã®Web APIãšã®çžä¹å¹æããããããããŸãã
- WebRTCïŒãããªäŒè°ã§ãªã¢ã«ã¿ã€ã ã§ãããªãã¬ãŒã ãçŽæ¥æäœããã«ã¹ã¿ã ãšãã§ã¯ããèæ¯ã®çœ®æãããã³ã¢ã¯ã»ã·ããªãã£æ©èœãå®çŸããŸãã
-
WebAssemblyïŒWasmïŒïŒãã€ãã£ãã«è¿ãããã©ãŒãã³ã¹ã®æ©æµãåããé«åºŠã«æé©åãããè€éãªãã¯ã»ã«æäœã¢ã«ãŽãªãºã ã®å ŽåãWasmã¢ãžã¥ãŒã«ã¯
VideoFrameãäœæããååŸã«çã®ãã¯ã»ã«ããŒã¿ãå¹ççã«åŠçã§ããŸãã - Web Audio APIïŒãããªåŠçããªãŒãã£ãªæäœãšåæãããŠãå®å šãªã¡ãã£ã¢ãã€ãã©ã€ã³å¶åŸ¡ãå®çŸããŸãã
- IndexedDB/Cache APIïŒãªãã©ã€ã³ã¢ã¯ã»ã¹ãŸãã¯ããŒãæéã®ççž®ã®ããã«ãåŠçããããã¬ãŒã ãŸãã¯äºåã«ã¬ã³ããªã³ã°ãããã¢ã»ãããä¿åããŸãã
WebCodecsãšVideoFrameã®å°æ¥
WebCodecs APIãç¹ã«VideoFrameãªããžã§ã¯ãã¯ããŸã é²åããŠããŸãããã©ãŠã¶ã®å®è£
ãæçããæ°ããæ©èœã远å ãããã«ã€ããŠãããã«æŽç·Žããã髿§èœãªæ©èœãæåŸ
ã§ããŸãããã¬ã³ãã¯ããã©ãŠã¶åŽã®åŠçèœåã®åäžããµãŒããŒã€ã³ãã©ã¹ãã©ã¯ãã£ãžã®äŸå床ã®äœäžãããã³éçºè
ããããªããã§ã€ã³ã¿ã©ã¯ãã£ãã§ãããããŒãœãã©ã€ãºãããã¡ãã£ã¢ãšã¯ã¹ããªãšã³ã¹ãäœæã§ããããã«ããããšã«åãã£ãŠããŸãã
ãã®ãããªåŠçã®æ°äž»åã¯ã倧ããªæå³ãæã¡ãŸããããã¯ãå°èŠæš¡ãªããŒã ãšåã ã®éçºè ãã以åã¯ã€ã³ãã©ã¹ãã©ã¯ãã£ãŸãã¯ç¹æ®ãªãœãããŠã§ã¢ãžã®å€å€§ãªæè³ãå¿ èŠãšããŠããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããããã«ãªã£ãããšãæå³ããŸãããšã³ã¿ãŒãã€ã¡ã³ããæè²ããã³ãã¥ãã±ãŒã·ã§ã³ãç£æ¥ã¢ãã¿ãªã³ã°ãŸã§ãããããåéã§ã€ãããŒã·ã§ã³ãä¿é²ããé«åºŠãªãããªæäœãã°ããŒãã«ãªã¯ãªãšã€ã¿ãŒãšãŠãŒã¶ãŒã®ã³ãã¥ããã£ãå©çšã§ããããã«ããŸãã
çµè«
WebCodecs VideoFrameåŠçã¯ãWebããŒã¹ã®ãããªã«ãšã£ãŠå€§ããªé£èºã衚ããŠããŸããåã
ã®ãããªãã¬ãŒã ãžã®çŽæ¥çãå¹ççããã€ããŒã¬ãã«ãªã¢ã¯ã»ã¹ãæäŸããããšã«ãããéçºè
ã¯ãã©ãŠã¶ã§çŽæ¥å®è¡ããããæŽç·Žããããªã¢ã«ã¿ã€ã ãããªã¢ããªã±ãŒã·ã§ã³ã®æ°äžä»£ãæ§ç¯ã§ããŸãã匷åããããããªäŒè°ãã€ã³ã¿ã©ã¯ãã£ããªã¹ããªãŒãã³ã°ããã匷åãªãã©ãŠã¶ããŒã¹ã®ç·šéã¹ã€ãŒããé«åºŠãªã¢ã¯ã»ã·ããªãã£ããŒã«ãŸã§ããã®å¯èœæ§ã¯åºå€§ã§ãã°ããŒãã«ã«åœ±é¿ãäžããŸãã
VideoFrameã®æ
ã«ä¹ãåºããšãã¯ãããã©ãŒãã³ã¹ã®æé©åãæ
éãªã¡ã¢ãªç®¡çãããã³å
ç¢ãªãšã©ãŒåŠçã®éèŠæ§ãå¿ããªãã§ãã ãããWebã¯ãŒã«ãŒãWebGPUãããã³ãã®ä»ã®è£å®çãªAPIã®åãæŽ»çšããŠããã®ãšããµã€ãã£ã³ã°ãªãã¯ãããžãŒã®ãã¹ãŠã®æ©èœãè§£æŸããŠãã ãããWebãããªã®æªæ¥ã¯ããã«ããããããŸã§ä»¥äžã«ã€ã³ã¿ã©ã¯ãã£ãã§ãã€ã³ããªãžã§ã³ãã§ãã¢ã¯ã»ã¹ãããããªã£ãŠããŸãã仿¥ããå®éšãæ§ç¯ãããã³é©æ°ãéå§ããŠãã ãããã°ããŒãã«ãªèå°ãããªãã®åµé ãåŸ
ã£ãŠããŸãã