peers / peerjs

Simple peer-to-peer with WebRTC.
https://peerjs.com
MIT License
12.35k stars 1.43k forks source link

Screen sharing #96

Closed kenianbei closed 10 years ago

kenianbei commented 10 years ago

Any plans for adding screen sharing?

Example: https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/

ericz commented 10 years ago

PeerJS takes in an arbitrary stream when calling peer.call. To screen share, you just need to get a screen sharing stream from getUserMedia instead of a webcam video stream. PeerJS doesn't differentiate when you call another Peer. Note that screen sharing requires your site be on HTTPS.

So it should already work.

Eric

On Thu, Oct 24, 2013 at 8:52 AM, kenianbei notifications@github.com wrote:

Any plans for adding screen sharing?

Example: https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/

— Reply to this email directly or view it on GitHubhttps://github.com/peers/peerjs/issues/96 .

510-691-3951 http://ericzhang.com

ericz commented 10 years ago

Give it a try and if you run into trouble please reopen the issue and I'll fix it

On Fri, Oct 25, 2013 at 10:41 AM, Eric Zhang really.ez@gmail.com wrote:

PeerJS takes in an arbitrary stream when calling peer.call. To screen share, you just need to get a screen sharing stream from getUserMedia instead of a webcam video stream. PeerJS doesn't differentiate when you call another Peer. Note that screen sharing requires your site be on HTTPS.

So it should already work.

Eric

On Thu, Oct 24, 2013 at 8:52 AM, kenianbei notifications@github.comwrote:

Any plans for adding screen sharing?

Example: https://www.webrtc-experiment.com/Pluginfree-Screen-Sharing/

— Reply to this email directly or view it on GitHubhttps://github.com/peers/peerjs/issues/96 .

510-691-3951 http://ericzhang.com

510-691-3951 http://ericzhang.com

kenianbei commented 10 years ago

I hadn't done my research on how screen sharing works, will test it out. Thanks for all your work... you guys are awesome!

SivaShhankar commented 6 years ago

Hello, can u please help me to integrate screen sharing on PeerJS.

theevann commented 4 years ago

For those looking for Screen Sharing, as said above, you need to use a MediaStream in the same way as what you would do for call.

The way to get the MediaStream for screen sharing is:

let screenStream = await navigator.mediaDevices.getDisplayMedia({
    video: true
});

Then simply:

peer.call(remote_peer_key, screenStream);

Hope this saves you 5 minutes ;)

venkpath commented 4 years ago

For those looking for Screen Sharing, as said above, you need to use a MediaStream in the same way as what you would do for call.

The way to get the MediaStream for screen sharing is:

let screenStream = await navigator.mediaDevices.getDisplayMedia({
    video: true
});

Then simply:

peer.call(remote_peer_key, screenStream);

Hope this saves you 5 minutes ;)

could you please provide source code for screen sharing in peerjs? thans in advance

theevann commented 4 years ago

Sorry I don't have time to provide a minimal working example for screen sharing. But if you take any working example of video call and replace the stream as shown above, it will work.

wzuqui commented 3 years ago

@theevann maybe my code will help you

I'm using in my project and it's working

constructor() {
    this.peer = new Peer();
    this.peer.on('open', (id) => {
      this.id = id;
    });
    this.peer.on('call', (call) => {
      call.answer();
      call.on('stream', (remoteStream) => {
        this.videoElementRef.nativeElement.srcObject = remoteStream;
      });
    });
  }

  public async buttonHandler(evento: Event, remotoId: string): Promise<void> {
    evento.preventDefault();
    const stream = await (navigator.mediaDevices as MyMediaDevices).getDisplayMedia(
      {
        video: { frameRate: 5, width: 1280, height: 720 },
      }
    );
    const call = this.peer.call(remotoId, stream);
  }
saini3911 commented 3 years ago

@venkpath peer.call(remote_peer_key, screenStream);
this worked but when screenshare is ended then also on other user side that video frame is not removed .. how to remove that video element after screenshare is ended

theevann commented 3 years ago

@saini3911 Maybe listen to the "close" event on the stream and remove your video tag then ? https://peerjs.com/docs.html#mediaconnection-on

saini3911 commented 3 years ago

i use that to but it remove original user face media also

saini3911 commented 3 years ago

i have made my project in expressjs and preerjs .. after other user connect to room why media stream is not connect .. like i other user have to refresh their tab 3-4 time to get media stream in peerjs why ?

Jinoy-Varghese commented 3 years ago

I too have this problem, this is my code

