Giter Site home page Giter Site logo

p5livemedia's Introduction

p5LiveMedia

Simple P5 WebRTC

Include this library in a p5 sketch and share audio/video streams or the canvas itself as a stream. Can also share data (string only for now). All WebRTC so Peer to Peer.

Running a public signaling server on https://p5livemedia.itp.io - Run your own signalling server by running server.js (with Node, Express and Socket.io).

Video Introducing p5LiveMedia

Introducing p5LiveMedia

Getting Started

Requires simplepeer and socket.io be included in the HTML:

<script type="text/javascript" src="https://p5livemedia.itp.io/simplepeer.min.js"></script>
<script type="text/javascript" src="https://p5livemedia.itp.io/socket.io.js"></script>

Of course, this library needs to be included as well:

<script type="text/javascript" src="https://p5livemedia.itp.io/p5livemedia.js"></script>

Basics - Sharing Live Video Stream

Use the callback from createCapture to get at the media stream.

Instantiate p5Live with:

  • a reference to the sketch (this)
  • a string indicating if this is audio/video ("CAPTURE") or a canvas ("CANVAS")
  • the media stream from the createCapture callback
  • and a unique room name. The sketch id from the p5 editor works well (in this case, "jZQ64AMJc").
    Add a callback for the "stream" event, in this case, a function defined later called "gotStream":
let myVideo = null;

function setup() {
  createCanvas(400,400);

  myVideo = createCapture(VIDEO, 
    function(stream) {
	let p5lm = new p5LiveMedia(this, "CAPTURE", stream, "jZQ64AMJc")
  	p5lm.on('stream', gotStream);
    }
  );
}

You can specify the normal MediaStreamConstraints to specify framerates, sizes, and stream types. You'll want to mute your local video to prevent feedback:

let myVideo = null;

function setup() {
  createCanvas(400,400);
  
  let constraints = {audio: true, video: true};
  myVideo = createCapture(constraints, 
    function(stream) {
      let p5lm = new p5LiveMedia(this, "CAPTURE", stream, "jZQ64AMJc")
      p5lm.on('stream', gotStream);
    }
  );

  myVideo.elt.muted = true;
}

The "stream" callback gives a normal video element:

let otherVideo;
function gotStream(stream, id) {
  otherVideo = stream;
  //otherVideo.id and id are the same and unique identifier
}

Both video elements can be used in the draw loop:

function draw() {
  if (myVideo != null) {
    image(myVideo,0,0,width/2,height);
    text("My Video", 10, 10);
  }

  if (otherVideo != null) {
    image(otherVideo,width/2,0,width/2,height);
    text("Their Video", width/2+10, 10);
  }  
}

Video: Getting Started and Video Sharing Basics Part 1

Getting Started and Video Sharing Basics Part 1

Video: Video Sharing Basics Part 2

Video Sharing Basics Part 2

Basics - Sharing p5 Canvas as Live Video Stream

Alternatively the p5 Canvas can be streamed instead of video:

let otherCanvas;

function setup() {
  let myCanvas = createCanvas(400, 400);
  let p5lm = new p5LiveMedia(this, "CANVAS", myCanvas, "e4LTqKI8Q");
  p5lm.on('stream', gotStream);
}

function draw() {
  background(220);
  fill(255,0,0);
  ellipse(mouseX,mouseY,100,100); 
}

function gotStream(stream) {
  otherCanvas = stream;
}

Sharing a p5 Canvas and Live Audio

Streaming a Canvas and Audio is a little more involved:

let myAudio;
let myCanvas;

let otherVideo;

function setup() {
  myCanvas = createCanvas(400, 400);
  
  // Use constraints to request audio from createCapture
  let constraints = {
    audio: true
  };
  
  // Need to use the callback to get at the audio/video stream
  myAudio = createCapture(constraints, function(stream) {
    
    // Get a stream from the canvas to send
    let canvasStream = myCanvas.elt.captureStream(15);
    
    // Extract the audio tracks from the stream
    let audioTracks = stream.getAudioTracks();
    
    // Use the first audio track, add it to the canvas stream
    if (audioTracks.length > 0) {
      canvasStream.addTrack(audioTracks[0]);
    }
    
    // Give the canvas stream to SimpleSimplePeer as a "CAPTURE" stream
    let p5lm = new p5LiveMedia(this, "CAPTURE", canvasStream, "SimpleSimplePeerAdvancedTest");
    p5lm.on('stream', gotStream);       
  });
  
  myAudio.elt.muted = true;
  myAudio.hide();
}

function draw() {
  background(220);
  fill(255,0,0);
  ellipse(mouseX,mouseY,100,100); 
}

function gotStream(stream) {
  otherVideo = stream;
}

Sharing Data

data can be shared between connected users (a data connection is always available between the connected users). To use you'll need to implement an additional callback for "data":

let otherX = 0;
let otherY = 0;

let ssp;

function setup() {
  createCanvas(400, 400);
  
  // Passing in "DATA" as the capture type but data sharing works with "CAPTURE" and "CANVAS" as well
  p5lm = new p5LiveMedia(this, "DATA", null, "w83C-S6DU");
  // "data" callback
  p5lm.on('data', gotData);
}

