Git Product home page Git Product logo

video-stream-merger's Introduction

video-stream-merger

JavaScript Style Guide

Merge the video of multiple MediaStreams. Also merges the audio via the WebAudio API.

  • Send multiple videos over a single WebRTC MediaConnection
  • Hotswap streams without worrying about renegotation or delays
  • Crop, scale, and rotate live video
  • Add crazy effects through the canvas API

Demo

P2P Demo

Existing Files Demo

Check out WBS, which uses this package.

install

npm install video-stream-merger

or

<script src="dist/video-stream-merger.js><script>

usage

Let's first get two media streams. One from the webcam, and another a screen capture.

var getusermedia = require('getusermedia')
var screenrecord = require('screen-record')

getusermedia({video: true, audio:true}, function (err, webcamStream) {
  screenRecord(window, function (err, sourceId, constraints) {
    getusermedia(constraints, function (err, screenStream) {
      // We now have 2 streams: webcamStream, screenStream
    })
  })
})

We want to overlay the webcam stream in the corner of the screen stream.

var VideoStreamMerger = require('video-stream-merger')

var merger = new VideoStreamMerger()

// Add the screen capture. Position it to fill the whole stream (the default)
merger.addStream(screenStream, {
  x: 0, // position of the topleft corner
  y: 0,
  width: merger.width,
  height: merger.height,
  mute: true // we don't want sound from the screen (if there is any)
})

// Add the webcam stream. Position it on the bottom left and resize it to 100x100.
merger.addStream(webcamStream, {
  x: 0,
  y: merger.height - 100,
  width: 100,
  height: 100,
  mute: false
})

// Start the merging. Calling this makes the result available to us
merger.start()

// We now have a merged MediaStream!
merger.result

API

merger = new VideoStreamMerger([opts])

Create a new video merger.

Optional opts defaults to the below:

{
  width: 400,   // Width of the output video
  height: 300,  // Height of the output video
  fps: 25       // Video capture frames per second,
  audioContext: null // Supply an external AudioContext (for audio effects)
}

merger.addStream(mediaStream|id, [opts])

Add a MediaStream to be merged. Use an id string if you only want to provide an effect.

The order that streams are added matters. Streams placed earlier will be behind later streams (use the index option to change this behaviour.)

Optional opts defaults to the below:

{
  x: 0, // position of the top-left corner
  y: 0,
  width: <width of output>,     // size to draw the stream
  height: <height of output>,
  index: null, // Order in which to draw the stream (0 pushes to bottom, null pushes to top)
  mute: false,  // if true, any audio tracks will not be merged
  draw: null,    // A custom drawing function (see below)
  audioEffect: null // A custom WebAudio effect (see below)
}

merger.removeStream(mediaStream|id)

Remove a MediaStream from the merging. You may also use the ID of the stream.

If you have added the same MediaStream multiple times, all instances will be removed.

merger.updateIndex(mediaStream|id, newIndex)

Update the z-index (draw order) of an already added stream or data object. Identical to the index option.

If you have added the same MediaStream multiple times, the relative order of instances is not guaranteed.

merger.start()

Start the merging and create merger.result.

You can call this any time, but you only need to call it once.

You will still be able to add/remove streams and the result stream will automatically update.

merger.result

The resulting merged MediaStream. Only available after calling merger.start()

Never has more than one Audio and one Video track.

merger.destroy()

Clean up everything and destroy the result stream.

merger.getAudioContext()

Get the WebAudio AudioContext being used by the merger.

merger.getAudioDestination()

Get the MediaStreamDestination node that is used by the merger.

merger.addMediaElement(id, mediaElement, opts)

A convenience function to merge a HTML5 MediaElement instead of a MediaStream.

id is a string used to remove of update the index of the stream later.

mediaElement is a playing HTML5 Audio or Video element.

opts are identical to the opts for addStream.

Streams from MediaElements can be removed via merger.removeStream(id).

Hot-Swapping Streams

This library makes it easy to change streams in a WebRTC connection without needing to renegotiate.

The result MediaStream will appear to be constant and stable, no matter what streams you add/remove!

P2P Streaming Demo

Custom Draw Function

If sizing and positioning aren't enough, you can directly draw the video frames by passing a function to the draw option.

merger.addStream(mediaStream, {
  draw: function (ctx, frame, done) {
    // You can do whatever you want with this canvas context
    ctx.drawImage(frame, 0, 0, merger.width, merger.height)
    done()
  })
})

See the bottom example of the Live Demo to see this in action.

Custom WebAudio Effects

You can also take direct control over how audio streams are merged, and apply effects.

merger.addStream(mediaStream, {
  audioEffect: function (sourceNode, destinationNode) {
    // sourceNode is the input streams audio (microphone, etc)
    // destinationNode is the output streams audio
    
    sourceNode.connect(destinationNode) // The default effect, simply merges audio
  })
})

Both the draw and audioEffect options can be used without any MediaStream at all. Just pass a string instead.

video-stream-merger's People

Contributors

notedit avatar paul-em avatar rationalcoding avatar t-mullen avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Forkers

swipswaps

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.