{"id":423,"date":"2026-06-30T09:13:12","date_gmt":"2026-06-30T00:13:12","guid":{"rendered":"https:\/\/www.marchboy.xyz\/wordpress\/?p=423"},"modified":"2026-06-30T09:16:55","modified_gmt":"2026-06-30T00:16:55","slug":"mediasoup%e5%85%a5%e9%96%80","status":"publish","type":"post","link":"https:\/\/www.marchboy.xyz\/wordpress\/archives\/423","title":{"rendered":"mediasoup\u5165\u9580"},"content":{"rendered":"<p>mediasoup\u5165\u9580\u30ac\u30a4\u30c9 \u2015 WebRTC SFU \u3092\u6d3b\u7528\u3057\u305f\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u901a\u4fe1\u306e\u5168\u8c8c<\/p>\n<p>\u8fd1\u5e74\u3001\u30aa\u30f3\u30e9\u30a4\u30f3\u30df\u30fc\u30c6\u30a3\u30f3\u30b0\u3084\u30e9\u30a4\u30d6\u914d\u4fe1\u3001\u30de\u30eb\u30c1\u30d7\u30ec\u30a4\u30e4\u30fc\u30b2\u30fc\u30e0\u306a\u3069\u3001\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u6027\u304c\u6c42\u3081\u3089\u308c\u308bWeb\u30a2\u30d7\u30ea\u304c\u6025\u5897\u3057\u3066\u3044\u307e\u3059\u3002\u305d\u306e\u4e2d\u3067 <strong>WebRTC<\/strong> \u306f\u30d6\u30e9\u30a6\u30b6\u9593\u306e\u76f4\u63a5\u901a\u4fe1\u3092\u5b9f\u73fe\u3059\u308b\u91cd\u8981\u6280\u8853\u3067\u3059\u304c\u3001\u8907\u6570\u53c2\u52a0\u8005\u304c\u540c\u6642\u306b\u6620\u50cf\u30fb\u97f3\u58f0\u3092\u3084\u308a\u53d6\u308a\u3059\u308b\u969b\u306b\u8ab2\u984c\u304c\u51fa\u3066\u304d\u307e\u3059\u3002\u305d\u3053\u3067\u767b\u5834\u3059\u308b\u306e\u304c <strong>SFU\uff08Selective Forwarding Unit\uff09<\/strong>\u3001\u305d\u3057\u3066 <strong>mediasoup<\/strong> \u3067\u3059\u3002<\/p>\n<h2>\u76ee\u6b21<\/h2>\n<ul>\n<li><a href=\"#what-is\">mediasoup \u3068\u306f\u4f55\u304b\uff1f<\/a><\/li>\n<li><a href=\"#architecture\">mediasoup \u306e\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3<\/a><\/li>\n<li><a href=\"#features\">\u4e3b\u8981\u6a5f\u80fd\u3068\u7279\u5fb4<\/a><\/li>\n<li><a href=\"#use-cases\">\u4ee3\u8868\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9<\/a><\/li>\n<li><a href=\"#getting-started\">\u59cb\u3081\u65b9\uff1a\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304b\u3089\u30b7\u30f3\u30d7\u30eb\u306a\u30b3\u30fc\u30c9\u4f8b\u307e\u3067<\/a><\/li>\n<li><a href=\"#best-practices\">\u5b9f\u88c5\u6642\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/a><\/li>\n<li><a href=\"#resources\">\u3055\u3089\u306b\u5b66\u3073\u305f\u3044\u65b9\u3078 \u2013 \u53c2\u8003\u30ea\u30bd\u30fc\u30b9<\/a><\/li>\n<\/ul>\n<h2 id=\"what-is\">mediasoup \u3068\u306f\u4f55\u304b\uff1f<\/h2>\n<p>mediasoup \u306f <strong>Node.js \u3067\u52d5\u4f5c\u3059\u308b\u30aa\u30fc\u30d7\u30f3\u30bd\u30fc\u30b9\u306e SFU \u30e9\u30a4\u30d6\u30e9\u30ea<\/strong>\u3067\u3059\u3002C++ \u306e\u30b3\u30a2\u3068 JavaScript \u306e\u30e9\u30c3\u30d1\u30fc\u3067\u69cb\u6210\u3055\u308c\u3066\u304a\u308a\u3001\u6b21\u306e\u3088\u3046\u306a\u7279\u9577\u304c\u3042\u308a\u307e\u3059\u3002<\/p>\n<ul>\n<li>\u9ad8\u6027\u80fd\u304b\u3064\u4f4e\u30ec\u30a4\u30c6\u30f3\u30b7\u2015\u306a\u30e1\u30c7\u30a3\u30a2\u8ee2\u9001\u3092\u5b9f\u73fe\u3002<\/li>\n<li>\u30de\u30eb\u30c1\u30c8\u30e9\u30c3\u30af\u3001\u30de\u30eb\u30c1\u30b9\u30c8\u30ea\u30fc\u30e0\u3001\u30b9\u30b1\u30fc\u30e9\u30d6\u30eb\u306a\u300c\u30eb\u30fc\u30e0\u300d\u8a2d\u8a08\u3002<\/li>\n<li>WebRTC \u306e\u6a19\u6e96 API \u306b\u3067\u304d\u308b\u3060\u3051\u5fe0\u5b9f\u306a\u30a4\u30f3\u30bf\u30fc\u30d5\u30a7\u30fc\u30b9\u3002<\/li>\n<li>\u30d7\u30e9\u30b0\u30a4\u30f3\u7684\u306b\u62e1\u5f35\u53ef\u80fd\u3067\u3001\u30ab\u30b9\u30bf\u30e0\u30eb\u30fc\u30c6\u30a3\u30f3\u30b0\u3084\u30c8\u30e9\u30f3\u30b9\u30b3\u30fc\u30c7\u30a3\u30f3\u30b0\u3082\u5b9f\u88c5\u53ef\u80fd\u3002<\/li>\n<\/ul>\n<h2 id=\"architecture\">mediasoup \u306e\u30a2\u30fc\u30ad\u30c6\u30af\u30c1\u30e3<\/h2>\n<p>mediasoup \u306e\u5185\u90e8\u306f\u4ee5\u4e0b\u306e\u30b3\u30f3\u30dd\u30fc\u30cd\u30f3\u30c8\u3067\u69cb\u6210\u3055\u308c\u307e\u3059\u3002<\/p>\n<h3>1. Router<\/h3>\n<p>\u5404\u300c\u4f1a\u8b70\u300d\u3084\u300c\u30eb\u30fc\u30e0\u300d\u306b\u5bfe\u5fdc\u3059\u308b\u8ad6\u7406\u7684\u306a\u30cf\u30d6\u3067\u3059\u3002Router \u306f <code>RtpCapabilities<\/code>\uff08\u53d7\u4fe1\u3067\u304d\u308b\u30b3\u30fc\u30c7\u30c3\u30af\u60c5\u5831\uff09\u3084 <code>RtpParameters<\/code>\uff08\u9001\u4fe1\u6642\u306e\u8a2d\u5b9a\uff09\u3092\u7ba1\u7406\u3057\u3001\u53c2\u52a0\u8005\u540c\u58eb\u306e\u30e1\u30c7\u30a3\u30a2\u8ee2\u9001\u7d4c\u8def\u3092\u6c7a\u5b9a\u3057\u307e\u3059\u3002<\/p>\n<h3>2. Transport<\/h3>\n<p>\u5b9f\u969b\u306e\u30c7\u30fc\u30bf\u8ee2\u9001\u306f <code>WebRtcTransport<\/code>\uff08UDP\/TLS\u30d9\u30fc\u30b9\u306e DTLS\uff09\u304b <code>PlainTransport<\/code>\uff08UDP\/TCP \u306e\u5358\u7d14\u306a\u8ee2\u9001\uff09\u3067\u884c\u308f\u308c\u307e\u3059\u3002\u5404\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306f\u81ea\u5206\u5c02\u7528\u306e Transport \u3092\u4f5c\u6210\u3057\u3001\u305d\u3053\u306b <code>Producer<\/code> \u3068 <code>Consumer<\/code> \u3092\u7d10\u4ed8\u3051\u307e\u3059\u3002<\/p>\n<h3>3. Producer \/ Consumer<\/h3>\n<ul>\n<li><strong>Producer<\/strong>\uff1a\u30d6\u30e9\u30a6\u30b6\u5074\u306e\u30ab\u30e1\u30e9\u30fb\u30de\u30a4\u30af\u304b\u3089\u9001\u3089\u308c\u305f\u30e1\u30c7\u30a3\u30a2\u30b9\u30c8\u30ea\u30fc\u30e0\u3092\u30b5\u30fc\u30d0\u306b\u9001\u4fe1\u3002<\/li>\n<li><strong>Consumer<\/strong>\uff1a\u4ed6\u306e\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u9001\u4fe1\u3057\u305f\u30b9\u30c8\u30ea\u30fc\u30e0\u3092\u53d7\u4fe1\u3057\u3001\u30d6\u30e9\u30a6\u30b6\u5074\u306b\u8ee2\u9001\u3002<\/li>\n<\/ul>\n<p>\u3053\u306e 1\u5bfeN \u306e\u30d1\u30bf\u30fc\u30f3\u306b\u3088\u308a\u3001\u30b5\u30fc\u30d0\u306f\u30e1\u30c7\u30a3\u30a2\u3092\u300c\u30b3\u30d4\u30fc\u300d\u305b\u305a\u306b\u52b9\u7387\u7684\u306b\u30d5\u30a9\u30ef\u30fc\u30c7\u30a3\u30f3\u30b0\u3067\u304d\u307e\u3059\u3002<\/p>\n<h2 id=\"features\">\u4e3b\u8981\u6a5f\u80fd\u3068\u7279\u5fb4<\/h2>\n<ul>\n<li><strong>\u30de\u30eb\u30c1\u30b3\u30fc\u30c9\u30c3\u30af\u5bfe\u5fdc<\/strong>\uff1aVP8\/VP9\/H.264\/AV1 \u306a\u3069\u3001\u4e3b\u8981\u306a\u30d3\u30c7\u30aa\u30b3\u30fc\u30c7\u30c3\u30af\u3068 Opus\/AAC \u306a\u3069\u97f3\u58f0\u30b3\u30fc\u30c7\u30c3\u30af\u3092\u30cd\u30a4\u30c6\u30a3\u30d6\u3067\u30b5\u30dd\u30fc\u30c8\u3002<\/li>\n<li><strong>Simulcast &amp; Scalable Video Coding (SVC)<\/strong>\uff1a\u5e2f\u57df\u306b\u5fdc\u3058\u305f\u89e3\u50cf\u5ea6\u3084\u30d5\u30ec\u30fc\u30e0\u30ec\u30fc\u30c8\u306e\u81ea\u52d5\u5207\u308a\u66ff\u3048\u3002<\/li>\n<li><strong>\u30aa\u30fc\u30c7\u30a3\u30aa\u30ec\u30d9\u30eb\u30fb\u97f3\u91cf\u6e2c\u5b9a<\/strong>\uff1a\u97f3\u58f0\u306e\u6d3b\u6027\u5316\u691c\u51fa\u3084\u97f3\u91cf\u30e1\u30fc\u30bf\u30fc\u8868\u793a\u304c\u5bb9\u6613\u3002<\/li>\n<li><strong>\u30d7\u30e9\u30b0\u30a4\u30f3\u53ef\u80fd\u306a\u30d3\u30c7\u30aa\u30a8\u30f3\u30b8\u30f3<\/strong>\uff1aSFU \u306e\u524d\u306b\u72ec\u81ea\u306e\u30a8\u30f3\u30b8\u30f3\uff08\u4f8b: AI\u9854\u8a8d\u8b58\u3001\u80cc\u666f\u5408\u6210\uff09\u3092\u5dee\u3057\u8fbc\u3081\u308b\u3002<\/li>\n<li><strong>\u7d30\u304b\u3044\u5e2f\u57df\u5236\u5fa1<\/strong>\uff1a\u5404 Consumer \u306b\u5bfe\u3057\u3066 <code>maxSpatialLayer<\/code> \u3084 <code>preferredBitrate<\/code> \u3092\u8a2d\u5b9a\u53ef\u80fd\u3002<\/li>\n<li><strong>\u7d71\u8a08\u53d6\u5f97 API<\/strong>\uff1a<code>getStats()<\/code> \u3067\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u306e\u30d1\u30b1\u30c3\u30c8\u30ed\u30b9\u3084\u30b8\u30c3\u30bf\u30fc\u3092\u53d6\u5f97\u3057\u3001QoE \u6539\u5584\u306b\u6d3b\u7528\u3002<\/li>\n<\/ul>\n<h2 id=\"use-cases\">\u4ee3\u8868\u7684\u306a\u30e6\u30fc\u30b9\u30b1\u30fc\u30b9<\/h2>\n<ol>\n<li><strong>\u5927\u898f\u6a21\u30aa\u30f3\u30e9\u30a4\u30f3\u4f1a\u8b70<\/strong>\uff08Zoom\u3001Microsoft Teams \u98a8\uff09<br \/>\n1,000 \u4eba\u898f\u6a21\u3067\u3082 <code>Router<\/code> \u3068 <code>Transport<\/code> \u3092\u6c34\u5e73\u5206\u5272\u3057\u3001\u8ca0\u8377\u3092\u5206\u6563\u3002<\/li>\n<li><strong>\u30e9\u30a4\u30d6\u30b9\u30c8\u30ea\u30fc\u30df\u30f3\u30b0 + \u53cc\u65b9\u5411\u30c1\u30e3\u30c3\u30c8<\/strong><br \/>\n\u30d7\u30ed\u30c7\u30e5\u30fc\u30b5\u30fc\u5074\u306f\u9ad8\u89e3\u50cf\u5ea6\u6620\u50cf\u3001\u8996\u8074\u8005\u306f\u4f4e\u89e3\u50cf\u5ea6\u306e\u6620\u50cf\u3068\u97f3\u58f0\u3060\u3051\u3092\u53d7\u4fe1\u3057\u3001\u8ca0\u8377\u3092\u6700\u5c0f\u5316\u3002<\/li>\n<li><strong>\u30b2\u30fc\u30e0\u5185\u30dc\u30a4\u30b9\u30c1\u30e3\u30c3\u30c8<\/strong><br \/>\n\u77ed\u3044\u97f3\u58f0\u30d1\u30b1\u30c3\u30c8\u3092\u4f4e\u30ec\u30a4\u30c6\u30f3\u30b7\u3067\u8ee2\u9001\u3057\u3001\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u6027\u304c\u6c42\u3081\u3089\u308c\u308b\u30b7\u30fc\u30f3\u306b\u6700\u9069\u3002<\/li>\n<li><strong>VR\/AR \u30b3\u30e9\u30dc\u30ec\u30fc\u30b7\u30e7\u30f3<\/strong><br \/>\n3D \u7a7a\u9593\u3067\u306e\u6620\u50cf\u30b9\u30c8\u30ea\u30fc\u30e0\u3092 simultane \u3067\u914d\u4fe1\u3057\u3001\u5404\u30e6\u30fc\u30b6\u30fc\u306e\u8996\u70b9\u306b\u5408\u308f\u305b\u3066\u89e3\u50cf\u5ea6\u3092\u8abf\u6574\u3002<\/li>\n<\/ol>\n<h2 id=\"getting-started\">\u59cb\u3081\u65b9\uff1a\u30a4\u30f3\u30b9\u30c8\u30fc\u30eb\u304b\u3089\u30b7\u30f3\u30d7\u30eb\u306a\u30b3\u30fc\u30c9\u4f8b\u307e\u3067<\/h2>\n<h3>1. \u524d\u63d0\u6761\u4ef6<\/h3>\n<ul>\n<li>Node.js \u2265 14\uff08LTS \u63a8\u5968\uff09<\/li>\n<li>npm \u307e\u305f\u306f yarn<\/li>\n<li>\u30b5\u30fc\u30d0\u306f UDP\/TCP \u306e 443\uff08TLS\uff09 \u3068 4443\uff08\u975e TLS\uff09\u3042\u305f\u308a\u306e\u30dd\u30fc\u30c8\u304c\u958b\u653e\u3055\u308c\u3066\u3044\u308b\u3053\u3068<\/li>\n<\/ul>\n<h3>2. \u30a4\u30f3\u30b9\u30c8\u30fc\u30eb<\/h3>\n<pre><code># npm\nnpm install mediasoup@latest\n\n# yarn\nyarn add mediasoup@latest\n<\/code><\/pre>\n<h3>3. \u57fa\u672c\u7684\u306a\u30b5\u30fc\u30d0\u69cb\u6210\u4f8b\uff08Node.js\uff09<\/h3>\n<pre><code>const http = require('http');\nconst express = require('express');\nconst socketIo = require('socket.io');\nconst mediasoup = require('mediasoup');\n\nconst app = express();\nconst server = http.createServer(app);\nconst io = socketIo(server);\n\nlet worker;          \/\/ mediasoup Worker\nlet router;          \/\/ 1 room \u7528 Router\n\n(async () =&gt; {\n  \/\/ 1\ufe0f\u20e3 Worker \u306e\u8d77\u52d5\n  worker = await mediasoup.createWorker({\n    rtcMinPort: 40000,\n    rtcMaxPort: 40100,\n    logLevel: 'warn',\n  });\n\n  \/\/ 2\ufe0f\u20e3 Router \u306e\u4f5c\u6210\uff08\u30d3\u30c7\u30aa\/\u30aa\u30fc\u30c7\u30a3\u30aa\u30b3\u30fc\u30c7\u30c3\u30af\u3092\u6307\u5b9a\uff09\n  router = await worker.createRouter({\n    mediaCodecs: [\n      {\n        kind: 'audio',\n        mimeType: 'audio\/opus',\n        clockRate: 48000,\n        channels: 2,\n      },\n      {\n        kind: 'video',\n        mimeType: 'video\/VP8',\n        clockRate: 90000,\n        parameters: { 'x-google-start-bitrate': 1000 },\n      },\n    ],\n  });\n\n  \/\/ 3\ufe0f\u20e3 Socket.io \u3067\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3068\u30b7\u30b0\u30ca\u30ea\u30f3\u30b0\n  io.on('connection', socket =&gt; {\n    console.log('Client connected:', socket.id);\n\n    \/\/ \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304c\u300e\u30c8\u30e9\u30f3\u30b9\u30dd\u30fc\u30c8\u4f5c\u6210\u8981\u6c42\u300f\u3092\u9001\u308b\n    socket.on('createWebRtcTransport', async ({ forceTcp }, callback) =&gt; {\n      const transport = await router.createWebRtcTransport({\n        listenIps: [{ ip: '0.0.0.0', announcedIp: 'YOUR_PUBLIC_IP' }],\n        enableTcp: forceTcp,\n        enableUdp: !forceTcp,\n        preferTcp: forceTcp,\n        maxIncomingBitrate: 1500000,\n      });\n\n      \/\/ Transport \u306e\u60c5\u5831\u3092\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u306b\u8fd4\u3059\n      callback({\n        id: transport.id,\n        iceParameters: transport.iceParameters,\n        iceCandidates: transport.iceCandidates,\n        dtlsParameters: transport.dtlsParameters,\n      });\n\n      \/\/ \u4ee5\u964d\u306f\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u304b\u3089\u306e DTLS \u7d42\u4e86\u901a\u77e5\u3092\u53d7\u3051\u53d6\u308b\n      socket.on('connectTransport', async ({ dtlsParameters }) =&gt; {\n        await transport.connect({ dtlsParameters });\n      });\n\n      \/\/ Producer \u767b\u9332\n      socket.on('produce', async ({ kind, rtpParameters }, prodCallback) =&gt; {\n        const producer = await transport.produce({ kind, rtpParameters });\n        prodCallback({ id: producer.id });\n        \/\/ \u4ed6\u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u3078 Consumer \u3092\u4f5c\u6210\u3059\u308b\u30ed\u30b8\u30c3\u30af\u306f\u5225\u9014\u5b9f\u88c5\n      });\n    });\n  });\n\n  \/\/ 4\ufe0f\u20e3 \u30b5\u30fc\u30d0\u8d77\u52d5\n  const PORT = process.env.PORT || 3000;\n  server.listen(PORT, () =&gt; console.log(`Server listening on ${PORT}`));\n})();\n<\/code><\/pre>\n<h3>4. \u30af\u30e9\u30a4\u30a2\u30f3\u30c8\u5074\uff08\u30d6\u30e9\u30a6\u30b6\uff09\u30b5\u30f3\u30d7\u30eb<\/h3>\n<p>\u4ee5\u4e0b\u306f <code>socket.io-client<\/code> \u3068\u6a19\u6e96 WebRTC API \u3092\u7d44\u307f\u5408\u308f\u305b\u305f\u6700\u5c0f\u69cb\u6210\u3067\u3059\u3002<\/p>\n<pre><code>import io from 'socket.io-client';\n\nconst socket = io('https:\/\/your-domain.com');\n\n\/\/ 1\ufe0f\u20e3 \u30e1\u30c7\u30a3\u30a2\u53d6\u5f97\nconst stream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });\n\n\/\/ 2\ufe0f\u20e3 Transport \u4f5c\u6210\u30ea\u30af\u30a8\u30b9\u30c8\nsocket.emit('createWebRtcTransport', { forceTcp: false }, async (transportInfo) =&gt; {\n  const pc = new RTCPeerConnection({\n    iceServers: [{ urls: 'stun:stun.l.google.com:19302' }],\n  });\n\n  \/\/ ICE &amp; DTLS \u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\n  transportInfo.iceCandidates.forEach(c =&gt; pc.addIceCandidate(c));\n  pc.setRemoteDescription({ type: 'offer', sdp: transportInfo.iceParameters });\n\n  \/\/ 3\ufe0f\u20e3 Transport \u63a5\u7d9a\n  socket.emit('connectTransport', { dtlsParameters: pc.getLocalDescription() });\n\n  \/\/ 4\ufe0f\u20e3 Producer\uff08\u6620\u50cf\uff09\u767b\u9332\n  const videoTrack = stream.getVideoTracks()[0];\n  const sender = pc.addTrack(videoTrack, stream);\n  const rtpParameters = sender.getParameters();\n\n  socket.emit('produce', { kind: 'video', rtpParameters }, ({ id }) =&gt; {\n    console.log('Producer created with id:', id);\n  });\n});\n\n\/\/ 5\ufe0f\u20e3 \u53d7\u4fe1\u5074\u306f\u5225\u9014 Consumer \u3092\u4f5c\u6210\u3057\u3001pc.addTrack() \u3067\u53d7\u4fe1\u30b9\u30c8\u30ea\u30fc\u30e0\u3092\u518d\u751f\n<\/code><\/pre>\n<h3>\u30dd\u30a4\u30f3\u30c8\u307e\u3068\u3081<\/h3>\n<ul>\n<li>mediasoup \u306f\u300c\u30b5\u30fc\u30d0\u5074\u3067\u8ee2\u9001\u300d\u3060\u3051\u3092\u884c\u3046\u306e\u3067\u3001CPU \u6d88\u8cbb\u306f\u6700\u5c0f\u9650\u306b\u6291\u3048\u3089\u308c\u307e\u3059\u3002<\/li>\n<li>\u30b7\u30b0\u30ca\u30ea\u30f3\u30b0\u306f\u597d\u304d\u306a\u30d7\u30ed\u30c8\u30b3\u30eb\uff08WebSocket, Socket.io, REST\uff09\u3067\u5b9f\u88c5\u53ef\u80fd\u3067\u3059\u3002<\/li>\n<li>\u5b9f\u969b\u306e\u30b5\u30fc\u30d3\u30b9\u3067\u306f\u300c\u90e8\u5c4b\u7ba1\u7406\u300d\u300c\u8a8d\u8a3c\u300d\u300c\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0\uff08Kubernetes \u3067\u30ef\u30fc\u30ab\u30fc\u30d7\u30fc\u30eb\uff09\u300d\u300c\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0\u300d\u7b49\u304c\u5fc5\u8981\u3067\u3059\u3002<\/li>\n<\/ul>\n<h2 id=\"best-practices\">\u5b9f\u88c5\u6642\u306e\u30d9\u30b9\u30c8\u30d7\u30e9\u30af\u30c6\u30a3\u30b9<\/h2>\n<h3>1. \u30ef\u30fc\u30ab\u30fc\u306e\u30b9\u30b1\u30fc\u30ea\u30f3\u30b0<\/h3>\n<p>CPU \u30b3\u30a2\u6570\u306b\u5408\u308f\u305b\u3066\u8907\u6570\u306e worker \u3092\u751f\u6210\u3057\u3001Router \u3092\u6c34\u5e73\u5206\u6563\u3055\u305b\u307e\u3059\u3002Kubernetes \u306e <code>Deployment<\/code> + <code>HorizontalPodAutoscaler<\/code> \u304c\u76f8\u6027\u629c\u7fa4\u3002<\/p>\n<h3>2. \u5e2f\u57df\u30fb\u30ec\u30a4\u30e4\u30fc\u5236\u5fa1<\/h3>\n<ul>\n<li>Simulcast\/SPATIAL \u5207\u66ff\u306f <code>consumer.setPreferredLayers()<\/code> \u3067\u5236\u5fa1\u3002<\/li>\n<li>\u9060\u9694\u30e6\u30fc\u30b6\u30fc\u306e\u56de\u7dda\u304c\u4e0d\u5b89\u5b9a\u306a\u5834\u5408\u306f <code>maxIncomingBitrate<\/code> \u3092\u7d5e\u3063\u3066\u30d1\u30b1\u30c3\u30c8\u30ed\u30b9\u3092\u6291\u5236\u3002<\/li>\n<\/ul>\n<h3>3. \u7d71\u8a08\u60c5\u5831\u306e\u6d3b\u7528<\/h3>\n<p>\u5b9a\u671f\u7684\u306b <code>router.getStats()<\/code> \u3068 <code>transport.getStats()<\/code> \u3092\u53d6\u5f97\u3057\u3001\u30a2\u30e9\u30fc\u30c8\u3084\u81ea\u52d5\u30ea\u30ab\u30d0\u30ea\u30ed\u30b8\u30c3\u30af\u3092\u69cb\u7bc9\u3002<\/p>\n<h3>4. \u30bb\u30ad\u30e5\u30ea\u30c6\u30a3<\/h3>\n<ul>\n<li>\u5fc5\u305a <strong>DTLS<\/strong> \u3068 <strong>SRTP<\/strong>\uff08\u30c7\u30d5\u30a9\u30eb\u30c8\uff09\u3067\u6697\u53f7\u5316\u3002<\/li>\n<li>\u8a8d\u8a3c\u30c8\u30fc\u30af\u30f3\uff08JWT\uff09\u3067 socket \u63a5\u7d9a\u3092\u4fdd\u8b77\u3057\u3001\u4e0d\u8981\u306a\u30eb\u30fc\u30e0\u30a2\u30af\u30bb\u30b9\u3092\u9632\u6b62\u3002<\/li>\n<li>\u30e1\u30c7\u30a3\u30a2\u30b5\u30fc\u30d0\u304c\u516c\u958b IP \u306b\u76f4\u63a5\u9732\u51fa\u3057\u306a\u3044\u3088\u3046\u3001\u30d5\u30a1\u30a4\u30a2\u30a6\u30a9\u30fc\u30eb\u3067 UDP\/443 \u306e\u307f\u958b\u653e\u3002<\/li>\n<\/ul>\n<h3>5. \u30ed\u30b0\u3068\u30e2\u30cb\u30bf\u30ea\u30f3\u30b0<\/h3>\n<p>mediasoup \u306f <code>worker.on('log', \u2026)<\/code> \u3067\u30ed\u30b0\u30ec\u30d9\u30eb\u3092\u5909\u66f4\u53ef\u80fd\u3002Prometheus exporter \u3084 Grafana \u30c0\u30c3\u30b7\u30e5\u30dc\u30fc\u30c9\u3092\u7d44\u307f\u5408\u308f\u305b\u308b\u3068\u904b\u7528\u304c\u697d\u3067\u3059\u3002<\/p>\n<h2 id=\"resources\">\u3055\u3089\u306b\u5b66\u3073\u305f\u3044\u65b9\u3078 \u2013 \u53c2\u8003\u30ea\u30bd\u30fc\u30b9<\/h2>\n<ul>\n<li>\u516c\u5f0f\u30ea\u30dd\u30b8\u30c8\u30ea &amp; \u30c9\u30ad\u30e5\u30e1\u30f3\u30c8 \u2013 <a href=\"https:\/\/mediasoup.org\" target=\"_blank\" rel=\"noopener\">mediasoup.org<\/a><\/li>\n<li>GitHub Issues &amp; Discussions \u2013 \u5b9f\u88c5\u4e0a\u306e\u7591\u554f\u306f\u3053\u3053\u3067\u691c\u7d22\u30fb\u8cea\u554f<\/li>\n<li>\u300cWebRTC &amp; mediasoup \u5165\u9580\u300d\u52d5\u753b\u30b7\u30ea\u30fc\u30ba\uff08YouTube\uff09 \u2013 \u5b9f\u969b\u306e\u30b3\u30fc\u30c9\u3068\u30c7\u30e2\u304c\u8c4a\u5bcc<\/li>\n<li>\u30b9\u30b1\u30fc\u30e9\u30d3\u30ea\u30c6\u30a3\u5b9f\u88c5\u4f8b \u2013 <a href=\"https:\/\/github.com\/versatica\/mediasoup-demo\" target=\"_blank\" rel=\"noopener\">mediasoup-demo<\/a><\/li>\n<li>Community Slack \u2013 <a href=\"https:\/\/join.slack.com\/t\/mediasoup\/shared_invite\/xyz\" target=\"_blank\" rel=\"noopener\">mediasoup Slack<\/a><\/li>\n<\/ul>\n<hr \/>\n<p>mediasoup \u306f\u300c\u9ad8\u5ea6\u306a\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u30b3\u30df\u30e5\u30cb\u30b1\u30fc\u30b7\u30e7\u30f3\u3092\u3001\u4f4e\u30b3\u30b9\u30c8\u304b\u3064\u30b9\u30b1\u30fc\u30e9\u30d6\u30eb\u306b\u5b9f\u88c5\u3057\u305f\u3044\u300d\u958b\u767a\u8005\u306b\u3068\u3063\u3066\u6700\u9069\u306a\u9078\u629e\u80a2\u3067\u3059\u3002\u3053\u306e\u8a18\u4e8b\u3067\u7d39\u4ecb\u3057\u305f\u6982\u5ff5\u3068\u30b5\u30f3\u30d7\u30eb\u30b3\u30fc\u30c9\u3092\u571f\u53f0\u306b\u3001\u305c\u3072\u81ea\u793e\u30b5\u30fc\u30d3\u30b9\u3084\u8da3\u5473\u306e\u30d7\u30ed\u30b8\u30a7\u30af\u30c8\u306b\u7d44\u307f\u8fbc\u3093\u3067\u307f\u3066\u304f\u3060\u3055\u3044\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>mediasoup\u5165\u9580\u30ac\u30a4\u30c9 \u2015 WebRTC SFU \u3092\u6d3b\u7528\u3057\u305f\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u901a\u4fe1\u306e\u5168\u8c8c \u8fd1\u5e74\u3001\u30aa\u30f3\u30e9\u30a4\u30f3\u30df\u30fc\u30c6\u30a3\u30f3\u30b0\u3084\u30e9\u30a4\u30d6\u914d\u4fe1\u3001\u30de\u30eb\u30c1\u30d7\u30ec\u30a4\u30e4\u30fc\u30b2\u30fc\u30e0\u306a\u3069\u3001\u30ea\u30a2\u30eb\u30bf\u30a4\u30e0\u6027\u304c\u6c42\u3081\u3089\u308c\u308bWeb\u30a2\u30d7\u30ea\u304c\u6025\u5897\u3057\u3066\u3044\u307e\u3059\u3002\u305d\u306e [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[],"class_list":["post-423","post","type-post","status-publish","format-standard","hentry","category-linux"],"_links":{"self":[{"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/posts\/423","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/comments?post=423"}],"version-history":[{"count":2,"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/posts\/423\/revisions"}],"predecessor-version":[{"id":425,"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/posts\/423\/revisions\/425"}],"wp:attachment":[{"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/media?parent=423"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/categories?post=423"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.marchboy.xyz\/wordpress\/wp-json\/wp\/v2\/tags?post=423"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}