function draw() {
  background(220);
  
  fill(255,0,0);
  ellipse(mouseX,mouseY,100,100); 
  
  fill(0,255,0);
  ellipse(otherX,otherY,100,100); 
}

function gotData(data, id) {
  print(id + ":" + data);
  
  // If it is JSON, parse it
  let d = JSON.parse(data);
  otherX = d.x;
  otherY = d.y;
}

function mouseMoved() {
  // Package as JSON to send
  let dataToSend = {x: mouseX, y: mouseY};
  
  // Send it
  p5lm.send(JSON.stringify(dataToSend));
}

Callbacks and IDs

Each callback also includes an "id" to indicate who is sending the stream or data and there is a "disconnect" callback when a user disconnects:

  p5lm.on('data', gotData);
  function gotData(theData, id) {
  }
  
  p5lm.on('stream', gotStream);
  function gotStream(theStream, id) {
  }
  
  p5lm.on('disconnect', gotDisconnect);
  function gotDisconnect(id) {
  }

More documentation forthcoming.

Examples

Contributed Examples

p5livemedia's People

Contributors

vanevery avatar

Stargazers

Ashish Vishwakarma avatar Rana Jayant avatar  avatar  avatar Joyce Z avatar  avatar Yihua Li avatar Sylvain Filoni avatar Dan Ward avatar Sihan avatar  avatar Matthew Mitchell avatar Reina Huang avatar munus avatar  avatar  avatar Yousif Al-Yousifi avatar Niranjan Anandkumar avatar  avatar  avatar  avatar Speks avatar henarts avatar Junwen Huang avatar Michael Chernoff avatar  avatar liquid avatar Justin Gitlin avatar Julien Moreau avatar  avatar Joseph Hancock avatar Sam Carlton avatar Joohun, Maeng avatar Kirill Ragozin avatar  avatar Can Evgin avatar Guille avatar  avatar john tran avatar sedbayram avatar Erol Bickici avatar  avatar Óscar A. Montiel avatar  avatar Dave Kelly avatar Melissa Ulto avatar Sam Lavigne avatar steve daniels avatar Qichao Lan avatar Matthieu Minguet avatar  avatar Jonathan Grizou avatar Dusk avatar Aidan Nelson avatar Tianjun Wang avatar Tirta Wening Rachman avatar Vibert Thio avatar  avatar  avatar karlos g liberal avatar Andreas Refsgaard avatar Julia Myers avatar スィルヴァン avatar Yifei Gao avatar Mathura MG avatar Toan Tran avatar cypress evelyn masso avatar aarón montoya-moraga avatar

Watchers

Alexandre Enkerli avatar  avatar Noah Pivnick avatar James Cloos avatar

p5livemedia's Issues

Allow more than 1 video track in a stream/channel

It seems that adding a 2nd video track to the stream doesn't do the trick - only 1 track is received. Perhaps using "addStream" will work?

Use case is sending a second stream that will act as an alpha channel on the receiving side - composite with p5 Image mask (which uses alpha rather than the blue channel ugh)

sketch Combine Canvas and Audio fails on macos Safari and iPadOS Safari

Amended: Most basic example fails on macOS Safari
sketchers: https://editor.p5js.org/shawn/sketches/jZQ64AMJc
console error: "Unhandled Promise Rejection: AbortError: Failed to fetch module, error: Cross origin requests are only supported for HTTP."

sketch Combine Canvas and Audio fails on macos Safari and iPadOS Safari
sketch url: https://editor.p5js.org/shawn/sketches/SbNzhNujd
name: Advanced - Combine Canvas and Audio - Video Chat
Works ok on macos Chrome and Firefox.

Getting Errorr that it can't call "play" of undefined on connect but it does no harm

I think I get this on all examples?

p5livemedia.js:338 Uncaught TypeError: Cannot read property 'play' of undefined
at HTMLVideoElement.domElement.onloadedmetadata (p5livemedia.js:338)
domElement.onloadedmetadata @ p5livemedia.js:338
VM30 about:srcdoc:40 Uncaught TypeError: Cannot read property 'split' of undefined
at window.onerror (VM30 about:srcdoc:40)

How to create my server with "Server.js"

Hi ! Thx for your work, it works very well on p5editor, but now I'm trying do that in my local network and I have some problems !
I correctly npm install express, cors, websocket and socket.io. --save
Then I found on the net 'star_itp_io.key' and 'star_itp_io.pem' files.
But now I have this error :
Capture d’écran 2022-09-29 à 22 44 00

Could you help me ? Sorry, but I'm nioub in js...
Thx in advance

draw video stream on canvas

how can i use this video stream to drawImage on p5 canvas.?

gotStream method returns the video stream, which i want to show on an video element or a canvas.

question about running signalling server

(I'm a P5 beginner so I apologize if this should be obvious)

I'm confused about how to run this so I can access camera feeds from two different devices.
Is it necessary to run my own signalling server?
I tried deploying the p5 example sketch to netlify, but neither device can see the other's video feed.

use of 'this' keyword

A student ran into an issue when making a room system using this library. Basically, it is not currently possible to create a p5LiveMedia object outside of the p5js' setup() function because it needs a reference to the p5js object.

As a workaround, I created a global reference for the p5js object, but it would be great if the library could try to manage this internally...

Disconnect from room?

It would be helpful to have the ability to manually trigger a disconnection from a room.

I can work on adding this!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.