UNPKG

observ-mediastream

Version:

An observable representation of a W3C MediaStream

104 lines (87 loc) 2.86 kB
var Observ = require('observ'); var ObservArray = require('observ-array'); var ObservStruct = require('observ-struct'); var MediaStream = require('feature/detect')('MediaStream'); var URL = require('feature/detect')('URL'); /** # observ-mediastream An attempt at making a [MediaStream](http://www.w3.org/TR/mediacapture-streams/#mediastream) represented simply using [observables](https://github.com/Raynos/observ) ## Example Usage <<< examples/simple.js **/ module.exports = function(mediastream, opts) { opts = opts || {}; var muted = Observ(false); var raw = Observ(null); var url = Observ(null); var version = Observ(1); var tracks = ObservArray([]); var tags = ObservArray(opts.tags || []); var metadata = ObservStruct(opts.metadata || {}); var s; var _set; function getAudioTracks() { return tracks.filter(function(track) { return track.kind === 'audio'; }); } function touch() { s.version.set(version() + 1); } function set(newStream) { var isMuted; if ((MediaStream && !(newStream instanceof MediaStream)) || newStream._diff) { return _set(newStream); } if (URL) { // if we have an existing url, revoke the url if (url()) { URL.revokeObjectURL(url()); } try { url.set(URL.createObjectURL(newStream)); } catch (e) { // Might be in a browser that has issues with creating object URLs with media streams // Aka. Safari 11. Instead of using the url, use the raw media stream and `el.srcObject = rawMediaStream` } } // Clean remove the listeners var existing = raw(); if (existing && existing.getTracks) { existing.getTracks().map(function(t) { t.removeEventListener('ended', touch); t.removeEventListener('mute', touch); t.removeEventListener('unmute', touch); }); } raw.set(newStream); s.tracks.set([].concat(newStream.getVideoTracks()).concat(newStream.getAudioTracks())); isMuted = s.tracks.filter(function(track) { // Attach the change of state listeners on the tracks track.addEventListener('ended', touch); track.addEventListener('mute', touch); track.addEventListener('unmute', touch); // Return the track if it matches the mute check return track.kind === 'audio' && (! track.enabled); })[0] || false; if (s.muted() !== isMuted) { s.muted.set(isMuted); } } function toggleMuted(value) { getAudioTracks().forEach(function(track) { track.enabled = !value; }); } s = ObservStruct({ tracks: tracks, muted: muted, raw: raw, url: url, tags: tags, metadata: metadata, version: version }); _set = s.set; s.set = set; s.touch = touch; if (mediastream) { set(mediastream); } // toggle muted state muted(toggleMuted); return s; };