Last active
June 25, 2026 13:36
-
-
Save coderofsalvation/d38a95a20d30a4303d0a388dd51c487f to your computer and use it in GitHub Desktop.
go2rtc example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # download: https://github.com/AlexxIT/go2rtc/releases | |
| # homepage: https://go2rtc.org | |
| # usage: go2rtc -c go2rtc.yaml | |
| api: | |
| listen: "127.0.0.1:1989" | |
| log: | |
| level: "debug" | |
| streams: | |
| x11: | |
| exec:ffmpeg -f x11grab -i :0.0 -c copy -rtsp_transport tcp -framerate 30 -c:v libx264 -preset ultrafast -tune zerolatency -f rtsp {output} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| $ go2rtc -c go2rtc.yaml | |
| http://localhost:1989/api/ (+below) | |
| H264/H265 source | |
| stream.html WebRTC stream / browsers: all / codecs: H264, PCMU, PCMA, OPUS / +H265 in Safari | |
| stream.html MSE stream / browsers: Chrome, Firefox, Safari Mac/iPad / codecs: H264, H265*, AAC, PCMA*, PCMU*, PCM* / +OPUS in Chrome and Firefox | |
| stream.mp4 legacy MP4 stream with AAC audio / browsers: Chrome, Firefox / codecs: H264, H265*, AAC | |
| stream.mp4 modern MP4 stream with common audio / browsers: Chrome, Firefox / codecs: H264, H265*, AAC, FLAC (PCMA, PCMU, PCM) | |
| stream.mp4 MP4 stream with any audio / browsers: Chrome / codecs: H264, H265*, AAC, OPUS, MP3, FLAC (PCMA, PCMU, PCM) | |
| frame.mp4 snapshot in MP4-format / browsers: all / codecs: H264, H265* | |
| stream.m3u8 legacy HLS/TS / browsers: Safari all, Chrome Android / codecs: H264 | |
| stream.m3u8 legacy HLS/fMP4 / browsers: Safari all, Chrome Android / codecs: H264, H265*, AAC | |
| stream.m3u8 modern HLS/fMP4 / browsers: Safari all, Chrome Android / codecs: H264, H265*, AAC, FLAC (PCMA, PCMU, PCM) | |
| MJPEG source | |
| stream.html with MJPEG mode / browsers: all / codecs: MJPEG, JPEG | |
| stream.mjpeg MJPEG stream / browsers: all / codecs: MJPEG, JPEG | |
| frame.jpeg snapshot in JPEG-format / browsers: all / codecs: MJPEG, JPEG |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <fireboxroom> | |
| <assets> | |
| <assetvideo id="stream" src="http://localhost:1984/api/stream.mp4?src=x11" auto_play="true" loop="true" corsproxy="false"/> | |
| </assets> | |
| <room pos="0 -1 -2" corsproxy="false"> | |
| <object id="plane" video_id="stream" scale="1 1 1" rotation="0 180 0"/> | |
| </room> | |
| </fireboxroom> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta name="viewport" content="width=device-width, initial-scale=1"> | |
| <link rel="apple-touch-icon" href="https://alexxit.github.io/go2rtc/icons/apple-touch-icon-180x180.png" sizes="180x180"> | |
| <link rel="icon" href="https://alexxit.github.io/go2rtc/icons/favicon.ico"> | |
| <link rel="manifest" href="https://alexxit.github.io/go2rtc/manifest.json"> | |
| <title>go2rtc - Stream</title> | |
| <style> | |
| body { | |
| background: black; | |
| margin: 0; | |
| padding: 0; | |
| display: flex; | |
| font-family: Arial, Helvetica, sans-serif; | |
| } | |
| html, body { | |
| height: 100%; | |
| width: 100%; | |
| } | |
| .flex { | |
| flex-wrap: wrap; | |
| align-content: flex-start; | |
| align-items: flex-start; | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <script type="module" src="./video-stream.js"></script> | |
| <script type="module"> | |
| const params = new URLSearchParams(location.search); | |
| // support multiple streams and multiple modes | |
| const streams = params.getAll('src'); | |
| const modes = params.getAll('mode'); | |
| if (modes.length === 0) modes.push(''); | |
| while (modes.length > streams.length) { | |
| streams.push(streams[0]); | |
| } | |
| while (streams.length > modes.length) { | |
| modes.push(modes[0]); | |
| } | |
| if (streams.length > 1) { | |
| document.body.className = 'flex'; | |
| } | |
| const background = params.get('background') !== 'false'; | |
| const width = '1 0 ' + (params.get('width') || '320px'); | |
| for (let i = 0; i < streams.length; i++) { | |
| /** @type {VideoStream} */ | |
| const video = document.createElement('video-stream'); | |
| video.background = background; | |
| video.mode = modes[i] || video.mode; | |
| video.style.flex = width; | |
| video.src = new URL('api/ws?src=' + encodeURIComponent(streams[i]), location.href); | |
| document.body.appendChild(video); | |
| } | |
| </script> | |
| </body> | |
| </html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import {VideoRTC} from './video-rtc.js'; | |
| /** | |
| * This is example, how you can extend VideoRTC player for your app. | |
| * Also you can check this example: https://github.com/AlexxIT/WebRTC | |
| */ | |
| class VideoStream extends VideoRTC { | |
| set divMode(value) { | |
| this.querySelector('.mode').innerText = value; | |
| this.querySelector('.status').innerText = ''; | |
| } | |
| set divError(value) { | |
| const state = this.querySelector('.mode').innerText; | |
| if (state !== 'loading') return; | |
| this.querySelector('.mode').innerText = 'error'; | |
| this.querySelector('.status').innerText = value; | |
| } | |
| /** | |
| * Custom GUI | |
| */ | |
| oninit() { | |
| console.debug('stream.oninit'); | |
| super.oninit(); | |
| this.innerHTML = ` | |
| <style> | |
| video-stream { | |
| position: relative; | |
| } | |
| .info { | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| right: 0; | |
| padding: 12px; | |
| color: white; | |
| display: flex; | |
| justify-content: space-between; | |
| pointer-events: none; | |
| } | |
| </style> | |
| <div class="info"> | |
| <div class="status"></div> | |
| <div class="mode"></div> | |
| </div> | |
| `; | |
| const info = this.querySelector('.info'); | |
| this.insertBefore(this.video, info); | |
| } | |
| onconnect() { | |
| console.debug('stream.onconnect'); | |
| const result = super.onconnect(); | |
| if (result) this.divMode = 'loading'; | |
| return result; | |
| } | |
| ondisconnect() { | |
| console.debug('stream.ondisconnect'); | |
| super.ondisconnect(); | |
| } | |
| onopen() { | |
| console.debug('stream.onopen'); | |
| const result = super.onopen(); | |
| this.onmessage['stream'] = msg => { | |
| console.debug('stream.onmessge', msg); | |
| switch (msg.type) { | |
| case 'error': | |
| this.divError = msg.value; | |
| break; | |
| case 'mse': | |
| case 'hls': | |
| case 'mp4': | |
| case 'mjpeg': | |
| this.divMode = msg.type.toUpperCase(); | |
| break; | |
| } | |
| }; | |
| return result; | |
| } | |
| onclose() { | |
| console.debug('stream.onclose'); | |
| return super.onclose(); | |
| } | |
| onpcvideo(ev) { | |
| console.debug('stream.onpcvideo'); | |
| super.onpcvideo(ev); | |
| if (this.pcState !== WebSocket.CLOSED) { | |
| this.divMode = 'RTC'; | |
| } | |
| } | |
| } | |
| customElements.define('video-stream', VideoStream); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment