diff --git a/api/index.php b/api/index.php new file mode 100644 index 0000000..a267093 --- /dev/null +++ b/api/index.php @@ -0,0 +1,90 @@ + uniqid('host_'), + 'participants' => [], + 'offer' => null, + 'host_candidates' => [], + 'participant_candidates' => [], + 'createdAt' => time() + ]; + saveRoomData($roomCode, $roomData); + echo json_encode(['roomCode' => $roomCode]); + break; + + case 'get-room-details': + $roomData = getRoomData($roomCode); + if ($roomData) { + echo json_encode($roomData); + } else { + http_response_code(404); + echo json_encode(['error' => 'Room not found']); + } + break; + + case 'signal': + $roomData = getRoomData($roomCode); + if ($roomData) { + $signal = json_decode(file_get_contents('php://input'), true); + if (isset($signal['offer'])) { + $roomData['offer'] = $signal['offer']; + } + if (isset($signal['answer'])) { + $roomData['answer'] = $signal['answer']; + } + if (isset($signal['candidate'])) { + if ($signal['isHost']) { + $roomData['host_candidates'][] = $signal['candidate']; + } else { + $roomData['participant_candidates'][] = $signal['candidate']; + } + } + saveRoomData($roomCode, $roomData); + echo json_encode(['success' => true]); + } else { + http_response_code(404); + echo json_encode(['error' => 'Room not found']); + } + break; + + default: + http_response_code(400); + echo json_encode(['error' => 'Invalid action']); +} diff --git a/api/rooms/31028b.json b/api/rooms/31028b.json new file mode 100644 index 0000000..bbe5439 --- /dev/null +++ b/api/rooms/31028b.json @@ -0,0 +1 @@ +{"host":"host_6944616ee8bc2","participants":[],"offer":{"sdp":"v=0\r\no=- 3413294180788668252 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS 33176d75-0788-4713-a15f-b183b3a366bb\r\nm=audio 9 UDP\/TLS\/RTP\/SAVPF 111 63 9 0 8 13 110 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:\/SLi\r\na=ice-pwd:Ky5LAtZ9zlFMIeggYnCDQiaD\r\na=ice-options:trickle\r\na=fingerprint:sha-256 9F:E9:06:5D:C7:AC:6C:9B:80:C7:66:63:45:96:D3:3D:9B:C3:F5:53:7D:72:AA:F6:88:6C:BE:77:41:54:9B:EE\r\na=setup:actpass\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=sendrecv\r\na=msid:33176d75-0788-4713-a15f-b183b3a366bb 8fd2dac3-60f0-45f9-980d-54bbcaa8367f\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:111 opus\/48000\/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red\/48000\/2\r\na=fmtp:63 111\/111\r\na=rtpmap:9 G722\/8000\r\na=rtpmap:0 PCMU\/8000\r\na=rtpmap:8 PCMA\/8000\r\na=rtpmap:13 CN\/8000\r\na=rtpmap:110 telephone-event\/48000\r\na=rtpmap:126 telephone-event\/8000\r\na=ssrc:2865566472 cname:Gp2sEBko0CE3nGQk\r\na=ssrc:2865566472 msid:33176d75-0788-4713-a15f-b183b3a366bb 8fd2dac3-60f0-45f9-980d-54bbcaa8367f\r\nm=video 9 UDP\/TLS\/RTP\/SAVPF 96 97 103 104 107 108 109 114 115 116 117 118 39 40 45 46 98 99 100 101 119 120 49 50 123 124 125\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:\/SLi\r\na=ice-pwd:Ky5LAtZ9zlFMIeggYnCDQiaD\r\na=ice-options:trickle\r\na=fingerprint:sha-256 9F:E9:06:5D:C7:AC:6C:9B:80:C7:66:63:45:96:D3:3D:9B:C3:F5:53:7D:72:AA:F6:88:6C:BE:77:41:54:9B:EE\r\na=setup:actpass\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:13 urn:3gpp:video-orientation\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/playout-delay\r\na=extmap:6 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-content-type\r\na=extmap:7 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-timing\r\na=extmap:8 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/color-space\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendrecv\r\na=msid:33176d75-0788-4713-a15f-b183b3a366bb 02335512-710c-4876-9558-5e749c8628ac\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8\/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx\/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:103 H264\/90000\r\na=rtcp-fb:103 goog-remb\r\na=rtcp-fb:103 transport-cc\r\na=rtcp-fb:103 ccm fir\r\na=rtcp-fb:103 nack\r\na=rtcp-fb:103 nack pli\r\na=fmtp:103 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\na=rtpmap:104 rtx\/90000\r\na=fmtp:104 apt=103\r\na=rtpmap:107 H264\/90000\r\na=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=rtcp-fb:107 ccm fir\r\na=rtcp-fb:107 nack\r\na=rtcp-fb:107 nack pli\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtpmap:108 rtx\/90000\r\na=fmtp:108 apt=107\r\na=rtpmap:109 H264\/90000\r\na=rtcp-fb:109 goog-remb\r\na=rtcp-fb:109 transport-cc\r\na=rtcp-fb:109 ccm fir\r\na=rtcp-fb:109 nack\r\na=rtcp-fb:109 nack pli\r\na=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:114 rtx\/90000\r\na=fmtp:114 apt=109\r\na=rtpmap:115 H264\/90000\r\na=rtcp-fb:115 goog-remb\r\na=rtcp-fb:115 transport-cc\r\na=rtcp-fb:115 ccm fir\r\na=rtcp-fb:115 nack\r\na=rtcp-fb:115 nack pli\r\na=fmtp:115 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtpmap:116 rtx\/90000\r\na=fmtp:116 apt=115\r\na=rtpmap:117 H264\/90000\r\na=rtcp-fb:117 goog-remb\r\na=rtcp-fb:117 transport-cc\r\na=rtcp-fb:117 ccm fir\r\na=rtcp-fb:117 nack\r\na=rtcp-fb:117 nack pli\r\na=fmtp:117 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f\r\na=rtpmap:118 rtx\/90000\r\na=fmtp:118 apt=117\r\na=rtpmap:39 H264\/90000\r\na=rtcp-fb:39 goog-remb\r\na=rtcp-fb:39 transport-cc\r\na=rtcp-fb:39 ccm fir\r\na=rtcp-fb:39 nack\r\na=rtcp-fb:39 nack pli\r\na=fmtp:39 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f\r\na=rtpmap:40 rtx\/90000\r\na=fmtp:40 apt=39\r\na=rtpmap:45 AV1\/90000\r\na=rtcp-fb:45 goog-remb\r\na=rtcp-fb:45 transport-cc\r\na=rtcp-fb:45 ccm fir\r\na=rtcp-fb:45 nack\r\na=rtcp-fb:45 nack pli\r\na=fmtp:45 level-idx=5;profile=0;tier=0\r\na=rtpmap:46 rtx\/90000\r\na=fmtp:46 apt=45\r\na=rtpmap:98 VP9\/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx\/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 VP9\/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 profile-id=2\r\na=rtpmap:101 rtx\/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:119 H264\/90000\r\na=rtcp-fb:119 goog-remb\r\na=rtcp-fb:119 transport-cc\r\na=rtcp-fb:119 ccm fir\r\na=rtcp-fb:119 nack\r\na=rtcp-fb:119 nack pli\r\na=fmtp:119 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f\r\na=rtpmap:120 rtx\/90000\r\na=fmtp:120 apt=119\r\na=rtpmap:49 H265\/90000\r\na=rtcp-fb:49 goog-remb\r\na=rtcp-fb:49 transport-cc\r\na=rtcp-fb:49 ccm fir\r\na=rtcp-fb:49 nack\r\na=rtcp-fb:49 nack pli\r\na=fmtp:49 level-id=123;profile-id=1;tier-flag=0;tx-mode=SRST\r\na=rtpmap:50 rtx\/90000\r\na=fmtp:50 apt=49\r\na=rtpmap:123 red\/90000\r\na=rtpmap:124 rtx\/90000\r\na=fmtp:124 apt=123\r\na=rtpmap:125 ulpfec\/90000\r\na=ssrc-group:FID 4241518844 1775357996\r\na=ssrc:4241518844 cname:Gp2sEBko0CE3nGQk\r\na=ssrc:4241518844 msid:33176d75-0788-4713-a15f-b183b3a366bb 02335512-710c-4876-9558-5e749c8628ac\r\na=ssrc:1775357996 cname:Gp2sEBko0CE3nGQk\r\na=ssrc:1775357996 msid:33176d75-0788-4713-a15f-b183b3a366bb 02335512-710c-4876-9558-5e749c8628ac\r\n","type":"offer"},"host_candidates":[{"candidate":"candidate:671262058 1 udp 2122260223 192.168.1.35 61065 typ host generation 0 ufrag \/SLi network-id 1 network-cost 10","sdpMid":"1","sdpMLineIndex":1,"usernameFragment":"\/SLi"},{"candidate":"candidate:671262058 1 udp 2122260223 192.168.1.35 61064 typ host generation 0 ufrag \/SLi network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"\/SLi"},{"candidate":"candidate:2269660244 1 udp 1686052607 110.235.236.71 61064 typ srflx raddr 192.168.1.35 rport 61064 generation 0 ufrag \/SLi network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"\/SLi"},{"candidate":"candidate:3601363454 1 tcp 1518280447 192.168.1.35 9 typ host tcptype active generation 0 ufrag \/SLi network-id 1 network-cost 10","sdpMid":"1","sdpMLineIndex":1,"usernameFragment":"\/SLi"},{"candidate":"candidate:3601363454 1 tcp 1518280447 192.168.1.35 9 typ host tcptype active generation 0 ufrag \/SLi network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"\/SLi"}],"participant_candidates":[{"candidate":"candidate:3266519066 1 udp 1677729535 152.59.204.59 59044 typ srflx raddr 192.0.0.4 rport 59044 generation 0 ufrag hWzc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"hWzc"},{"candidate":"candidate:3363013610 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 34558 typ host generation 0 ufrag hWzc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"hWzc"},{"candidate":"candidate:2105573526 1 udp 2113937151 192.0.0.4 59044 typ host generation 0 ufrag hWzc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"hWzc"},{"candidate":"candidate:3866464576 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 34558 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 34558 generation 0 ufrag hWzc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"hWzc"},{"candidate":"candidate:616156537 1 udp 2113937151 192.0.0.4 43901 typ host generation 0 ufrag 2Yod network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"2Yod"},{"candidate":"candidate:3346552650 1 udp 1677729535 152.59.204.59 43901 typ srflx raddr 192.0.0.4 rport 43901 generation 0 ufrag 2Yod network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"2Yod"},{"candidate":"candidate:3043666873 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 46599 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 46599 generation 0 ufrag 2Yod network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"2Yod"},{"candidate":"candidate:1154382749 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 50291 typ host generation 0 ufrag zaa1 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"zaa1"},{"candidate":"candidate:1791519031 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 50291 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 50291 generation 0 ufrag zaa1 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"zaa1"},{"candidate":"candidate:2126993791 1 udp 2113937151 192.0.0.4 47519 typ host generation 0 ufrag 7ZGz network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"7ZGz"},{"candidate":"candidate:1810717576 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 45797 typ host generation 0 ufrag 7ZGz network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"7ZGz"},{"candidate":"candidate:3696654583 1 udp 1677729535 152.59.204.59 47519 typ srflx raddr 192.0.0.4 rport 47519 generation 0 ufrag 7ZGz network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"7ZGz"},{"candidate":"candidate:3385658929 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 45797 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 45797 generation 0 ufrag 7ZGz network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"7ZGz"},{"candidate":"candidate:2589391388 1 udp 2113937151 192.0.0.4 48526 typ host generation 0 ufrag HbvZ network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"HbvZ"},{"candidate":"candidate:3113924513 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 45983 typ host generation 0 ufrag HbvZ network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"HbvZ"},{"candidate":"candidate:2039963695 1 udp 1677729535 152.59.204.59 48526 typ srflx raddr 192.0.0.4 rport 48526 generation 0 ufrag HbvZ network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"HbvZ"},{"candidate":"candidate:193305820 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 45983 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 45983 generation 0 ufrag HbvZ network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"HbvZ"},{"candidate":"candidate:2634220935 1 udp 2113937151 192.0.0.4 56775 typ host generation 0 ufrag O5xc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"O5xc"},{"candidate":"candidate:1831648218 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 54368 typ host generation 0 ufrag O5xc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"O5xc"},{"candidate":"candidate:705196281 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 54368 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 54368 generation 0 ufrag O5xc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"O5xc"},{"candidate":"candidate:1800667044 1 udp 1677729535 152.59.204.59 56775 typ srflx raddr 192.0.0.4 rport 56775 generation 0 ufrag O5xc network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"O5xc"},{"candidate":"candidate:3672088379 1 udp 2113937151 192.0.0.4 46381 typ host generation 0 ufrag ppNW network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"ppNW"},{"candidate":"candidate:4178825862 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 44751 typ host generation 0 ufrag ppNW network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"ppNW"},{"candidate":"candidate:958268680 1 udp 1677729535 152.59.204.59 46381 typ srflx raddr 192.0.0.4 rport 46381 generation 0 ufrag ppNW network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"ppNW"}],"createdAt":1766089070,"answer":{"sdp":"v=0\r\no=- 7045757228396801497 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=audio 9 UDP\/TLS\/RTP\/SAVPF 111 63 9 0 8 13 110 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:ppNW\r\na=ice-pwd:NM\/fzVh6G54XKgV0ReCI49wj\r\na=ice-options:trickle\r\na=fingerprint:sha-256 46:79:72:44:9C:EC:C0:22:58:A0:C4:0D:87:30:7F:55:E9:37:7D:35:E1:D8:78:0D:1C:E3:3C:7D:2B:E1:C7:2A\r\na=setup:active\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:111 opus\/48000\/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red\/48000\/2\r\na=fmtp:63 111\/111\r\na=rtpmap:9 G722\/8000\r\na=rtpmap:0 PCMU\/8000\r\na=rtpmap:8 PCMA\/8000\r\na=rtpmap:13 CN\/8000\r\na=rtpmap:110 telephone-event\/48000\r\na=rtpmap:126 telephone-event\/8000\r\nm=video 9 UDP\/TLS\/RTP\/SAVPF 96 97 103 104 107 108 109 114 115 116 117 118 39 40 45 46 98 99 100 101 119 120 49 50 123 124 125\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:ppNW\r\na=ice-pwd:NM\/fzVh6G54XKgV0ReCI49wj\r\na=ice-options:trickle\r\na=fingerprint:sha-256 46:79:72:44:9C:EC:C0:22:58:A0:C4:0D:87:30:7F:55:E9:37:7D:35:E1:D8:78:0D:1C:E3:3C:7D:2B:E1:C7:2A\r\na=setup:active\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:13 urn:3gpp:video-orientation\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/playout-delay\r\na=extmap:6 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-content-type\r\na=extmap:7 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-timing\r\na=extmap:8 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/color-space\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8\/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx\/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:103 H264\/90000\r\na=rtcp-fb:103 goog-remb\r\na=rtcp-fb:103 transport-cc\r\na=rtcp-fb:103 ccm fir\r\na=rtcp-fb:103 nack\r\na=rtcp-fb:103 nack pli\r\na=fmtp:103 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\na=rtpmap:104 rtx\/90000\r\na=fmtp:104 apt=103\r\na=rtpmap:107 H264\/90000\r\na=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=rtcp-fb:107 ccm fir\r\na=rtcp-fb:107 nack\r\na=rtcp-fb:107 nack pli\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtpmap:108 rtx\/90000\r\na=fmtp:108 apt=107\r\na=rtpmap:109 H264\/90000\r\na=rtcp-fb:109 goog-remb\r\na=rtcp-fb:109 transport-cc\r\na=rtcp-fb:109 ccm fir\r\na=rtcp-fb:109 nack\r\na=rtcp-fb:109 nack pli\r\na=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:114 rtx\/90000\r\na=fmtp:114 apt=109\r\na=rtpmap:115 H264\/90000\r\na=rtcp-fb:115 goog-remb\r\na=rtcp-fb:115 transport-cc\r\na=rtcp-fb:115 ccm fir\r\na=rtcp-fb:115 nack\r\na=rtcp-fb:115 nack pli\r\na=fmtp:115 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtpmap:116 rtx\/90000\r\na=fmtp:116 apt=115\r\na=rtpmap:117 H264\/90000\r\na=rtcp-fb:117 goog-remb\r\na=rtcp-fb:117 transport-cc\r\na=rtcp-fb:117 ccm fir\r\na=rtcp-fb:117 nack\r\na=rtcp-fb:117 nack pli\r\na=fmtp:117 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f\r\na=rtpmap:118 rtx\/90000\r\na=fmtp:118 apt=117\r\na=rtpmap:39 H264\/90000\r\na=rtcp-fb:39 goog-remb\r\na=rtcp-fb:39 transport-cc\r\na=rtcp-fb:39 ccm fir\r\na=rtcp-fb:39 nack\r\na=rtcp-fb:39 nack pli\r\na=fmtp:39 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f\r\na=rtpmap:40 rtx\/90000\r\na=fmtp:40 apt=39\r\na=rtpmap:45 AV1\/90000\r\na=rtcp-fb:45 goog-remb\r\na=rtcp-fb:45 transport-cc\r\na=rtcp-fb:45 ccm fir\r\na=rtcp-fb:45 nack\r\na=rtcp-fb:45 nack pli\r\na=fmtp:45 level-idx=5;profile=0;tier=0\r\na=rtpmap:46 rtx\/90000\r\na=fmtp:46 apt=45\r\na=rtpmap:98 VP9\/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx\/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 VP9\/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 profile-id=2\r\na=rtpmap:101 rtx\/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:119 H264\/90000\r\na=rtcp-fb:119 goog-remb\r\na=rtcp-fb:119 transport-cc\r\na=rtcp-fb:119 ccm fir\r\na=rtcp-fb:119 nack\r\na=rtcp-fb:119 nack pli\r\na=fmtp:119 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f\r\na=rtpmap:120 rtx\/90000\r\na=fmtp:120 apt=119\r\na=rtpmap:49 H265\/90000\r\na=rtcp-fb:49 goog-remb\r\na=rtcp-fb:49 transport-cc\r\na=rtcp-fb:49 ccm fir\r\na=rtcp-fb:49 nack\r\na=rtcp-fb:49 nack pli\r\na=fmtp:49 level-id=93;profile-id=1;tier-flag=0;tx-mode=SRST\r\na=rtpmap:50 rtx\/90000\r\na=fmtp:50 apt=49\r\na=rtpmap:123 red\/90000\r\na=rtpmap:124 rtx\/90000\r\na=fmtp:124 apt=123\r\na=rtpmap:125 ulpfec\/90000\r\n","type":"answer"}}0000\r\n","type":"answer"}} \ No newline at end of file diff --git a/api/rooms/6ce484.json b/api/rooms/6ce484.json new file mode 100644 index 0000000..7ccea8a --- /dev/null +++ b/api/rooms/6ce484.json @@ -0,0 +1 @@ +{"host":"host_694462ae2d640","participants":[],"offer":null,"host_candidates":[],"participant_candidates":[],"createdAt":1766089390} \ No newline at end of file diff --git a/api/rooms/a4412f.json b/api/rooms/a4412f.json new file mode 100644 index 0000000..4f6f65d --- /dev/null +++ b/api/rooms/a4412f.json @@ -0,0 +1 @@ +{"host":"host_6944616e8a5c9","participants":[],"offer":null,"host_candidates":[],"participant_candidates":[],"createdAt":1766089070} \ No newline at end of file diff --git a/api/rooms/ab99e6.json b/api/rooms/ab99e6.json new file mode 100644 index 0000000..c6e303c --- /dev/null +++ b/api/rooms/ab99e6.json @@ -0,0 +1 @@ +{"host":"host_694462ade7734","participants":[],"offer":null,"host_candidates":[],"participant_candidates":[],"createdAt":1766089389} \ No newline at end of file diff --git a/api/rooms/ec098a.json b/api/rooms/ec098a.json new file mode 100644 index 0000000..7a8074b --- /dev/null +++ b/api/rooms/ec098a.json @@ -0,0 +1 @@ +{"host":"host_694461f1b5e71","participants":[],"offer":{"sdp":"v=0\r\no=- 2509079247093481205 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS 9493daa8-168a-4d2b-a602-4a19f1d29471\r\nm=audio 9 UDP\/TLS\/RTP\/SAVPF 111 63 9 0 8 13 110 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:cU+E\r\na=ice-pwd:yUtP91Ib\/ynvZR6rla0coCax\r\na=ice-options:trickle\r\na=fingerprint:sha-256 CF:2A:11:FA:5D:EF:D7:98:50:A2:2C:D5:A1:75:0A:53:16:D5:79:7B:0B:98:0A:A3:E1:CD:CD:6A:0F:B0:64:B6\r\na=setup:actpass\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=sendrecv\r\na=msid:9493daa8-168a-4d2b-a602-4a19f1d29471 33fed82d-c40c-4162-b436-13c017a57ccf\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:111 opus\/48000\/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red\/48000\/2\r\na=fmtp:63 111\/111\r\na=rtpmap:9 G722\/8000\r\na=rtpmap:0 PCMU\/8000\r\na=rtpmap:8 PCMA\/8000\r\na=rtpmap:13 CN\/8000\r\na=rtpmap:110 telephone-event\/48000\r\na=rtpmap:126 telephone-event\/8000\r\na=ssrc:2174101789 cname:LXYpGhcO2rynA6J4\r\na=ssrc:2174101789 msid:9493daa8-168a-4d2b-a602-4a19f1d29471 33fed82d-c40c-4162-b436-13c017a57ccf\r\nm=video 9 UDP\/TLS\/RTP\/SAVPF 96 97 103 104 107 108 109 114 115 116 117 118 39 40 45 46 98 99 100 101 119 120 49 50 123 124 125\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:cU+E\r\na=ice-pwd:yUtP91Ib\/ynvZR6rla0coCax\r\na=ice-options:trickle\r\na=fingerprint:sha-256 CF:2A:11:FA:5D:EF:D7:98:50:A2:2C:D5:A1:75:0A:53:16:D5:79:7B:0B:98:0A:A3:E1:CD:CD:6A:0F:B0:64:B6\r\na=setup:actpass\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:13 urn:3gpp:video-orientation\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/playout-delay\r\na=extmap:6 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-content-type\r\na=extmap:7 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-timing\r\na=extmap:8 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/color-space\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendrecv\r\na=msid:9493daa8-168a-4d2b-a602-4a19f1d29471 fcb9464b-876d-48f4-a95a-e41a21ac4745\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8\/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx\/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:103 H264\/90000\r\na=rtcp-fb:103 goog-remb\r\na=rtcp-fb:103 transport-cc\r\na=rtcp-fb:103 ccm fir\r\na=rtcp-fb:103 nack\r\na=rtcp-fb:103 nack pli\r\na=fmtp:103 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\na=rtpmap:104 rtx\/90000\r\na=fmtp:104 apt=103\r\na=rtpmap:107 H264\/90000\r\na=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=rtcp-fb:107 ccm fir\r\na=rtcp-fb:107 nack\r\na=rtcp-fb:107 nack pli\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtpmap:108 rtx\/90000\r\na=fmtp:108 apt=107\r\na=rtpmap:109 H264\/90000\r\na=rtcp-fb:109 goog-remb\r\na=rtcp-fb:109 transport-cc\r\na=rtcp-fb:109 ccm fir\r\na=rtcp-fb:109 nack\r\na=rtcp-fb:109 nack pli\r\na=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:114 rtx\/90000\r\na=fmtp:114 apt=109\r\na=rtpmap:115 H264\/90000\r\na=rtcp-fb:115 goog-remb\r\na=rtcp-fb:115 transport-cc\r\na=rtcp-fb:115 ccm fir\r\na=rtcp-fb:115 nack\r\na=rtcp-fb:115 nack pli\r\na=fmtp:115 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtpmap:116 rtx\/90000\r\na=fmtp:116 apt=115\r\na=rtpmap:117 H264\/90000\r\na=rtcp-fb:117 goog-remb\r\na=rtcp-fb:117 transport-cc\r\na=rtcp-fb:117 ccm fir\r\na=rtcp-fb:117 nack\r\na=rtcp-fb:117 nack pli\r\na=fmtp:117 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f\r\na=rtpmap:118 rtx\/90000\r\na=fmtp:118 apt=117\r\na=rtpmap:39 H264\/90000\r\na=rtcp-fb:39 goog-remb\r\na=rtcp-fb:39 transport-cc\r\na=rtcp-fb:39 ccm fir\r\na=rtcp-fb:39 nack\r\na=rtcp-fb:39 nack pli\r\na=fmtp:39 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f\r\na=rtpmap:40 rtx\/90000\r\na=fmtp:40 apt=39\r\na=rtpmap:45 AV1\/90000\r\na=rtcp-fb:45 goog-remb\r\na=rtcp-fb:45 transport-cc\r\na=rtcp-fb:45 ccm fir\r\na=rtcp-fb:45 nack\r\na=rtcp-fb:45 nack pli\r\na=fmtp:45 level-idx=5;profile=0;tier=0\r\na=rtpmap:46 rtx\/90000\r\na=fmtp:46 apt=45\r\na=rtpmap:98 VP9\/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx\/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 VP9\/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 profile-id=2\r\na=rtpmap:101 rtx\/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:119 H264\/90000\r\na=rtcp-fb:119 goog-remb\r\na=rtcp-fb:119 transport-cc\r\na=rtcp-fb:119 ccm fir\r\na=rtcp-fb:119 nack\r\na=rtcp-fb:119 nack pli\r\na=fmtp:119 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f\r\na=rtpmap:120 rtx\/90000\r\na=fmtp:120 apt=119\r\na=rtpmap:49 H265\/90000\r\na=rtcp-fb:49 goog-remb\r\na=rtcp-fb:49 transport-cc\r\na=rtcp-fb:49 ccm fir\r\na=rtcp-fb:49 nack\r\na=rtcp-fb:49 nack pli\r\na=fmtp:49 level-id=123;profile-id=1;tier-flag=0;tx-mode=SRST\r\na=rtpmap:50 rtx\/90000\r\na=fmtp:50 apt=49\r\na=rtpmap:123 red\/90000\r\na=rtpmap:124 rtx\/90000\r\na=fmtp:124 apt=123\r\na=rtpmap:125 ulpfec\/90000\r\na=ssrc-group:FID 3926586293 1017430750\r\na=ssrc:3926586293 cname:LXYpGhcO2rynA6J4\r\na=ssrc:3926586293 msid:9493daa8-168a-4d2b-a602-4a19f1d29471 fcb9464b-876d-48f4-a95a-e41a21ac4745\r\na=ssrc:1017430750 cname:LXYpGhcO2rynA6J4\r\na=ssrc:1017430750 msid:9493daa8-168a-4d2b-a602-4a19f1d29471 fcb9464b-876d-48f4-a95a-e41a21ac4745\r\n","type":"offer"},"host_candidates":[{"candidate":"candidate:3993187874 1 udp 2122260223 192.168.1.35 56902 typ host generation 0 ufrag cU+E network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"cU+E"},{"candidate":"candidate:3993187874 1 udp 2122260223 192.168.1.35 56903 typ host generation 0 ufrag cU+E network-id 1 network-cost 10","sdpMid":"1","sdpMLineIndex":1,"usernameFragment":"cU+E"},{"candidate":"candidate:2935571595 1 udp 1686052607 110.235.236.71 56903 typ srflx raddr 192.168.1.35 rport 56903 generation 0 ufrag cU+E network-id 1 network-cost 10","sdpMid":"1","sdpMLineIndex":1,"usernameFragment":"cU+E"},{"candidate":"candidate:2935571595 1 udp 1686052607 110.235.236.71 56902 typ srflx raddr 192.168.1.35 rport 56902 generation 0 ufrag cU+E network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"cU+E"},{"candidate":"candidate:2429342906 1 tcp 1518280447 192.168.1.35 9 typ host tcptype active generation 0 ufrag cU+E network-id 1 network-cost 10","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"cU+E"},{"candidate":"candidate:2429342906 1 tcp 1518280447 192.168.1.35 9 typ host tcptype active generation 0 ufrag cU+E network-id 1 network-cost 10","sdpMid":"1","sdpMLineIndex":1,"usernameFragment":"cU+E"}],"participant_candidates":[{"candidate":"candidate:3082498993 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 35484 typ host generation 0 ufrag LI\/N network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"LI\/N"},{"candidate":"candidate:38285517 1 udp 2113937151 192.0.0.4 56423 typ host generation 0 ufrag LI\/N network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"LI\/N"},{"candidate":"candidate:3178991681 1 udp 1677729535 152.59.204.59 56423 typ srflx raddr 192.0.0.4 rport 56423 generation 0 ufrag LI\/N network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"LI\/N"},{"candidate":"candidate:2579308827 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 35484 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 35484 generation 0 ufrag LI\/N network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"LI\/N"},{"candidate":"candidate:2882032921 1 udp 2113937151 192.0.0.4 60992 typ host generation 0 ufrag tCa7 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"tCa7"},{"candidate":"candidate:3202504686 1 udp 2113939711 2409:40f0:4a:52c4:8000:: 60082 typ host generation 0 ufrag tCa7 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"tCa7"},{"candidate":"candidate:156857489 1 udp 1677729535 152.59.204.59 60992 typ srflx raddr 192.0.0.4 rport 60992 generation 0 ufrag tCa7 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"tCa7"},{"candidate":"candidate:482476631 1 udp 1677732095 2409:40f0:4a:52c4:8000:: 60082 typ srflx raddr 2409:40f0:4a:52c4:8000:: rport 60082 generation 0 ufrag tCa7 network-cost 999","sdpMid":"0","sdpMLineIndex":0,"usernameFragment":"tCa7"}],"createdAt":1766089201,"answer":{"sdp":"v=0\r\no=- 5233570653005384314 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=audio 9 UDP\/TLS\/RTP\/SAVPF 111 63 9 0 8 13 110 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:tCa7\r\na=ice-pwd:dN4iPBv4gISlA2OuA4PxmsZM\r\na=ice-options:trickle\r\na=fingerprint:sha-256 B1:EF:40:A2:82:D1:DF:D4:FD:78:4D:4F:51:45:07:2D:6C:9C:78:89:F8:29:47:4C:66:40:36:9B:75:A7:58:5C\r\na=setup:active\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:111 opus\/48000\/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red\/48000\/2\r\na=fmtp:63 111\/111\r\na=rtpmap:9 G722\/8000\r\na=rtpmap:0 PCMU\/8000\r\na=rtpmap:8 PCMA\/8000\r\na=rtpmap:13 CN\/8000\r\na=rtpmap:110 telephone-event\/48000\r\na=rtpmap:126 telephone-event\/8000\r\nm=video 9 UDP\/TLS\/RTP\/SAVPF 96 97 103 104 107 108 109 114 115 116 117 118 39 40 45 46 98 99 100 101 119 120 49 50 123 124 125\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:tCa7\r\na=ice-pwd:dN4iPBv4gISlA2OuA4PxmsZM\r\na=ice-options:trickle\r\na=fingerprint:sha-256 B1:EF:40:A2:82:D1:DF:D4:FD:78:4D:4F:51:45:07:2D:6C:9C:78:89:F8:29:47:4C:66:40:36:9B:75:A7:58:5C\r\na=setup:active\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/abs-send-time\r\na=extmap:13 urn:3gpp:video-orientation\r\na=extmap:3 http:\/\/www.ietf.org\/id\/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/playout-delay\r\na=extmap:6 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-content-type\r\na=extmap:7 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/video-timing\r\na=extmap:8 http:\/\/www.webrtc.org\/experiments\/rtp-hdrext\/color-space\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8\/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx\/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:103 H264\/90000\r\na=rtcp-fb:103 goog-remb\r\na=rtcp-fb:103 transport-cc\r\na=rtcp-fb:103 ccm fir\r\na=rtcp-fb:103 nack\r\na=rtcp-fb:103 nack pli\r\na=fmtp:103 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\na=rtpmap:104 rtx\/90000\r\na=fmtp:104 apt=103\r\na=rtpmap:107 H264\/90000\r\na=rtcp-fb:107 goog-remb\r\na=rtcp-fb:107 transport-cc\r\na=rtcp-fb:107 ccm fir\r\na=rtcp-fb:107 nack\r\na=rtcp-fb:107 nack pli\r\na=fmtp:107 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtpmap:108 rtx\/90000\r\na=fmtp:108 apt=107\r\na=rtpmap:109 H264\/90000\r\na=rtcp-fb:109 goog-remb\r\na=rtcp-fb:109 transport-cc\r\na=rtcp-fb:109 ccm fir\r\na=rtcp-fb:109 nack\r\na=rtcp-fb:109 nack pli\r\na=fmtp:109 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:114 rtx\/90000\r\na=fmtp:114 apt=109\r\na=rtpmap:115 H264\/90000\r\na=rtcp-fb:115 goog-remb\r\na=rtcp-fb:115 transport-cc\r\na=rtcp-fb:115 ccm fir\r\na=rtcp-fb:115 nack\r\na=rtcp-fb:115 nack pli\r\na=fmtp:115 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtpmap:116 rtx\/90000\r\na=fmtp:116 apt=115\r\na=rtpmap:117 H264\/90000\r\na=rtcp-fb:117 goog-remb\r\na=rtcp-fb:117 transport-cc\r\na=rtcp-fb:117 ccm fir\r\na=rtcp-fb:117 nack\r\na=rtcp-fb:117 nack pli\r\na=fmtp:117 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f\r\na=rtpmap:118 rtx\/90000\r\na=fmtp:118 apt=117\r\na=rtpmap:39 H264\/90000\r\na=rtcp-fb:39 goog-remb\r\na=rtcp-fb:39 transport-cc\r\na=rtcp-fb:39 ccm fir\r\na=rtcp-fb:39 nack\r\na=rtcp-fb:39 nack pli\r\na=fmtp:39 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f\r\na=rtpmap:40 rtx\/90000\r\na=fmtp:40 apt=39\r\na=rtpmap:45 AV1\/90000\r\na=rtcp-fb:45 goog-remb\r\na=rtcp-fb:45 transport-cc\r\na=rtcp-fb:45 ccm fir\r\na=rtcp-fb:45 nack\r\na=rtcp-fb:45 nack pli\r\na=fmtp:45 level-idx=5;profile=0;tier=0\r\na=rtpmap:46 rtx\/90000\r\na=fmtp:46 apt=45\r\na=rtpmap:98 VP9\/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx\/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 VP9\/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 profile-id=2\r\na=rtpmap:101 rtx\/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:119 H264\/90000\r\na=rtcp-fb:119 goog-remb\r\na=rtcp-fb:119 transport-cc\r\na=rtcp-fb:119 ccm fir\r\na=rtcp-fb:119 nack\r\na=rtcp-fb:119 nack pli\r\na=fmtp:119 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=64001f\r\na=rtpmap:120 rtx\/90000\r\na=fmtp:120 apt=119\r\na=rtpmap:49 H265\/90000\r\na=rtcp-fb:49 goog-remb\r\na=rtcp-fb:49 transport-cc\r\na=rtcp-fb:49 ccm fir\r\na=rtcp-fb:49 nack\r\na=rtcp-fb:49 nack pli\r\na=fmtp:49 level-id=93;profile-id=1;tier-flag=0;tx-mode=SRST\r\na=rtpmap:50 rtx\/90000\r\na=fmtp:50 apt=49\r\na=rtpmap:123 red\/90000\r\na=rtpmap:124 rtx\/90000\r\na=fmtp:124 apt=123\r\na=rtpmap:125 ulpfec\/90000\r\n","type":"answer"}} \ No newline at end of file diff --git a/api/rooms/f38da9.json b/api/rooms/f38da9.json new file mode 100644 index 0000000..4b2113a --- /dev/null +++ b/api/rooms/f38da9.json @@ -0,0 +1 @@ +{"host":"host_694461f172d06","participants":[],"offer":null,"host_candidates":[],"participant_candidates":[],"createdAt":1766089201} \ No newline at end of file diff --git a/assets/css/custom.css b/assets/css/custom.css new file mode 100644 index 0000000..828c99f --- /dev/null +++ b/assets/css/custom.css @@ -0,0 +1,36 @@ + +body { + background-color: #F4F7F6; + background-image: linear-gradient(135deg, rgba(0,123,255,0.05) 0%, rgba(255,255,255,0) 25%); + font-family: 'Georgia', serif; +} + +.display-4 { + font-family: system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + font-weight: 700; +} + +.card { + border: 1px solid rgba(0,0,0,0.08); + box-shadow: 0 4px 12px rgba(0,0,0,0.06); + transition: transform 0.2s ease-in-out, box-shadow 0.2s ease-in-out; +} + +.card:hover { + transform: translateY(-5px); + box-shadow: 0 8px 24px rgba(0,0,0,0.08); +} + +.form-control-lg { + text-align: center; + font-family: monospace; + letter-spacing: 0.5em; +} + +.btn-lg { + padding: 0.75rem 1.5rem; +} + +.toast-container { + z-index: 1090; +} diff --git a/assets/js/main.js b/assets/js/main.js new file mode 100644 index 0000000..26d2434 --- /dev/null +++ b/assets/js/main.js @@ -0,0 +1,346 @@ +document.addEventListener('DOMContentLoaded', function () { + const API_URL = './api/'; + + // --- Main UI Elements --- + const selectionContainer = document.getElementById('selection-container'); + const hostPanelContainer = document.getElementById('host-panel-container'); + const participantPanelContainer = document.getElementById('participant-panel-container'); + const toastContainer = document.querySelector('.toast-container'); + + // --- Room Joining Elements --- + const joinCodeInput = document.getElementById('join-code'); + const joinRoomBtn = document.getElementById('join-room-btn'); + + // --- Room Creation Elements --- + const createRoomBtn = document.getElementById('create-room-btn'); + + // --- Host Panel Elements --- + const hostRoomCodeDisplay = document.getElementById('host-room-code'); + const hostStatusDisplay = document.getElementById('host-status'); + const startStreamingBtn = document.getElementById('start-streaming-btn'); + const deleteRoomBtn = document.getElementById('delete-room-btn'); + + // --- Participant Panel Elements --- + const participantStatusDisplay = document.getElementById('participant-status'); + const participantAudio = document.getElementById('participant-audio'); + const leaveRoomBtn = document.getElementById('leave-room-btn'); + + // --- State Management --- + let localAudioStream = null; + let peerConnection = null; + let roomCode = null; + let isHost = false; + + // =================================================================== + // 1. EVENT LISTENERS + // =================================================================== + + if (joinCodeInput) { + joinCodeInput.addEventListener('input', () => { + joinRoomBtn.disabled = joinCodeInput.value.length < 6; + }); + } + + if (joinRoomBtn) { + joinRoomBtn.addEventListener('click', () => { + const code = joinCodeInput.value.toLowerCase(); + joinRoom(code); + }); + } + + if (createRoomBtn) { + createRoomBtn.addEventListener('click', createRoom); + } + + if (startStreamingBtn) { + startStreamingBtn.addEventListener('click', () => { + if (localAudioStream) { + stopStreaming(); + } else { + startStreaming(); + } + }); + } + + if (deleteRoomBtn) { + deleteRoomBtn.addEventListener('click', () => { + stopStreaming(); + // TODO: Add server-side room deletion + hostPanelContainer.classList.add('d-none'); + selectionContainer.classList.remove('d-none'); + showToast('Room has been closed.'); + }); + } + + if (leaveRoomBtn) { + leaveRoomBtn.addEventListener('click', () => { + if (peerConnection) { + peerConnection.close(); + } + participantPanelContainer.classList.add('d-none'); + selectionContainer.classList.remove('d-none'); + showToast('You have left the room.'); + }); + } + + // =================================================================== + // 2. API & ROOM MANAGEMENT + // =================================================================== + + async function createRoom() { + try { + const response = await fetch(`${API_URL}?action=create-room`); + const data = await response.json(); + if (data.roomCode) { + roomCode = data.roomCode; + isHost = true; + hostRoomCodeDisplay.textContent = roomCode; + selectionContainer.classList.add('d-none'); + hostPanelContainer.classList.remove('d-none'); + showToast('Your room is live!', 'success'); + listenForSignals(); + } + } catch (error) { + console.error('Error creating room:', error); + showToast('Could not create room. Please try again.', 'danger'); + } + } + + async function joinRoom(code) { + try { + const response = await fetch(`${API_URL}?action=get-room-details&roomCode=${code}`); + if (!response.ok) throw new Error('Room not found'); + + const data = await response.json(); + roomCode = code; + isHost = false; + + selectionContainer.classList.add('d-none'); + participantPanelContainer.classList.remove('d-none'); + updateParticipantStatus('joining'); + + await setupParticipantConnection(data); + listenForSignals(); + + } catch (error) { + console.error('Error joining room:', error); + showToast(`Could not join room: ${error.message}`, 'danger'); + } + } + + // =================================================================== + // 3. CORE STREAMING LOGIC (WebRTC) + // =================================================================== + + async function startStreaming() { + updateHostStatus('connecting'); + try { + const stream = await navigator.mediaDevices.getDisplayMedia({ audio: true, video: true }); + + if (stream.getAudioTracks().length === 0) { + stream.getTracks().forEach(track => track.stop()); + showToast('No audio was shared. Please enable audio sharing.', 'danger'); + updateHostStatus('error'); + return; + } + + localAudioStream = stream; + updateHostStatus('streaming'); + showToast('Streaming started! Waiting for a participant...', 'success'); + + stream.getAudioTracks()[0].onended = () => stopStreaming(); + + // --- WebRTC Host Logic --- + peerConnection = createPeerConnection(); + stream.getTracks().forEach(track => peerConnection.addTrack(track, stream)); + + const offer = await peerConnection.createOffer(); + await peerConnection.setLocalDescription(offer); + + await signal({ offer }); + + } catch (err) { + console.error('Streaming Error:', err); + updateHostStatus('error'); + showToast('Could not start streaming.', 'danger'); + } + } + + function stopStreaming() { + if (localAudioStream) { + localAudioStream.getTracks().forEach(track => track.stop()); + localAudioStream = null; + } + if (peerConnection) { + peerConnection.close(); + peerConnection = null; + } + updateHostStatus('idle'); + console.log('Streaming stopped.'); + } + + async function setupParticipantConnection(roomData) { + peerConnection = createPeerConnection(); + peerConnection.ontrack = (event) => { + updateParticipantStatus('playing'); + participantAudio.srcObject = event.streams[0]; + participantAudio.play(); + }; + + await peerConnection.setRemoteDescription(new RTCSessionDescription(roomData.offer)); + const answer = await peerConnection.createAnswer(); + await peerConnection.setLocalDescription(answer); + + await signal({ answer }); + + // Add host's ICE candidates + if (roomData.host_candidates) { + for (const candidate of roomData.host_candidates) { + await peerConnection.addIceCandidate(new RTCIceCandidate(candidate)); + } + } + } + + + function createPeerConnection() { + const pc = new RTCPeerConnection({ + iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] + }); + + pc.onicecandidate = event => { + if (event.candidate) { + signal({ candidate: event.candidate }); + } + }; + + pc.oniceconnectionstatechange = () => { + console.log('ICE Connection State:', pc.iceConnectionState); + if (isHost) { + if (pc.iceConnectionState === 'connected') { + showToast('A participant has connected!', 'success'); + } + } else { + if (pc.iceConnectionState === 'failed' || pc.iceConnectionState === 'disconnected') { + updateParticipantStatus('error'); + } + } + }; + + return pc; + } + + async function signal(data) { + await fetch(`${API_URL}?action=signal&roomCode=${roomCode}`, { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ ...data, isHost }) + }); + } + + // Basic polling to get signals from the other party + async function listenForSignals() { + const interval = setInterval(async () => { + try { + const response = await fetch(`${API_URL}?action=get-room-details&roomCode=${roomCode}`); + const data = await response.json(); + + if (peerConnection && peerConnection.signalingState === 'stable') return; + + + if (isHost && data.answer && peerConnection.signalingState !== 'stable') { + await peerConnection.setRemoteDescription(new RTCSessionDescription(data.answer)); + // Add participant's ICE candidates + if (data.participant_candidates) { + for (const candidate of data.participant_candidates) { + await peerConnection.addIceCandidate(new RTCIceCandidate(candidate)); + } + } + } + + } catch (error) { + // console.error('Signaling listener error:', error); + } + }, 3000); + // Note: In a real app, you'd use WebSockets instead of polling. + } + + + // =================================================================== + // 4. UI HELPER FUNCTIONS + // =================================================================== + + function updateHostStatus(status) { + startStreamingBtn.disabled = false; + let content = ''; + switch (status) { + case 'connecting': + startStreamingBtn.disabled = true; + content = `
Requesting permission...`; + hostStatusDisplay.className = 'alert alert-warning'; + break; + case 'streaming': + startStreamingBtn.innerHTML = ' Stop Streaming'; + startStreamingBtn.className = 'btn btn-danger btn-lg'; + content = ` Now streaming... Waiting for connections.`; + hostStatusDisplay.className = 'alert alert-success'; + break; + case 'error': + content = ' Could not start streaming.'; + hostStatusDisplay.className = 'alert alert-danger'; + break; + case 'idle': + default: + startStreamingBtn.innerHTML = ' Start Streaming'; + startStreamingBtn.className = 'btn btn-success btn-lg'; + content = 'Not currently streaming.'; + hostStatusDisplay.className = 'alert alert-info'; + break; + } + hostStatusDisplay.innerHTML = content; + } + + function updateParticipantStatus(status) { + let content = ''; + switch (status) { + case 'joining': + content = `

Connecting to host...

`; + participantStatusDisplay.className = 'alert alert-info'; + break; + case 'playing': + content = ` Live audio is playing.`; + participantStatusDisplay.className = 'alert alert-success'; + break; + case 'error': + content = ' Connection lost. Please try rejoining.'; + participantStatusDisplay.className = 'alert alert-danger'; + if (participantAudio.srcObject) { + participantAudio.srcObject.getTracks().forEach(track => track.stop()); + participantAudio.srcObject = null; + } + break; + } + participantStatusDisplay.innerHTML = content; + } + + function showToast(message, type = 'info') { + if (!toastContainer) return; + const bgClass = { + info: 'bg-primary', + success: 'bg-success', + danger: 'bg-danger' + }[type] || 'bg-primary'; + const toastEl = document.createElement('div'); + toastEl.className = `toast align-items-center text-white ${bgClass} border-0`; + toastEl.setAttribute('role', 'alert'); + toastEl.innerHTML = ` +
+
${message}
+ +
+ `; + toastContainer.appendChild(toastEl); + const toast = new bootstrap.Toast(toastEl, { delay: 5000 }); + toast.show(); + toastEl.addEventListener('hidden.bs.toast', () => toastEl.remove()); + } +}); \ No newline at end of file diff --git a/index.php b/index.php index 7205f3d..bc51af0 100644 --- a/index.php +++ b/index.php @@ -1,150 +1,131 @@ - + - - - New Style - - - - - - - - - - - - - - - - - - - + + + <?php echo htmlspecialchars($project_name); ?> + + + + + + + + + + + + + + + + + + + -
-
-

Analyzing your requirements and generating your website…

-
- Loading… -
-

AI is collecting your requirements and applying the first changes.

-

This page will update automatically as the plan is implemented.

-

Runtime: PHP — UTC

-
-
- + +
+
+
+ +
+

LiveAudio Rooms

+

Share your device audio in real-time. Create a room or join with a code.

+
+ +
+
+ +
+
+
+ +
Create a Room
+

Become the host and stream audio to your friends.

+ +
+
+
+ + +
+
+
+ +
Join a Room
+

Enter the 6-character code to start listening.

+
+ +
+ +
+
+
+
+
+ +
+
+
+ Host Control Panel +
+
+
Your Room is Live!
+

Share this code with your participants:

+

+ +
+ + Not currently streaming. Click "Start Streaming" to begin. +
+ + + +
+ +
+
+ +
+
+
+ You are in a Room +
+
+
+ Waiting for audio to start... +
+ + +
+
+
+
+
+
+ + +
+ + + + + + - + \ No newline at end of file