mirror of
https://github.com/ianramzy/decentralized-video-chat.git
synced 2025-02-23 00:15:04 +08:00
draggable video, no crop video, text overlay while connecting
This commit is contained in:
parent
117fd15fa1
commit
a58dcb706b
@ -8,6 +8,7 @@
|
|||||||
<link rel="stylesheet" href="../css/snackbar.css">
|
<link rel="stylesheet" href="../css/snackbar.css">
|
||||||
<script src="https://kit.fontawesome.com/9d7bb7e31a.js" crossorigin="anonymous"></script>
|
<script src="https://kit.fontawesome.com/9d7bb7e31a.js" crossorigin="anonymous"></script>
|
||||||
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
|
||||||
|
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
|
||||||
<meta property="og:title" content="Join your friends call - Neonchat">
|
<meta property="og:title" content="Join your friends call - Neonchat">
|
||||||
<meta property="og:description" content="Click the link to join this chat room using Neonchat">
|
<meta property="og:description" content="Click the link to join this chat room using Neonchat">
|
||||||
<meta property="og:image" content="https://neonchat.io/images/preview.png">
|
<meta property="og:image" content="https://neonchat.io/images/preview.png">
|
||||||
@ -27,13 +28,15 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
<p id="remote-video-text">Waiting for peer to connect...</p>
|
||||||
|
<video id="remote-video" autoplay ondblclick={openFullscreen()}></video>
|
||||||
|
|
||||||
<div class="videos">
|
|
||||||
<video id="remote-video" autoplay ondblclick={openFullscreen()}></video>
|
<div id="moveable">
|
||||||
|
<p id="local-video-text">No webcam input</p>
|
||||||
<video id="local-video" autoplay muted></video>
|
<video id="local-video" autoplay muted></video>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="multi-button">
|
<div class="multi-button">
|
||||||
<div class="buttonContainer">
|
<div class="buttonContainer">
|
||||||
<button class="hoverButton" onclick="{muteMicrophone()}">
|
<button class="hoverButton" onclick="{muteMicrophone()}">
|
||||||
@ -53,18 +56,18 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="HoverState" id="video-text">Pause Video</div>
|
<div class="HoverState" id="video-text">Pause Video</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="buttonContainer">
|
||||||
|
<button class="hoverButton" id="share-button" onclick="{swap()}">
|
||||||
|
<i id="swap-icon" class="fas fa-desktop fa-xs"></i>
|
||||||
|
</button>
|
||||||
|
<div class="HoverState" id="swap-text">Share Screen</div>
|
||||||
|
</div>
|
||||||
<div class="buttonContainer">
|
<div class="buttonContainer">
|
||||||
<button class="hoverButton" onclick="{window.location.href = '/newroom'}">
|
<button class="hoverButton" onclick="{window.location.href = '/newroom'}">
|
||||||
<i class="fas fa-phone-slash fa-xs"></i>
|
<i class="fas fa-phone-slash fa-xs"></i>
|
||||||
</button>
|
</button>
|
||||||
<div class="HoverState">End Call</div>
|
<div class="HoverState">End Call</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="buttonContainer">
|
|
||||||
<button class="hoverButton" onclick="{swap()}">
|
|
||||||
<i id="swap-icon" class="fas fa-desktop fa-xs"></i>
|
|
||||||
</button>
|
|
||||||
<div class="HoverState" id="swap-text">Share Screen</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,9 +6,64 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.videos {
|
|
||||||
height: 80vh;
|
video {
|
||||||
width: 80vw;
|
background: #16171a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#moveable {
|
||||||
|
z-index: 100;
|
||||||
|
right: 14px;
|
||||||
|
bottom: 10px;
|
||||||
|
position: absolute;
|
||||||
|
width: 15%;
|
||||||
|
cursor: move;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#moveable p {
|
||||||
|
z-index: 101;
|
||||||
|
position: absolute;
|
||||||
|
color: white;
|
||||||
|
font-family: "Heebo", sans-serif;
|
||||||
|
white-space: nowrap;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
-ms-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
font-weight: bold;
|
||||||
|
background: rgba(0, 0, 0, 0.38);
|
||||||
|
padding: 10px;
|
||||||
|
transition: 0.5s;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#local-video {
|
||||||
|
width: 100%;
|
||||||
|
height: auto;
|
||||||
|
border-radius: 20px;
|
||||||
|
-webkit-transform: scaleX(-1);
|
||||||
|
transform: scaleX(-1);
|
||||||
|
background: #16171a;
|
||||||
|
}
|
||||||
|
|
||||||
|
#remote-video-text {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(40%);
|
||||||
|
left: 50%;
|
||||||
|
-ms-transform: translate(-50%, -50%);
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
color: white;
|
||||||
|
font-family: "Heebo", sans-serif;
|
||||||
|
white-space: nowrap;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
#remote-video {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -16,35 +71,13 @@ body {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
-ms-transform: translate(-50%, -50%);
|
-ms-transform: translate(-50%, -50%);
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
}
|
width: 70%;
|
||||||
|
|
||||||
|
|
||||||
video {
|
|
||||||
/*background: #292B32;*/
|
|
||||||
background: #16171a;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#local-video {
|
|
||||||
width: 20%;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
position: absolute;
|
|
||||||
z-index: 100;
|
|
||||||
right: 14px;
|
|
||||||
bottom: 10px;
|
|
||||||
border-radius: 20px;
|
|
||||||
-webkit-transform: scaleX(-1);
|
|
||||||
transform: scaleX(-1);
|
|
||||||
background: #16171a;
|
|
||||||
}
|
|
||||||
|
|
||||||
#remote-video {
|
|
||||||
max-height: 100%;
|
max-height: 100%;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
min-width: 100%;
|
|
||||||
min-height: 100%;
|
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
object-fit: cover;
|
|
||||||
background-image: url(../images/loader.gif);
|
background-image: url(../images/loader.gif);
|
||||||
background-size: 400px auto;
|
background-size: 400px auto;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
@ -74,7 +107,7 @@ button:hover {
|
|||||||
.multi-button {
|
.multi-button {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: calc(5vw - 40px);
|
right: calc(5vw - 40px);
|
||||||
top: 10vh;
|
top: calc(50vh - 175px);
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background: #16171a;
|
background: #16171a;
|
||||||
|
@ -62,6 +62,8 @@ var VideoChat = {
|
|||||||
audio: true
|
audio: true
|
||||||
}).then(stream => {
|
}).then(stream => {
|
||||||
VideoChat.onMediaStream(stream);
|
VideoChat.onMediaStream(stream);
|
||||||
|
$('#local-video-text').text("Drag Me");
|
||||||
|
setTimeout(() => $('#local-video-text').hide(), 5000);
|
||||||
}).catch(error => {
|
}).catch(error => {
|
||||||
logIt(error);
|
logIt(error);
|
||||||
logIt('Failed to get local webcam video, check webcam privacy settings');
|
logIt('Failed to get local webcam video, check webcam privacy settings');
|
||||||
@ -202,7 +204,7 @@ var VideoChat = {
|
|||||||
logIt("createAnswer");
|
logIt("createAnswer");
|
||||||
return function () {
|
return function () {
|
||||||
logIt('>>> Creating answer...');
|
logIt('>>> Creating answer...');
|
||||||
VideoChat.connected = true;
|
// VideoChat.connected = true;
|
||||||
rtcOffer = new RTCSessionDescription(JSON.parse(offer));
|
rtcOffer = new RTCSessionDescription(JSON.parse(offer));
|
||||||
VideoChat.peerConnection.setRemoteDescription(rtcOffer);
|
VideoChat.peerConnection.setRemoteDescription(rtcOffer);
|
||||||
VideoChat.peerConnection.createAnswer(
|
VideoChat.peerConnection.createAnswer(
|
||||||
@ -232,9 +234,11 @@ var VideoChat = {
|
|||||||
onAnswer: function (answer) {
|
onAnswer: function (answer) {
|
||||||
logIt("onAnswer");
|
logIt("onAnswer");
|
||||||
logIt('<<< Received answer');
|
logIt('<<< Received answer');
|
||||||
|
|
||||||
var rtcAnswer = new RTCSessionDescription(JSON.parse(answer));
|
var rtcAnswer = new RTCSessionDescription(JSON.parse(answer));
|
||||||
VideoChat.peerConnection.setRemoteDescription(rtcAnswer);
|
VideoChat.peerConnection.setRemoteDescription(rtcAnswer);
|
||||||
VideoChat.connected = true;
|
VideoChat.connected = true;
|
||||||
|
// should prolly move conneted = true to onaddstream
|
||||||
VideoChat.localICECandidates.forEach(candidate => {
|
VideoChat.localICECandidates.forEach(candidate => {
|
||||||
// The caller now knows that the callee is ready to accept new ICE candidates, so sending the buffer over
|
// The caller now knows that the callee is ready to accept new ICE candidates, so sending the buffer over
|
||||||
logIt(`>>> Sending local ICE candidate (${candidate.address})`);
|
logIt(`>>> Sending local ICE candidate (${candidate.address})`);
|
||||||
@ -253,6 +257,7 @@ var VideoChat = {
|
|||||||
VideoChat.remoteVideo.srcObject = event.stream;
|
VideoChat.remoteVideo.srcObject = event.stream;
|
||||||
Snackbar.close();
|
Snackbar.close();
|
||||||
VideoChat.remoteVideo.style.background = 'none';
|
VideoChat.remoteVideo.style.background = 'none';
|
||||||
|
$('#remote-video-text').text("");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -260,7 +265,7 @@ var VideoChat = {
|
|||||||
var isFullscreen = false;
|
var isFullscreen = false;
|
||||||
|
|
||||||
function openFullscreen() {
|
function openFullscreen() {
|
||||||
var elem = document.getElementsByClassName("videos")[0];
|
var elem = document.getElementById("remote-video");
|
||||||
if (!isFullscreen) {
|
if (!isFullscreen) {
|
||||||
isFullscreen = true;
|
isFullscreen = true;
|
||||||
if (elem.requestFullscreen) {
|
if (elem.requestFullscreen) {
|
||||||
@ -370,6 +375,10 @@ $(document).ready(function () {
|
|||||||
var mode = "camera";
|
var mode = "camera";
|
||||||
|
|
||||||
function swap() {
|
function swap() {
|
||||||
|
if (!VideoChat.connected) {
|
||||||
|
alert("You must join a call before you can share your screen.");
|
||||||
|
return
|
||||||
|
}
|
||||||
const swapIcon = document.getElementById("swap-icon");
|
const swapIcon = document.getElementById("swap-icon");
|
||||||
const swapText = document.getElementById("swap-text");
|
const swapText = document.getElementById("swap-text");
|
||||||
if (mode === "camera") {
|
if (mode === "camera") {
|
||||||
@ -399,10 +408,13 @@ function swap() {
|
|||||||
|
|
||||||
function switchStreamHelper(stream) {
|
function switchStreamHelper(stream) {
|
||||||
let videoTrack = stream.getVideoTracks()[0];
|
let videoTrack = stream.getVideoTracks()[0];
|
||||||
var sender = VideoChat.peerConnection.getSenders().find(function (s) {
|
if (VideoChat.connected) {
|
||||||
return s.track.kind === videoTrack.kind;
|
var sender = VideoChat.peerConnection.getSenders().find(function (s) {
|
||||||
});
|
return s.track.kind === videoTrack.kind;
|
||||||
sender.replaceTrack(videoTrack);
|
});
|
||||||
|
sender.replaceTrack(videoTrack);
|
||||||
|
}
|
||||||
|
|
||||||
VideoChat.localStream = videoTrack;
|
VideoChat.localStream = videoTrack;
|
||||||
VideoChat.localVideo.srcObject = stream;
|
VideoChat.localVideo.srcObject = stream;
|
||||||
}
|
}
|
||||||
@ -410,3 +422,9 @@ function switchStreamHelper(stream) {
|
|||||||
|
|
||||||
// auto get media
|
// auto get media
|
||||||
VideoChat.requestMediaStream();
|
VideoChat.requestMediaStream();
|
||||||
|
|
||||||
|
|
||||||
|
$("#moveable").draggable({containment: 'window'});
|
||||||
|
|
||||||
|
|
||||||
|
setInterval(() => console.log(VideoChat.remoteVideo.srcObject), 2000);
|
Loading…
x
Reference in New Issue
Block a user