Skip to content

vanevery/p5LiveMedia

Folders and files

NameName
Last commit message
Last commit date

Latest commit

66c51fc · Mar 14, 2024

History

81 Commits
Mar 20, 2023
Jun 22, 2021
Mar 14, 2024
Oct 6, 2021
Sep 7, 2021

Repository files navigation

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

About

Simple P5 WebRTC

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published