`const socket = io('/') const videoGrid = document.getElementById('video-grid') const myPeer = new Peer(undefined, { host: '/', port: '3001' }) //code 1 let myVideoStream; const myVideo = document.createElement('video') myVideo.muted = true const peers = {} navigator.mediaDevices.getUserMedia({ video: true, audio: true }).then(stream => { myVideoStream = stream; addVideoStream(myVideo, stream)

myPeer.on('call', call => { call.answer(stream) const video = document.createElement('video') call.on('stream', userVideoStream => { addVideoStream(video, userVideoStream) }) })

socket.on('user-connected', userId => { connectToNewUser(userId, stream) }) })

socket.on('user-disconnected', userId => { if (peers[userId]) peers[userId].close() })

myPeer.on('open', id => { socket.emit('join-room', ROOM_ID, id) })

function connectToNewUser(userId, stream) { const call = myPeer.call(userId, stream) const video = document.createElement('video') call.on('stream', userVideoStream => { addVideoStream(video, userVideoStream) }) call.on('close', () => { video.remove() })

peers[userId] = call }

function addVideoStream(video, stream) { video.srcObject = stream video.addEventListener('loadedmetadata', () => { video.play() }) videoGrid.append(video) }

//new code

const muteUnmute = () => { const enabled = myVideoStream.getAudioTracks()[0].enabled; if (enabled) { myVideoStream.getAudioTracks()[0].enabled = false; setUnmuteButton(); } else { setMuteButton(); myVideoStream.getAudioTracks()[0].enabled = true; } }

const playStop = () => { console.log('object') let enabled = myVideoStream.getVideoTracks()[0].enabled; if (enabled) { myVideoStream.getVideoTracks()[0].enabled = false; setPlayVideo() } else { setStopVideo() myVideoStream.getVideoTracks()[0].enabled = true; } }

const setMuteButton = () => { const html = <i class="fas fa-microphone"></i> <span>Mute</span> document.querySelector('.main__mute_button').innerHTML = html; }

const setUnmuteButton = () => { const html = <i class="unmute fas fa-microphone-slash"></i> <span>Unmute</span> document.querySelector('.main__mute_button').innerHTML = html; }

const setStopVideo = () => { const html = <i class="fas fa-video"></i> <span>Stop Video</span> document.querySelector('.main__video_button').innerHTML = html; }

const setPlayVideo = () => { const html = <i class="stop fas fa-video-slash"></i> <span>Play Video</span> document.querySelector('.main__video_button').innerHTML = html; }

`

I can't stream my screen with peerjs but video cam streaming is working properly

MikePooh commented 3 years ago

I have the same problem.

const myPeer = new Peer()

navigator.mediaDevices.getUserMedia({
  video: true,
  audio: false
}).then(stream => {
  addVideoStream(myVideo, stream);

  myPeer.on('call', call => {
    console.log("on call")
    call.answer(stream)
  });
});

Works fine and as expected

navigator.mediaDevices.getDisplayMedia({
  video: true,
  audio: false
}).then(stream => {
  addVideoStream(myVideo, stream);

  myPeer.on('call', call => {
    console.log("on call")
    call.answer(stream)
  });
});

works wrong - "on.call" never called

I thought that problem might be in https, but not. Https test didn't help.

kjohnson commented 2 years ago

I was able to piece together a screen share app referencing the following:

I baked it into a Laravel project (using Livewire), but here is the template:

<div class="relative pt-28">

    <x-jet-button id="share" class="absolute z-10 top-8 right-12" onclick="share()">Share</x-jet-button>

    @foreach( $teamUsers as $user)
        <button onclick="watch('{{ $team->id . '-' . $user->id }}')">
            <img class="h-10 w-10 rounded-full object-cover" src="{{ $user->profile_photo_url }}" alt="{{ $user->name }}">
        </button>
    @endforeach

    <!-- Local Video Element-->
    <video id="local-video" class="absolute top-0 right-0 w-48"></video>

    <!-- Remote Video Element-->
    <video id="remote-video" class="m-auto" style="width: 800px;" poster="https://thumbs.dreamstime.com/b/no-signal-screen-everything-plugged-tv-no-tv-signal-broadcast-screen-124890412.jpg"></video>

    <style>
        video {
            background-color: lightgray;
        }
    </style>

    @push('scripts')
        <script src="https://unpkg.com/peerjs@1.3.1/dist/peerjs.min.js"></script>
        <script>
            let peerID;
            let screenShare;
            const peer = new Peer('{{ $team->id . '-' . $peerID }}');

            peer.on('open', function(id) {
                console.log('My peer ID is: ' + id);
                peerID = id
            });

            peer.on('call', (call) => {
                console.log( 'CALL' )
                call.answer( screenShare );
            })

            function share() {
                navigator.mediaDevices.getDisplayMedia({ video: true }).then((stream) => {
                    screenShare = stream
                    let video = document.getElementById("local-video");
                    video.srcObject = stream;
                    video.play()
                    @this.stream()
                })
            }

            function watch( remoteID ) {
                console.log( remoteID )

                // A stream is required to start a call, so call with an empty stream
                // This allows the call to be answered with the screen share.
                const videoTrack = createEmptyVideoTrack({ width: 500, height: 500 })
                const mediaStream = new MediaStream([ videoTrack ]);
                const call = peer.call(remoteID, mediaStream);

                // `stream` is the MediaStream of the remote peer.
                // Here you'd add it to an HTML video/canvas element.
                call.on('stream', function(stream) {
                    console.log( 'STREAM', stream )
                    let video = document.getElementById("remote-video");
                    video.srcObject = stream;
                    video.play();
                });
            }

            function createEmptyVideoTrack({ width, height }) {
                const canvas = Object.assign(document.createElement('canvas'), { width, height });
                canvas.getContext('2d').fillRect(0, 0, width, height);

                const stream = canvas.captureStream();
                const track = stream.getVideoTracks()[0];

                return Object.assign(track, { enabled: false });
            }

        </script>
    @endpush
</div>