Commit 32455d3c authored by Kulya's avatar Kulya 😊

n_core_4

parent a92da51d
Pipeline #21 canceled with stages
# Node
node_modules
# bower
bower_components
npm-debug.log
.DS_Store
\ No newline at end of file
# ignore everything
*
# but not these files...
!MultiStreamsMixer.js
!MultiStreamsMixer.min.js
!index.html
!package.json
!bower.json
!server.js
!README.md
\ No newline at end of file
language: node_js
node_js:
- "0.11"
install: npm install
before_script:
- npm install grunt-cli@0.1.13 -g
- npm install grunt@0.4.5
- grunt
after_failure: npm install && grunt
matrix:
fast_finish: true
'use strict';
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt, {
pattern: 'grunt-*',
config: 'package.json',
scope: 'devDependencies'
});
var versionNumber = grunt.file.readJSON('package.json').version;
var banner = '// Last time updated: <%= grunt.template.today("UTC:yyyy-mm-dd h:MM:ss TT Z") %>\n\n';
banner += '// ________________________\n';
banner += '// MultiStreamsMixer v' + versionNumber + '\n\n';
banner += '// Open-Sourced: https://github.com/muaz-khan/MultiStreamsMixer\n\n';
banner += '// --------------------------------------------------\n';
banner += '// Muaz Khan - www.MuazKhan.com\n';
banner += '// MIT License - www.WebRTC-Experiment.com/licence\n';
banner += '// --------------------------------------------------\n\n';
// configure project
grunt.initConfig({
// make node configurations available
pkg: grunt.file.readJSON('package.json'),
concat: {
options: {
stripBanners: true,
separator: '\n',
banner: banner
},
dist: {
src: [
'dev/head.js',
'dev/init.js',
'dev/cross-browser-declarations.js',
'dev/start-drawing-frames.js',
'dev/draw-videos-on-canvas.js',
'dev/get-mixed-stream.js',
'dev/get-mixed-video-stream.js',
'dev/get-mixed-audio-stream.js',
'dev/get-video-element.js',
'dev/append-streams.js',
'dev/release-streams.js',
'dev/replace-streams.js',
'dev/tail.js'
],
dest: 'MultiStreamsMixer.js',
},
},
uglify: {
options: {
mangle: false,
banner: banner
},
my_target: {
files: {
'MultiStreamsMixer.min.js': ['MultiStreamsMixer.js']
}
}
},
jsbeautifier: {
files: ['MultiStreamsMixer.js', 'dev/*.js', 'server.js', 'Gruntfile.js'],
options: {
js: {
braceStyle: "collapse",
breakChainedMethods: false,
e4x: false,
evalCode: false,
indentChar: " ",
indentLevel: 0,
indentSize: 4,
indentWithTabs: false,
jslintHappy: false,
keepArrayIndentation: false,
keepFunctionIndentation: false,
maxPreserveNewlines: 10,
preserveNewlines: true,
spaceBeforeConditional: true,
spaceInParen: false,
unescapeStrings: false,
wrapLineLength: 0
},
html: {
braceStyle: "collapse",
indentChar: " ",
indentScripts: "keep",
indentSize: 4,
maxPreserveNewlines: 10,
preserveNewlines: true,
unformatted: ["a", "sub", "sup", "b", "i", "u"],
wrapLineLength: 0
},
css: {
indentChar: " ",
indentSize: 4
}
}
},
bump: {
options: {
files: ['package.json', 'bower.json'],
updateConfigs: [],
commit: true,
commitMessage: 'v%VERSION%',
commitFiles: ['package.json', 'bower.json'],
createTag: true,
tagName: '%VERSION%',
tagMessage: '%VERSION%',
push: false,
pushTo: 'upstream',
gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d'
}
},
watch: {
scripts: {
files: ['dev/*.js'],
tasks: ['concat', 'jsbeautifier', 'uglify'],
options: {
spawn: false,
},
}
}
});
// enable plugins
// set default tasks to run when grunt is called without parameters
// http://gruntjs.com/api/grunt.task
grunt.registerTask('default', ['concat', 'jsbeautifier', 'uglify']);
grunt.loadNpmTasks('grunt-contrib-watch');
};
The MIT License (MIT)
Copyright (c) 2017 [Muaz Khan](https://github.com/muaz-khan)
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
This diff is collapsed.
// Last time updated: 2019-01-12 7:02:57 AM UTC
// ________________________
// MultiStreamsMixer v1.0.7
// Open-Sourced: https://github.com/muaz-khan/MultiStreamsMixer
// --------------------------------------------------
// Muaz Khan - www.MuazKhan.com
// MIT License - www.WebRTC-Experiment.com/licence
// --------------------------------------------------
function MultiStreamsMixer(arrayOfMediaStreams){function setSrcObject(stream,element){"srcObject"in element?element.srcObject=stream:"mozSrcObject"in element?element.mozSrcObject=stream:element.srcObject=stream}function drawVideosToCanvas(){if(!isStopDrawingFrames){var videosLength=videos.length,fullcanvas=!1,remaining=[];if(videos.forEach(function(video){video.stream||(video.stream={}),video.stream.fullcanvas?fullcanvas=video:remaining.push(video)}),fullcanvas)canvas.width=fullcanvas.stream.width,canvas.height=fullcanvas.stream.height;else if(remaining.length){canvas.width=videosLength>1?2*remaining[0].width:remaining[0].width;var height=1;3!==videosLength&&4!==videosLength||(height=2),5!==videosLength&&6!==videosLength||(height=3),7!==videosLength&&8!==videosLength||(height=4),9!==videosLength&&10!==videosLength||(height=5),canvas.height=remaining[0].height*height}else canvas.width=self.width||360,canvas.height=self.height||240;fullcanvas&&fullcanvas instanceof HTMLVideoElement&&drawImage(fullcanvas),remaining.forEach(function(video,idx){drawImage(video,idx)}),setTimeout(drawVideosToCanvas,self.frameInterval)}}function drawImage(video,idx){if(!isStopDrawingFrames){var x=0,y=0,width=video.width,height=video.height;1===idx&&(x=video.width),2===idx&&(y=video.height),3===idx&&(x=video.width,y=video.height),4===idx&&(y=2*video.height),5===idx&&(x=video.width,y=2*video.height),6===idx&&(y=3*video.height),7===idx&&(x=video.width,y=3*video.height),"undefined"!=typeof video.stream.left&&(x=video.stream.left),"undefined"!=typeof video.stream.top&&(y=video.stream.top),"undefined"!=typeof video.stream.width&&(width=video.stream.width),"undefined"!=typeof video.stream.height&&(height=video.stream.height),context.drawImage(video,x,y,width,height),"function"==typeof video.stream.onRender&&video.stream.onRender(context,x,y,width,height,idx)}}function getMixedStream(){isStopDrawingFrames=!1;var mixedVideoStream=getMixedVideoStream(),mixedAudioStream=getMixedAudioStream();mixedAudioStream&&mixedAudioStream.getTracks().filter(function(t){return"audio"===t.kind}).forEach(function(track){mixedVideoStream.addTrack(track)});var fullcanvas;return arrayOfMediaStreams.forEach(function(stream){stream.fullcanvas&&(fullcanvas=!0)}),mixedVideoStream}function getMixedVideoStream(){resetVideoStreams();var capturedStream;"captureStream"in canvas?capturedStream=canvas.captureStream():"mozCaptureStream"in canvas?capturedStream=canvas.mozCaptureStream():self.disableLogs||console.error("Upgrade to latest Chrome or otherwise enable this flag: chrome://flags/#enable-experimental-web-platform-features");var videoStream=new MediaStream;return capturedStream.getTracks().filter(function(t){return"video"===t.kind}).forEach(function(track){videoStream.addTrack(track)}),canvas.stream=videoStream,videoStream}function getMixedAudioStream(){Storage.AudioContextConstructor||(Storage.AudioContextConstructor=new Storage.AudioContext),self.audioContext=Storage.AudioContextConstructor,self.audioSources=[],self.useGainNode===!0&&(self.gainNode=self.audioContext.createGain(),self.gainNode.connect(self.audioContext.destination),self.gainNode.gain.value=0);var audioTracksLength=0;if(arrayOfMediaStreams.forEach(function(stream){if(stream.getTracks().filter(function(t){return"audio"===t.kind}).length){audioTracksLength++;var audioSource=self.audioContext.createMediaStreamSource(stream);self.useGainNode===!0&&audioSource.connect(self.gainNode),self.audioSources.push(audioSource)}}),audioTracksLength)return self.audioDestination=self.audioContext.createMediaStreamDestination(),self.audioSources.forEach(function(audioSource){audioSource.connect(self.audioDestination)}),self.audioDestination.stream}function getVideo(stream){var video=document.createElement("video");return setSrcObject(stream,video),video.muted=!0,video.volume=0,video.width=stream.width||self.width||360,video.height=stream.height||self.height||240,video.play(),video}function resetVideoStreams(streams){videos=[],streams=streams||arrayOfMediaStreams,streams.forEach(function(stream){if(stream.getTracks().filter(function(t){return"video"===t.kind}).length){var video=getVideo(stream);video.stream=stream,videos.push(video)}})}var videos=[],isStopDrawingFrames=!1,canvas=document.createElement("canvas"),context=canvas.getContext("2d");canvas.style="opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000; margin-top:-1000000000;margin-left:-1000000000;",(document.body||document.documentElement).appendChild(canvas),this.disableLogs=!1,this.frameInterval=10,this.width=360,this.height=240,this.useGainNode=!0;var self=this,AudioContext=window.AudioContext;"undefined"==typeof AudioContext&&("undefined"!=typeof webkitAudioContext&&(AudioContext=webkitAudioContext),"undefined"!=typeof mozAudioContext&&(AudioContext=mozAudioContext));var URL=window.URL;"undefined"==typeof URL&&"undefined"!=typeof webkitURL&&(URL=webkitURL),"undefined"!=typeof navigator&&"undefined"==typeof navigator.getUserMedia&&("undefined"!=typeof navigator.webkitGetUserMedia&&(navigator.getUserMedia=navigator.webkitGetUserMedia),"undefined"!=typeof navigator.mozGetUserMedia&&(navigator.getUserMedia=navigator.mozGetUserMedia));var MediaStream=window.MediaStream;"undefined"==typeof MediaStream&&"undefined"!=typeof webkitMediaStream&&(MediaStream=webkitMediaStream),"undefined"!=typeof MediaStream&&"undefined"==typeof MediaStream.prototype.stop&&(MediaStream.prototype.stop=function(){this.getTracks().forEach(function(track){track.stop()})});var Storage={};"undefined"!=typeof AudioContext?Storage.AudioContext=AudioContext:"undefined"!=typeof webkitAudioContext&&(Storage.AudioContext=webkitAudioContext),this.startDrawingFrames=function(){drawVideosToCanvas()},this.appendStreams=function(streams){if(!streams)throw"First parameter is required.";streams instanceof Array||(streams=[streams]),arrayOfMediaStreams.concat(streams),streams.forEach(function(stream){if(stream.getTracks().filter(function(t){return"video"===t.kind}).length){var video=getVideo(stream);video.stream=stream,videos.push(video)}if(stream.getTracks().filter(function(t){return"audio"===t.kind}).length&&self.audioContext){var audioSource=self.audioContext.createMediaStreamSource(stream);audioSource.connect(self.audioDestination),self.audioSources.push(audioSource)}})},this.releaseStreams=function(){videos=[],isStopDrawingFrames=!0,self.gainNode&&(self.gainNode.disconnect(),self.gainNode=null),self.audioSources.length&&(self.audioSources.forEach(function(source){source.disconnect()}),self.audioSources=[]),self.audioDestination&&(self.audioDestination.disconnect(),self.audioDestination=null),self.audioContext&&self.audioContext.close(),self.audioContext=null,context.clearRect(0,0,canvas.width,canvas.height),canvas.stream&&(canvas.stream.stop(),canvas.stream=null)},this.resetVideoStreams=function(streams){!streams||streams instanceof Array||(streams=[streams]),resetVideoStreams(streams)},this.name="MultiStreamsMixer",this.toString=function(){return this.name},this.getMixedStream=getMixedStream}
\ No newline at end of file
// @maalouf
export class MultiStreamsMixer {
videos : Array<any>;
isStopDrawingFrames: boolean;
canvas : any;
context : CanvasRenderingContext2D;
disableLogs: boolean;
frameInterval: number;
width : number;
height: number;
useGainNode : boolean;
arrayOfMediaStreams: Array<MediaStream>;
/********************************************/
audioContext : any;
audioDestination : any;
audioSources : Array<any>;
gainNode : GainNode;
constructor (_arrayOfMediaStreams) {
// requires: chrome://flags/#enable-experimental-web-platform-features
this.arrayOfMediaStreams = _arrayOfMediaStreams;
this.videos = new Array<any>();
this.isStopDrawingFrames = false;
this.canvas = document.createElement('canvas');
this.context = this.canvas.getContext('2d');
// this.canvas.style = 'opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000; margin-top:-1000000000;margin-left:-1000000000;';
// (document.body || document.documentElement).appendChild(canvas);
this.disableLogs = false;
this.frameInterval = 10;
this.width = 360;
this.height = 240;
this.useGainNode = true;
this.audioContext = undefined;
}
private isPureAudio(){
for (let i = 0; i < this.arrayOfMediaStreams.length;i++){
if (this.arrayOfMediaStreams[i].getTracks().filter(function(t) {
return t.kind === 'video';
}).length > 0) return false;
}
return true;
}
getAudioContext():AudioContext {
if (typeof AudioContext !== 'undefined') {
return new AudioContext();
} else if (typeof (<any>window).webkitAudioContext !== 'undefined') {
return new (<any>window).webkitAudioContext();
} else if (typeof (<any>window).mozAudioContext !== 'undefined') {
return new (<any>window).mozAudioContext();
}
}
/**************************************************/
private setSrcObject(stream, element) {
var URL = window.URL || (<any>window).webkitURL;
if ('srcObject' in element) {
element.srcObject = stream;
} else if ('mozSrcObject' in element) {
element.mozSrcObject = stream;
} else if ('createObjectURL' in URL) {
element.src = URL.createObjectURL(stream);
} else {
alert('createObjectURL/srcObject both are not supported.');
}
}
public startDrawingFrames() {
this.drawVideosToCanvas();
};
private drawVideosToCanvas() {
if (this.isStopDrawingFrames) {
return;
}
let videosLength = this.videos.length;
let fullcanvas = undefined;
let remaining = [];
this.videos.forEach(video => {
if (!video.stream) {
video.stream = {};
}
if (video.stream.fullcanvas) {
fullcanvas = video;
} else {
remaining.push(video);
}
});
if (fullcanvas !== undefined) {
this.canvas.width = fullcanvas.stream.width;
this.canvas.height = fullcanvas.stream.height;
} else if (remaining.length) {
this.canvas.width = videosLength > 1 ? remaining[0].width * 2 : remaining[0].width;
var height = 1;
if (videosLength === 3 || videosLength === 4) {
height = 2;
}
if (videosLength === 5 || videosLength === 6) {
height = 3;
}
if (videosLength === 7 || videosLength === 8) {
height = 4;
}
if (videosLength === 9 || videosLength === 10) {
height = 5;
}
this.canvas.height = remaining[0].height * height;
} else {
this.canvas.width = this.width || 360;
this.canvas.height = this.height || 240;
}
if (fullcanvas && fullcanvas instanceof HTMLVideoElement) {
this.drawImage(fullcanvas,0);
}
remaining.forEach((video, idx) => {
this.drawImage(video, idx);
});
setTimeout(this.drawVideosToCanvas.bind(this), this.frameInterval);
}
private drawImage(video, idx) {
if (this.isStopDrawingFrames) {
return;
}
var x = 0;
var y = 0;
var width = video.width;
var height = video.height;
if (idx === 1) {
x = video.width;
}
if (idx === 2) {
y = video.height;
}
if (idx === 3) {
x = video.width;
y = video.height;
}
if (idx === 4) {
y = video.height * 2;
}
if (idx === 5) {
x = video.width;
y = video.height * 2;
}
if (idx === 6) {
y = video.height * 3;
}
if (idx === 7) {
x = video.width;
y = video.height * 3;
}
if (typeof video.stream.left !== 'undefined') {
x = video.stream.left;
}
if (typeof video.stream.top !== 'undefined') {
y = video.stream.top;
}
if (typeof video.stream.width !== 'undefined') {
width = video.stream.width;
}
if (typeof video.stream.height !== 'undefined') {
height = video.stream.height;
}
this.context.drawImage(video, x, y, width, height);
if (typeof video.stream.onRender === 'function') {
video.stream.onRender(this.context, x, y, width, height, idx);
}
}
getMixedStream() {
this.isStopDrawingFrames = false;
let mixedAudioStream = this.getMixedAudioStream();
let mixedVideoStream = (this.isPureAudio()) ? undefined: this.getMixedVideoStream();
if (mixedVideoStream == undefined){
return mixedAudioStream;
} else {
if (mixedAudioStream) {
mixedAudioStream.getTracks().filter(function(t) {
return t.kind === 'audio';
}).forEach(track => {
mixedVideoStream.addTrack(track);
});
}
return mixedVideoStream;
}
}
private getMixedVideoStream() {
this.resetVideoStreams();
var capturedStream = this.canvas.captureStream() || this.canvas.mozCaptureStream();
var videoStream = new MediaStream();
capturedStream.getTracks().filter(function(t) {
return t.kind === 'video';
}).forEach(track => {
videoStream.addTrack(track);
});
this.canvas.stream = videoStream;
return videoStream;
}
private getMixedAudioStream() {
// via: @pehrsons
if (this.audioContext == undefined) this.audioContext = this.getAudioContext();
this.audioSources = new Array<any>();
if (this.useGainNode === true) {
this.gainNode = this.audioContext.createGain();
this.gainNode.connect(this.audioContext.destination);
this.gainNode.gain.value = 0; // don't hear self
}
let audioTracksLength = 0;
this.arrayOfMediaStreams.forEach(stream => {
if (!stream.getTracks().filter(function(t) {
return t.kind === 'audio';
}).length) {
return;
}
audioTracksLength++;
let _audioSource = this.audioContext.createMediaStreamSource(stream);
if (this.useGainNode === true) {
_audioSource.connect(this.gainNode);
}
this.audioSources.push(_audioSource);
});
if (!audioTracksLength) {
return undefined;
}
this.audioDestination = this.audioContext.createMediaStreamDestination();
this.audioSources.forEach(_audioSource => {
_audioSource.connect(this.audioDestination);
});
return this.audioDestination.stream;
}
private getVideo(stream) {
var video = document.createElement('video');
this.setSrcObject(stream, video);
video.muted = true;
video.volume = 0;
video.width = stream.width || this.width || 360;
video.height = stream.height || this.height || 240;
video.play();
return video;
}
appendStreams(streams) {
if (!streams) {
throw 'First parameter is required.';
}
if (!(streams instanceof Array)) {
streams = [streams];
}
this.arrayOfMediaStreams.concat(streams);
streams.forEach(stream => {
if (stream.getTracks().filter(function(t) {
return t.kind === 'video';
}).length) {
var video = this.getVideo(stream);
video['stream'] = stream;
this.videos.push(video);
}
if (stream.getTracks().filter(function(t) {
return t.kind === 'audio';
}).length && this.audioContext) {
var audioSource = this.audioContext.createMediaStreamSource(stream);
audioSource.connect(this.audioDestination);
this.audioSources.push(audioSource);
}
});
};
private releaseStreams() {
this.videos = [];
this.isStopDrawingFrames = true;
if (this.gainNode) {
this.gainNode.disconnect();
this.gainNode = null;
}
if (this.audioSources.length) {
this.audioSources.forEach(source => {
source.disconnect();
});
this.audioSources = [];
}
if (this.audioDestination) {
this.audioDestination.disconnect();
this.audioDestination = null;
}
if (this.audioContext) {
this.audioContext.close();
}
this.audioContext = null;
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
if (this.canvas.stream) {
this.canvas.stream.stop();
this.canvas.stream = null;
}
}
private resetVideoStreams(streams?:any) {
if (streams && !(streams instanceof Array)) {
streams = [streams];
}
this._resetVideoStreams(streams);
}
private _resetVideoStreams(streams) {
this.videos = [];
streams = streams || this.arrayOfMediaStreams;
// via: @adrian-ber
streams.forEach(stream => {
if (!stream.getTracks().filter(function(t) {
return t.kind === 'video';
}).length) {
return;
}
let tempVideo = this.getVideo(stream);
tempVideo['stream'] = stream;
this.videos.push(tempVideo);
});
}
}
# [MultiStreamsMixer.js](https://github.com/muaz-khan/MultiStreamsMixer) | [LIVE DEMO](https://www.webrtc-experiment.com/MultiStreamsMixer/)
* Mix Multiple Cameras or Videos
* Mix Multiple Microphones or Audios (Mp3/Wav/Ogg)
* Mix Multiple Screens or Screen+Video
* Mix Canvas 2D Animation + Camera + Screen
* and **GET SINGLE STREAM!!**
[![npm](https://img.shields.io/npm/v/multistreamsmixer.svg)](https://npmjs.org/package/multistreamsmixer) [![downloads](https://img.shields.io/npm/dm/multistreamsmixer.svg)](https://npmjs.org/package/multistreamsmixer) [![Build Status: Linux](https://travis-ci.org/muaz-khan/MultiStreamsMixer.png?branch=master)](https://travis-ci.org/muaz-khan/MultiStreamsMixer)
# All Demos
1. **Main Demo:** https://www.webrtc-experiment.com/MultiStreamsMixer/
2. [Record Multiple Cameras](https://www.webrtc-experiment.com/RecordRTC/simple-demos/multi-cameras-recording.html)
3. [Record Camera+Screen](https://www.webrtc-experiment.com/RecordRTC/simple-demos/video-plus-screen-recording.html)
> Pass multiple streams (e.g. screen+camera or multiple-cameras) and get single stream.
# Link the library
```html
<script src="https://cdn.webrtc-experiment.com/MultiStreamsMixer.js"></script>
<!-- or min.js -->
<script src="https://cdn.webrtc-experiment.com/MultiStreamsMixer.min.js"></script>
<!-- or without CDN -->
<script src="https://www.webrtc-experiment.com/MultiStreamsMixer.js"></script>
<!-- or rawgit -->
<script src="https://rawgit.com/muaz-khan/MultiStreamsMixer/master/MultiStreamsMixer.js"></script>
```
Or link specific build:
* https://github.com/muaz-khan/MultiStreamsMixer/releases
```html
<script src="https://github.com/muaz-khan/MultiStreamsMixer/releases/download/1.0.4/MultiStreamsMixer.js"></script>
```
Or install using NPM:
```sh
npm install multistreamsmixer
```
# How to mix audios?
```javascript
var audioMixer = new MultiStreamsMixer([microphone1, microphone2]);
// record using MediaRecorder API
var recorder = new MediaRecorder(audioMixer.getMixedStream());
// or share using WebRTC
rtcPeerConnection.addStream(audioMixer.getMixedStream());
```
# How to mix screen+camera?
```javascript
screenStream.fullcanvas = true;
screenStream.width = screen.width; // or 3840
screenStream.height = screen.height; // or 2160
cameraStream.width = parseInt((20 / 100) * screenStream.width);
cameraStream.height = parseInt((20 / 100) * screenStream.height);
cameraStream.top = screenStream.height - cameraStream.height;
cameraStream.left = screenStream.width - cameraStream.width;
var mixer = new MultiStreamsMixer([screenStream, cameraStream]);
rtcPeerConnection.addStream(audioMixer.getMixedStream());
mixer.frameInterval = 1;
mixer.startDrawingFrames();
btnStopStreams.onclick = function() {
mixer.releaseStreams();
};
btnAppendNewStreams.onclick = function() {
mixer.appendStreams([anotherStream]);
};
btnStopScreenSharing.onclick = function() {
// replace all old streams with this one
// it will replace only video tracks
mixer.resetVideoStreams([cameraStreamOnly]);
};
```
# How to mix multiple cameras?
```javascript
var mixer = new MultiStreamsMixer([camera1, camera2]);
rtcPeerConnection.addStream(audioMixer.getMixedStream());
mixer.frameInterval = 1;
mixer.startDrawingFrames();
```
# API
1. `getMixedStream`: (function) returns mixed MediaStream object
2. `frameInterval`: (property) allows you set frame interval
3. `startDrawingFrames`: (function) start mixing video streams
4. `resetVideoStreams`: (function) replace all existing video streams with new ones
5. `releaseStreams`: (function) stop mixing streams
6. `appendStreams`: (function) append extra/new streams (anytime)
# TypeScript / Angular
```javascript
import {MultiStreamsMixer} from 'yourPath/MultiStreamsMixer';
use normally ex:
let mixer = new MultiStreamsMixer([stream1,stream2]);
mixer.appendStreams(stream3);
let mixed = mixer.getMixedStream();
```
P.S: pollyfills are removed (except for AudioContext) use adapter instead
## License
[MultiStreamsMixer.js](https://github.com/muaz-khan/MultiStreamsMixer) is released under [MIT licence](https://www.webrtc-experiment.com/licence/) . Copyright (c) [Muaz Khan](http://www.MuazKhan.com).
{
"name": "multistreamsmixer",
"description": "Pass multiple streams (e.g. screen+camera or multiple-cameras) and get single stream.",
"version": "1.0.7",
"authors": [
{
"name": "Muaz Khan",
"email": "muazkh@gmail.com",
"homepage": "https://muazkhan.com/"
}
],
"main": "./MultiStreamsMixer.js",
"keywords": [
"webrtc",
"multistreamsmixer",
"webrtc-library",
"library",
"javascript",
"rtcweb",
"webrtc-experiment",
"javascript-library",
"muaz",
"muaz-khan"
],
"repository": {
"type": "git",
"url": "https://github.com/muaz-khan/MultiStreamsMixer.git"
},
"homepage": "https://www.webrtc-experiment.com/MultiStreamsMixer/",
"ignore": [
"**/.*",
"node_modules",
"test",
"tests"
]
}
# MultiStreamsMixer | Mix Multiple Cameras & Screens into Single Stream
MultiStreamsMixer.js is separated/splitted into unique files.
This directory contains all those development files.
`grunt` tools are used to concatenate/merge all these files into `~/MultiStreamsMixer.js`.
## License
[MultiStreamsMixer.js](https://github.com/muaz-khan/MultiStreamsMixer) is released under [MIT licence](https://www.webrtc-experiment.com/licence/) . Copyright (c) [Muaz Khan](http://www.MuazKhan.com/).
this.appendStreams = function(streams) {
if (!streams) {
throw 'First parameter is required.';
}
if (!(streams instanceof Array)) {
streams = [streams];
}
arrayOfMediaStreams.concat(streams);
streams.forEach(function(stream) {
if (stream.getTracks().filter(function(t) {
return t.kind === 'video';
}).length) {
var video = getVideo(stream);
video.stream = stream;
videos.push(video);
}
if (stream.getTracks().filter(function(t) {
return t.kind === 'audio';
}).length && self.audioContext) {
var audioSource = self.audioContext.createMediaStreamSource(stream);
audioSource.connect(self.audioDestination);
self.audioSources.push(audioSource);
}
});
};
// _____________________________
// Cross-Browser-Declarations.js
// WebAudio API representer
var AudioContext = window.AudioContext;
if (typeof AudioContext === 'undefined') {
if (typeof webkitAudioContext !== 'undefined') {
/*global AudioContext:true */
AudioContext = webkitAudioContext;
}
if (typeof mozAudioContext !== 'undefined') {
/*global AudioContext:true */
AudioContext = mozAudioContext;
}
}
/*jshint -W079 */
var URL = window.URL;
if (typeof URL === 'undefined' && typeof webkitURL !== 'undefined') {
/*global URL:true */
URL = webkitURL;
}
if (typeof navigator !== 'undefined' && typeof navigator.getUserMedia === 'undefined') { // maybe window.navigator?
if (typeof navigator.webkitGetUserMedia !== 'undefined') {
navigator.getUserMedia = navigator.webkitGetUserMedia;
}
if (typeof navigator.mozGetUserMedia !== 'undefined') {
navigator.getUserMedia = navigator.mozGetUserMedia;
}
}
var MediaStream = window.MediaStream;
if (typeof MediaStream === 'undefined' && typeof webkitMediaStream !== 'undefined') {
MediaStream = webkitMediaStream;
}
/*global MediaStream:true */
if (typeof MediaStream !== 'undefined') {
// override "stop" method for all browsers
if (typeof MediaStream.prototype.stop === 'undefined') {
MediaStream.prototype.stop = function() {
this.getTracks().forEach(function(track) {
track.stop();
});
};
}
}
var Storage = {};
if (typeof AudioContext !== 'undefined') {
Storage.AudioContext = AudioContext;
} else if (typeof webkitAudioContext !== 'undefined') {
Storage.AudioContext = webkitAudioContext;
}
function setSrcObject(stream, element) {
if ('srcObject' in element) {
element.srcObject = stream;
} else if ('mozSrcObject' in element) {
element.mozSrcObject = stream;
} else {
element.srcObject = stream;
}
}
function drawVideosToCanvas() {
if (isStopDrawingFrames) {
return;
}
var videosLength = videos.length;
var fullcanvas = false;
var remaining = [];
videos.forEach(function(video) {
if (!video.stream) {
video.stream = {};
}
if (video.stream.fullcanvas) {
fullcanvas = video;
} else {
remaining.push(video);
}
});
if (fullcanvas) {
canvas.width = fullcanvas.stream.width;
canvas.height = fullcanvas.stream.height;
} else if (remaining.length) {
canvas.width = videosLength > 1 ? remaining[0].width * 2 : remaining[0].width;
var height = 1;
if (videosLength === 3 || videosLength === 4) {
height = 2;
}
if (videosLength === 5 || videosLength === 6) {
height = 3;
}
if (videosLength === 7 || videosLength === 8) {
height = 4;
}
if (videosLength === 9 || videosLength === 10) {
height = 5;
}
canvas.height = remaining[0].height * height;
} else {
canvas.width = self.width || 360;
canvas.height = self.height || 240;
}
if (fullcanvas && fullcanvas instanceof HTMLVideoElement) {
drawImage(fullcanvas);
}
remaining.forEach(function(video, idx) {
drawImage(video, idx);
});
setTimeout(drawVideosToCanvas, self.frameInterval);
}
function drawImage(video, idx) {
if (isStopDrawingFrames) {
return;
}
var x = 0;
var y = 0;
var width = video.width;
var height = video.height;
if (idx === 1) {
x = video.width;
}
if (idx === 2) {
y = video.height;
}
if (idx === 3) {
x = video.width;
y = video.height;
}
if (idx === 4) {
y = video.height * 2;
}
if (idx === 5) {
x = video.width;
y = video.height * 2;
}
if (idx === 6) {
y = video.height * 3;
}
if (idx === 7) {
x = video.width;
y = video.height * 3;
}
if (typeof video.stream.left !== 'undefined') {
x = video.stream.left;
}
if (typeof video.stream.top !== 'undefined') {
y = video.stream.top;
}
if (typeof video.stream.width !== 'undefined') {
width = video.stream.width;
}
if (typeof video.stream.height !== 'undefined') {
height = video.stream.height;
}
context.drawImage(video, x, y, width, height);
if (typeof video.stream.onRender === 'function') {
video.stream.onRender(context, x, y, width, height, idx);
}
}
function getMixedAudioStream() {
// via: @pehrsons
if (!Storage.AudioContextConstructor) {
Storage.AudioContextConstructor = new Storage.AudioContext();
}
self.audioContext = Storage.AudioContextConstructor;
self.audioSources = [];
if (self.useGainNode === true) {
self.gainNode = self.audioContext.createGain();
self.gainNode.connect(self.audioContext.destination);
self.gainNode.gain.value = 0; // don't hear self
}
var audioTracksLength = 0;
arrayOfMediaStreams.forEach(function(stream) {
if (!stream.getTracks().filter(function(t) {
return t.kind === 'audio';
}).length) {
return;
}
audioTracksLength++;
var audioSource = self.audioContext.createMediaStreamSource(stream);
if (self.useGainNode === true) {
audioSource.connect(self.gainNode);
}
self.audioSources.push(audioSource);
});
if (!audioTracksLength) {
return;
}
self.audioDestination = self.audioContext.createMediaStreamDestination();
self.audioSources.forEach(function(audioSource) {
audioSource.connect(self.audioDestination);
});
return self.audioDestination.stream;
}
function getMixedStream() {
isStopDrawingFrames = false;
var mixedVideoStream = getMixedVideoStream();
var mixedAudioStream = getMixedAudioStream();
if (mixedAudioStream) {
mixedAudioStream.getTracks().filter(function(t) {
return t.kind === 'audio';
}).forEach(function(track) {
mixedVideoStream.addTrack(track);
});
}
var fullcanvas;
arrayOfMediaStreams.forEach(function(stream) {
if (stream.fullcanvas) {
fullcanvas = true;
}
});
return mixedVideoStream;
}
function getMixedVideoStream() {
resetVideoStreams();
var capturedStream;
if ('captureStream' in canvas) {
capturedStream = canvas.captureStream();
} else if ('mozCaptureStream' in canvas) {
capturedStream = canvas.mozCaptureStream();
} else if (!self.disableLogs) {
console.error('Upgrade to latest Chrome or otherwise enable this flag: chrome://flags/#enable-experimental-web-platform-features');
}
var videoStream = new MediaStream();
capturedStream.getTracks().filter(function(t) {
return t.kind === 'video';
}).forEach(function(track) {
videoStream.addTrack(track);
});
canvas.stream = videoStream;
return videoStream;
}
function getVideo(stream) {
var video = document.createElement('video');
setSrcObject(stream, video);
video.muted = true;
video.volume = 0;
video.width = stream.width || self.width || 360;
video.height = stream.height || self.height || 240;
video.play();
return video;
}
function MultiStreamsMixer(arrayOfMediaStreams) {
// requires: chrome://flags/#enable-experimental-web-platform-features
var videos = [];
var isStopDrawingFrames = false;
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.style = 'opacity:0;position:absolute;z-index:-1;top: -100000000;left:-1000000000; margin-top:-1000000000;margin-left:-1000000000;';
(document.body || document.documentElement).appendChild(canvas);
this.disableLogs = false;
this.frameInterval = 10;
this.width = 360;
this.height = 240;
// use gain node to prevent echo
this.useGainNode = true;
var self = this;
if (typeof module !== 'undefined' /* && !!module.exports*/ ) {
module.exports = MultiStreamsMixer;
}
this.releaseStreams = function() {
videos = [];
isStopDrawingFrames = true;
if (self.gainNode) {
self.gainNode.disconnect();
self.gainNode = null;
}
if (self.audioSources.length) {
self.audioSources.forEach(function(source) {
source.disconnect();
});
self.audioSources = [];
}
if (self.audioDestination) {
self.audioDestination.disconnect();
self.audioDestination = null;
}
if (self.audioContext) {
self.audioContext.close();
}
self.audioContext = null;
context.clearRect(0, 0, canvas.width, canvas.height);
if (canvas.stream) {
canvas.stream.stop();
canvas.stream = null;
}
};
this.resetVideoStreams = function(streams) {
if (streams && !(streams instanceof Array)) {
streams = [streams];
}
resetVideoStreams(streams);
};
function resetVideoStreams(streams) {
videos = [];
streams = streams || arrayOfMediaStreams;
// via: @adrian-ber
streams.forEach(function(stream) {
if (!stream.getTracks().filter(function(t) {
return t.kind === 'video';
}).length) {
return;
}
var video = getVideo(stream);
video.stream = stream;
videos.push(video);
});
}
this.startDrawingFrames = function() {
drawVideosToCanvas();
};
// for debugging
this.name = 'MultiStreamsMixer';
this.toString = function() {
return this.name;
};
this.getMixedStream = getMixedStream;
}
This diff is collapsed.
{
"name": "multistreamsmixer",
"preferGlobal": true,
"version": "1.0.7",
"author": {
"name": "Muaz Khan",
"email": "muazkh@gmail.com",
"url": "https://muazkhan.com/"
},
"description": "Pass multiple streams (e.g. screen+camera or multiple-cameras) and get single stream.",
"scripts": {
"start": "node server.js"
},
"main": "./MultiStreamsMixer.js",
"repository": {
"type": "git",
"url": "https://github.com/muaz-khan/MultiStreamsMixer.git"
},
"keywords": [
"webrtc",
"multistreamsmixer",
"webrtc-library",
"library",
"javascript",
"rtcweb",
"webrtc-experiment",
"javascript-library",
"muaz",
"muaz-khan"
],
"analyze": false,
"license": "MIT",
"readmeFilename": "README.md",
"bugs": {
"url": "https://github.com/muaz-khan/MultiStreamsMixer/issues",
"email": "muazkh@gmail.com"
},
"homepage": "https://www.webrtc-experiment.com/MultiStreamsMixer/",
"_id": "multistreamsmixer@",
"_from": "multistreamsmixer@",
"devDependencies": {
"grunt": "0.4.5",
"grunt-bump": "0.7.0",
"grunt-cli": "0.1.13",
"grunt-contrib-concat": "0.5.1",
"grunt-contrib-uglify": "0.11.0",
"grunt-jsbeautifier": "0.2.10",
"load-grunt-tasks": "3.4.0",
"grunt-contrib-watch": "^1.1.0"
}
}
// http://127.0.0.1:9001
// http://localhost:9001
var server = require('http'),
url = require('url'),
path = require('path'),
fs = require('fs');
function serverHandler(request, response) {
var uri = url.parse(request.url).pathname,
filename = path.join(process.cwd(), uri);
fs.exists(filename, function(exists) {
if (!exists) {
response.writeHead(404, {
'Content-Type': 'text/plain'
});
response.write('404 Not Found: ' + filename + '\n');
response.end();
return;
}
if (filename.indexOf('favicon.ico') !== -1) {
return;
}
var isWin = !!process.platform.match(/^win/);
if (fs.statSync(filename).isDirectory() && !isWin) {
filename += '/index.html';
} else if (fs.statSync(filename).isDirectory() && !!isWin) {
filename += '\\index.html';
}
fs.readFile(filename, 'binary', function(err, file) {
if (err) {
response.writeHead(500, {
'Content-Type': 'text/plain'
});
response.write(err + '\n');
response.end();
return;
}
var contentType;
if (filename.indexOf('.html') !== -1) {
contentType = 'text/html';
}
if (filename.indexOf('.js') !== -1) {
contentType = 'application/javascript';
}
if (contentType) {
response.writeHead(200, {
'Content-Type': contentType
});
} else response.writeHead(200);
response.write(file, 'binary');
response.end();
});
});
}
var app;
app = server.createServer(serverHandler);
app = app.listen(process.env.PORT || 9001, process.env.IP || "0.0.0.0", function() {
var addr = app.address();
console.log("Server listening at", addr.address + ":" + addr.port);
});
<?php
namespace App\Commands;
use App\Commands\Command;
use Illuminate\Contracts\Bus\SelfHandling;
class VmjChat extends Command implements SelfHandling
{
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
//
}
/**
* Execute the command.
*
* @return void
*/
public function handle()
{
//
}
}
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Foundation\Inspiring;
class Inspire extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'inspire';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Display an inspiring quote';
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->comment(PHP_EOL.Inspiring::quote().PHP_EOL);
}
}
<?php
namespace App\Console\Commands;
//use App\Commands\Command;
use Illuminate\Console\Command;
class VmjChat extends Command
{
protected $signature = 'vmj:chat {vid}';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the command.
*
* @return void
*/
public function handle(){
$vid = $this->argument('vid');
echo 'Proverka Vmj Chat.['.$vid.']....';
}
}
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Ratchet\Server\IoServer;
use Ratchet\Http\HttpServer;
use Ratchet\WebSocket\WsServer;
use App\Http\Controllers\WebSocketController;
class WebSocketServer extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'websocket:init';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Initializing Websocket server to receive and manage connections';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return void
*/
public function handle()
{
$server = IoServer::factory(
new HttpServer(
new WsServer(
new WebSocketController()
)
),
8085
);
$server->run();
}
}
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
Commands\Inspire::class,
//Commands\VmjChat::class,
//Commands\WebSocketServer::class
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
$schedule->command('inspire')
->hourly();
}
}
<?php
namespace App\Events;
abstract class Event
{
//
}
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
HttpException::class,
ModelNotFoundException::class,
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $e
* @return void
*/
public function report(Exception $e)
{
return parent::report($e);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if ($e instanceof ModelNotFoundException) {
$e = new NotFoundHttpException($e->getMessage(), $e);
}
if( method_exists($e, "getStatusCode")){
if ($e->getStatusCode() == 404) {
return \Response::view('errors.404',array(),404);
}
}
if( substr($e->getMessage(),0,9) == "fsockopen" ){
header('Content-Type: application/json');
return \Response::view('errors.200',array(),200);
} else {
return parent::render($request, $e);
}
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class AdminsController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
public function __construct(){
}
protected function Begin(Request $request){
if( !Auth::check() ){
return redirect('/');
}
//$settingPath = str_replace("settings/","", $request->path());
//var_dump($settingPath);
//if( empty($input) ){ return false; }
//if( empty($input["func"]) ){ return false; } else { $method = $input["func"]; }
//var_dump("sdfsfsdf");
return view('admins'); //,['path',$settingPath]
}
}
\ No newline at end of file
This diff is collapsed.
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Http\RedirectResponse;
class AuthController extends Controller
{
/*
|--------------------------------------------------------------------------
| Registration & Login Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users, as well as the
| authentication of existing users. By default, this controller uses
| a simple trait to add these behaviors. Why don't you explore it?
|
*/
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
/**
* Create a new authentication controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'getLogout']);
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'phone' => 'required|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'phone' => $data['phone'],
'password' => bcrypt($data['password']),
]);
}
public function postLogin(Request $request)
{
$auth = false;
$credentials = $request->only('email', 'password');
if (Auth::attempt($credentials, $request->has('remember'))) {
$auth = true; // Success
}
if ($request->ajax()) {
return response()->json([
'auth' => $auth,
'intended' => URL::previous()
]);
} else {
return redirect()->intended(URL::route('dashboard'));
}
return redirect(URL::route('login_page'));
}
protected function postRegister(){
return "Registering in....";
}
protected function getLogin(){
return view('auth.login');
}
protected function getRegister(){
return view('auth.register');
}
protected function getLogout(){
\Session::forget('ulogin');
\Session::forget('uname');
\Session::forget('unumber');
\Session::forget('upass');
\Session::forget('utocall');
\Auth::logout();
//return redirect()->action( 'UserController@profile', ['sw_msg' => "Thank you!"]);
session(['sw_msg' => "Thank you!"]);
return redirect('/'); //->route('/', ['sw_msg' => "Thank you!"]);
}
}
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
class PasswordController extends Controller
{
/*
|--------------------------------------------------------------------------
| Password Reset Controller
|--------------------------------------------------------------------------
|
| This controller is responsible for handling password reset requests
| and uses a simple trait to include this behavior. You're free to
| explore this trait and override any methods you wish to tweak.
|
*/
use ResetsPasswords;
/**
* Create a new password controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest');
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ChatsController extends Controller
{
protected function Begin(){
/*if( Auth::check() ){
$user = \Auth::user();
$uid = \Session::get('uid');
//var_dump($user);
return view('dashboard',["user"=>$user,"uid"=>$uid]);
} elseif( !empty(\Session::get('ulogin')) ) {
return redirect('/meet');
} else {
if( $jmsg = session('sw_msg') ){
\Session::forget('sw_msg');
return view('welcome',["sw_msg"=>$jmsg]);
}*/
return view('welcome');
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class ClicktocallController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
public function __construct(){
}
protected function Begin(Request $request){
if( !Auth::check() ){
return redirect('/');
}
$settingPath = str_replace("settings/","", $request->path());
//var_dump($settingPath);
//if( empty($input) ){ return false; }
//if( empty($input["func"]) ){ return false; } else { $method = $input["func"]; }
return view('clicktocall');
}
}
\ No newline at end of file
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Routing\Controller as BaseController;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
abstract class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class FilesController extends Controller
{
protected function Begin(Request $request){
$fid = substr(str_replace("webinar/","", $request->path()),6);
if( is_numeric($fid) ){
$arFiles = DB::table('files')->where('id', $fid)->get();
if( empty($arFiles) ){
return "File not found![".$fid."]";
die();
}
$arFile = json_decode(json_encode($arFiles[0]),true);
$fpath = $arFile["path"].$arFile["uploadedname"];
$this->file_force_download($fpath,$arFile["filename"]);
/*
["id"]=> int(8)
["filename"]=> string(62) "Инструкция_по_приёму_и_переводу.doc"
["uploadedname"]=> string(20) "D4QL49_gw2qOA6mgtlmq"
["date"]=> int(1550667807)
["room"]=> string(4) "8906"
["path"]=> string(48) "/var/www/html/online.vmajlis.uz/storage/uploads/"
["desc"]=> string(0) ""
*/
//$fpath = htmlspecialchars(urldecode($fpath));
//$upldir = dirname(dirname(dirname(__DIR__))).'/storage/uploads' ;
/*
return view('files',[
"arrFile"=>$arFile,
]);
die();
*/
} else {
}
}
function file_force_download($file,$uname=false) {
if(empty($uname)) { $uname = basename($file); }
if (file_exists($file)) {
// сбрасываем буфер вывода PHP, чтобы избежать переполнения памяти выделенной под скрипт
// если этого не сделать файл будет читаться в память полностью!
if (ob_get_level()) {
ob_end_clean();
}
// заставляем браузер показать окно сохранения файла
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $uname);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
// читаем файл и отправляем его пользователю
readfile($file);
exit;
}
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LangController extends Controller
{
protected function chooseLang(Request $request){
/*
if (App::isLocale('en')) {
//
}*/
$locl = str_replace("/","", $request->path());
//$locale = \Session::get('locale');
if( empty($locl) ){
\App::setLocale("ru");
\Session::set('locale', "ru");
} else {
\Session::set('locale', $locl);
\App::setLocale($locl);
}
/*
Route::get('/en', function () { \Session::set('locale', "en"); return back(); });
Route::get('/uz', function () { \Session::set('locale', "uz"); return back(); });
Route::get('/ru', function () { \Session::set('locale', "ru"); return back(); });
*/
//return redirect('/meet');
return back();
//var_dump( $locl );
//return view('welcome' [ "locale"=> $locale, 'locl'=>$locl ] );
}
}
\ No newline at end of file
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LayoutsController extends Controller
{
// use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected function Begin(){
if( !Auth::check() ){
return redirect('/');
}
$curLayout = \Session::get('current_layout');
//$lyt = str_replace("layouts/","", $request->path());
//$vData = ["all"=>$allLayouts];
$vData = [];
if( !empty($curLayout) ){ $vData["current"] = $curLayout; }
return view('layouts',$vData);
}
}
<?php
namespace App\Http\Controllers;
use Mail;
use App\User;
use App\Vms;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LiveController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
static protected $vms;
public function __construct()
{
self::$vms = new Vms;
/*if( Auth::check() ){
header('Content-Type: application/json');
echo json_encode( array("error"=>"no authorisation") );
}*/
//$this->middleware('guest', ['except' => 'getLogout']);
//return view('ajax',['data'=>$input]);
}
protected function getIP(Request $request){
//$allh = $request->headers()->all();
//var_dump($allh);
//var_dump("<HR>");
//var_dump($_SERVER);
}
protected function createUser($arPeer){
//$response = self::$vms->eRequest( "api reloadxml" );
}
protected function doAction(Request $request){
$uid = \Session::get('uid');
$typeuser = \Session::get('utype');
$uroom = \Session::get('uroom');
if( empty($typeuser) ){
return redirect('/');
}
if( $typeuser !== 'live' ){
return redirect('/');
}
$isLiveStream = self::$vms->isConfStreaming($uroom);
if( $isLiveStream ){
return view('livestream',["uroom"=>$uroom]);
} else {
return view('livestream_off',["uroom"=>$uroom]);
}
//return "The end";
//return view('livestream');
//$input = $request->all();
/*if( !empty($input["rname"]) ){
return self::createRoom($input["rname"]);
}*/
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Vms;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
use Cookie;
class MainController extends Controller
{
protected function Begin(Request $request){
$locale = \App::getLocale();
$vms = new Vms;
if( (!empty($_COOKIE["vmj_uid"])) && (!empty($_COOKIE["vmj_mdp"])) ){
$u_auth = $vms->checkWrtcPassAndEnter( array("uid"=>$_COOKIE["vmj_uid"],"mdpassword"=>$_COOKIE["vmj_mdp"]) );
if( !is_array($u_auth) ){
$clearCookie = true;
} else {
\Session::set('tologin',$u_auth["password"]);
}
}
if( Auth::check() ){
$user = \Auth::user();
$uid = \Session::get('uid');
//var_dump($user);
$arClients = $vms->getAllUsers();
return view('dashboard',[
"user"=>$user,
"uid"=>$uid,
"clients" => $arClients,
//"f_lang_text" => $f_lang_text,
//"s_lang_link" => $s_lang_link,
//"s_lang_text" => $s_lang_text,
]);
} elseif( !empty(\Session::get('ulogin')) ) {
$utype = \Session::get('utype');
$utype = (!empty($utype)) ? $utype : "";
if( $utype == "live" ){
return redirect('/live');
}
return redirect('/meet');
} else {
$welldatas = array(
//"f_lang_link" => $f_lang_link,
//"f_lang_text" => $f_lang_text,
//"s_lang_link" => $s_lang_link,
//"s_lang_text" => $s_lang_text,
"vmj_uid" => "",
"vmj_mdp" => "",
);
if( $jmsg = session('sw_msg') ){
\Session::forget('sw_msg');
$welldatas["sw_msg"] = $jmsg ;
}
return view('welcome',$welldatas);
}
}
}
//var_dump($vmj_mdp, $vmj_uid);
/*$langPath = base_path('resources/lang/'.$locale); //''; //resource_path('lang/'.\App::getLocale());
$allLang = collect(File::allFiles($langPath))->flatMap(function ($file) {
return [
($translation = $file->getBasename('.php')) => trans($translation),
];
})->toJson();
*/
//var_dump($allLang);
//var_dump( trans("lang.wbr_subject_temp") );
\ No newline at end of file
<?php
namespace App\Http\Controllers;
use App\User;
use App\Vms;
use App\Mobile_Detect;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class MeetController extends Controller
{
protected function Begin(Request $request){
$detect = new Mobile_Detect;
$ulogin = \Session::get('ulogin');
$wurl = $request->url();
$devType = ($detect->isMobile()) ? "Mobile" : "PC";
if( $wurl == "http://webinar.vmajlis.uz/meet" ){
return view('meet',[
"uname"=>"Kulya",
"unumber"=>"7979",
"upass"=>"733d7be2196ff70efaf6913fc8bdcabf",
"utocall"=>"7777",
"ulogin"=>"kulya",
"dev"=>$devType
]);
} elseif( empty($ulogin) ){
return redirect('/');
} else {
$uname = \Session::get('uname');
$unumber = \Session::get('unumber');
$upass = \Session::get('upass');
$utocall = \Session::get('utocall');
$tologin = \Session::get('tologin');
$sharenum = \Session::get('sharenum');
//$user = \Auth::user();
$arRooms = DB::table('rooms')->get();
$uRooms = [];
foreach( $arRooms as $rm){
$rUsrs = json_decode($rm->users);
if(!empty($rUsrs)){
if( in_array($unumber,$rUsrs) ){
$uRooms[] = array("id"=>$rm->number, "value"=>$rm->name);
}
}
}
return view('meet',[
"uname"=>$uname,
"unumber"=>$unumber,
"upass"=>$upass,
"utocall"=>$utocall,
"ulogin"=>$ulogin,
"tologin"=>$tologin,
"urooms"=>$uRooms,
"sharenum"=>$sharenum,
"dev"=>$devType
]);
}
}
protected function Begintest(Request $request){
$detect = new Mobile_Detect;
$ulogin = \Session::get('ulogin');
$wurl = $request->url();
$devType = ($detect->isMobile()) ? "Mobile" : "PC";
if( empty($ulogin) ){
$vms = new Vms;
$testUser = DB::table('clients')->where('id', 34)->get();
$vms->enterToSystemIfGoodLogin($testUser[0]);
}
$uname = \Session::get('uname');
$unumber = \Session::get('unumber');
$upass = \Session::get('upass');
$utocall = \Session::get('utocall');
$tologin = \Session::get('tologin');
//$user = \Auth::user();
$arRooms = DB::table('rooms')->get();
$uRooms = [];
foreach( $arRooms as $rm){
if(!empty($rm->users)){
$rUsrs = json_decode($rm->users);
if(!empty($rUsrs)){
if( in_array($unumber,$rUsrs) ){
$uRooms[] = array("id"=>$rm->number, "value"=>$rm->name);
}
}
}
}
return view('meet',[
"uname"=>$uname,
"unumber"=>$unumber,
"upass"=>$upass,
"utocall"=>$utocall,
"ulogin"=>$ulogin,
"tologin"=>$tologin,
"urooms"=>$uRooms,
"dev"=>$devType
]);
}
protected function Share(Request $request){
$detect = new Mobile_Detect;
$devType = ($detect->isMobile()) ? "Mobile" : "PC";
$ulogin = \Session::get('ulogin');
$wurl = $request->url();
if($detect->isMobile()) {
return redirect('/meet');
}
if( empty($ulogin) ){
return redirect('/');
} else {
$sharename = \Session::get('sharename');
$sharenum = \Session::get('sharenum');
$shareroom = \Session::get('shareroom');
$sharepass = \Session::get('sharepass');
return view('sharing',[
"sharename"=>$sharename,
"sharenum"=>$sharenum,
"shareroom"=>$shareroom,
"sharepass"=>$sharepass,
"dev"=>$devType
]);
}
}
protected function Cam(Request $request){
return view('mycam');
}
protected function getSourceId(Request $request){
return view('getSourceId');
}
protected function rcControl(Request $request){
return view('remotecontrol');
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Mobile_Detect;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class MeetsController extends Controller
{
protected function Begin(Request $request){
$detect = new Mobile_Detect;
$ulogin = \Session::get('ulogin');
$wurl = $request->url();
$devType = ($detect->isMobile()) ? "Mobile" : "PC";
//var_dump($wurl);
if( $wurl == "https://online.vmajlis.uz/meets" ){
return view('meets',[
"uname"=>"Kulya",
"unumber"=>"7979",
"upass"=>"733d7be2196ff70efaf6913fc8bdcabf",
"utocall"=>"3333",
"ulogin"=>"kulya",
"dev"=>$devType
]);
}
/*elseif( empty($ulogin) ){
return redirect('/');
} else {
//$user = \Auth::user();
$uname = \Session::get('uname');
$unumber = \Session::get('unumber');
$upass = \Session::get('upass');
$utocall = \Session::get('utocall');
return view('meet',[
"uname"=>$uname,
"unumber"=>$unumber,
"upass"=>$upass,
"utocall"=>$utocall,
"ulogin"=>$ulogin,
"dev"=>$devType
]);
}*/
}
protected function Cam(Request $request){
return view('mycam');
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class PersonalCabinetController extends Controller
{
protected function Begin(Request $request){
$uid = \Session::get('uid');
$avatar_id = DB::table('files')->where('uid',$uid)->where('desc','avatar')->value('id');
$logo_id = DB::table('files')->where('uid',$uid)->where('desc','logo')->value('id');
//$room = str_replace("cabinet/","", $request->path());
return view('cabinet',['uid'=>$uid,'avatar_id'=>$avatar_id,'logo_id'=>$logo_id]);
/*if( !empty($ulogin) ){
return redirect('/');
} else {
//$user = \Auth::user();
$uname = \Session::get('uname');
$unumber = \Session::get('unumber');
$upass = \Session::get('upass');
$utocall = \Session::get('utocall');
return view('webinar');
}*/
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RecordingsController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
public function __construct(){
}
protected function Begin(Request $request){
$recs_path = $rPath = config('vms.records_path');
$recFile = str_replace("recordings/","", $request->path());
$fullFile = $recs_path.$recFile;
$fileSize = filesize($fullFile);
$humanSize = self::human_filesize($fileSize);
return response()->download($fullFile);
//return array("file"=>$recFile,"full"=>$recs_path.$recFile,"bytes"=>$fileSize, "hs"=>$humanSize);
//return view('settings',['path',$settingPath]);
//$file = basename($_GET['file']);
//$file = '/path/to/your/dir/'.$file;
/*
if(!file_exists($fuulFile)){ // file does not exist
return 'file not found';
} else {
header("Cache-Control: public");
header("Content-Description: File Transfer");
header("Content-Disposition: attachment; filename=$recFile");
header("Content-Type: application/zip");
header("Content-Transfer-Encoding: binary");
header("Content-length: $fileSize");
// read the file from disk
readfile($fuulFile);
}*/
}
function human_filesize($bytes, $decimals = 2) {
$sz = 'BKMGTP';
$factor = floor((strlen($bytes) - 1) / 3);
return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
}
}
\ No newline at end of file
<?php
namespace App\Http\Controllers;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class RoomController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
public function __construct()
{
//$this->middleware('guest', ['except' => 'getLogout']);
//return view('ajax',['data'=>$input]);
}
protected function openRoom(Request $request){
if( !Auth::check() ){
return redirect('/');
}
$roomNumber = str_replace("room/","", $request->path());
return view('room',["number"=>$roomNumber]);
}
}
<?php
namespace App\Http\Controllers\Settings;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class SettingsController extends Controller
{
/**
* Create a new authentication controller instance.
*
* @return void
*/
public function __construct()
{
// $this->middleware('settings', ['except' => 'getLogout']);
}
/**
* Get a validator for an incoming registration request.
*
* @param array $data
* @return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'phone' => 'required|max:255|unique:users',
'password' => 'required|confirmed|min:6',
]);
}
/**
* Create a new user instance after a valid registration.
*
* @param array $data
* @return User
*/
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'phone' => $data['phone'],
'password' => bcrypt($data['password']),
]);
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class SettingsController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
public function __construct(){
}
protected function Begin(Request $request){
if( !Auth::check() ){
return redirect('/');
}
$settingPath = str_replace("settings/","", $request->path());
//var_dump($settingPath);
//if( empty($input) ){ return false; }
//if( empty($input["func"]) ){ return false; } else { $method = $input["func"]; }
return view('settings',['path',$settingPath]);
}
}
\ No newline at end of file
<?php
namespace App\Http\Controllers;
use Mail;
use App\User;
use App\Vms;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class TestController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
static protected $vms;
public function __construct()
{
self::$vms = new Vms;
/*if( Auth::check() ){
header('Content-Type: application/json');
echo json_encode( array("error"=>"no authorisation") );
}*/
//$this->middleware('guest', ['except' => 'getLogout']);
//return view('ajax',['data'=>$input]);
}
protected function getIP(Request $request){
//$allh = $request->headers()->all();
//var_dump($allh);
//var_dump("<HR>");
var_dump($_SERVER);
}
protected function createUser($arPeer){
/*
num
password
name
room
*/
if( empty($arPeer["num"]) || empty($arPeer["password"]) || empty($arPeer["name"])){
return false;
}
if( empty($arPeer["room"]) ) { $pRoom = '7777';}
$peer_temp = '<include>
<user id="'.$arPeer["num"].'">
<params>
<param name="password" value="'.$arPeer["password"].'"/>
<param name="vm-password" value="'.$arPeer["password"].'"/>
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local"/>
<variable name="accountcode" value="'.$arPeer["num"].'"/>
<variable name="user_context" value="default"/>
<variable name="effective_caller_id_name" value="'.$arPeer["name"].'"/>
<variable name="effective_caller_id_number" value="'.$arPeer["num"].'"/>
<variable name="outbound_caller_id_name" value="'.$arPeer["name"].'"/>
<variable name="outbound_caller_id_number" value="'.$arPeer["num"].'"/>
<variable name="callgroup" value="'.$pRoom.'"/>
</variables>
</user>
</include>';
if( self::save_user_file($arPeer["num"], $peer_temp) ){
//$vms = new Vms;
$response = self::$vms->eRequest( "api reloadxml" );
var_dump($response);
}
}
protected function myget(){
//$rooms_path = config('vms.rooms_path');
//var_dump($rooms_path);
/*
$response = self::$vms->eRequest( "api conference json_list" );
var_dump($response);
$arActiveRooms = json_decode($response."}]",true);
echo "<pre>";
var_dump($arActiveRooms);
echo "</pre>";
echo "<hr>";
*/
$vms = new Vms;
$rooms = $vms->getAllRooms();
echo "<pre>";
var_dump($rooms);
echo "</pre>";
echo "<hr>";
/*$users = self::$vms->getAllUsers();
echo "<pre>";
var_dump($users);
echo "</pre>";
echo "<hr>";*/
//$usersResponse = self::$vms->eRequest( "api list_users" );
//$arActiveUsers = json_decode($usersResponse."}]",true);
/*$roomXml = Vms::createRoomXml(array("number"=>7777,"name"=>"MyMajlis1","member_flags"=>"join-vid-floor"));
echo "<textarea row='50'>";
echo $roomXml;
echo "</textarea>";*/
}
protected function createRoom($name){
$room_temp = '<include>
<extension name="cdquality_stereo_conferences">
<condition field="destination_number" expression="(7777)">
<action application="answer"/>
<action application="send_display" data="vMajlis|$1"/>
<action application="set" data="conference_member_flags=join-vid-floor"/>
<action application="conference" data="$1@video-mcu-stereo"/>
</condition>
</extension>
</include>
';
if( self::save_room_file($name, $room_temp) ){
$vms = new Vms;
$response = $vms->eRequest( "api reloadxml" );
var_dump($response);
}
}
protected function save_user_file($name, $data){
$users_path = '/usr/local/freeswitch/conf/directory/vmajlis/';
if( $myfile = fopen($users_path."vmj_".$name.".xml", "w")) {
fwrite($myfile, $data);
fclose($myfile);
return true;
} else {
return false;
}
}
protected function save_room_file($name, $data){
$rooms_path = '/usr/local/freeswitch/conf/dialplan/vmajlis/';
//$rooms_path = '/var/www/html/test.vmajlis.uz/storage/vmj/';
if( $myfile = fopen($rooms_path."vmj_".$name.".xml", "w")) {
fwrite($myfile, $data);
fclose($myfile);
return true;
} else {
return false;
}
}
protected function doAction(Request $request){
/*$data = array("speakername"=>"Michael Jackson","subject"=>"Music is everythink of we!","link"=>"https://webinar.vmajlis.uz/WLqH5Y6WcM");
Mail::send('emails.invitewebinar', $data, function ($message) use ($data){
//$message->from('no-reply@vmajlis.uz', 'vMajlisTest1');
//$message->to('knavruzov@technounit.uz')->cc('bar@example.com');
$message->to('knavruzov@technounit.uz')->subject('S-'.$data["subject"]);
//$message->subject($subject);
echo "Massage sent";
});*/
return view('tests');
/*$input = $request->all();
if( !empty($input["rname"]) ){
return self::createRoom($input["rname"]);
}
if( !empty($input["pname"]) ){
return self::createUser(array(
"num" => $input["pnum"],
"name" => $input["pname"],
"password" => $input["ppass"],
));
}
if( !empty($input["f"]) ){
$method = $input["f"];
if( method_exists($this, $method) ){
$this->$method($input);
}
}
*/
}
}
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class TopngController extends Controller
{
public function __construct()
{
}
protected function Begin(Request $request){
$ptext = str_replace("topng/","", $request->path());
//var_dump($ptext);
$this->create_png_from_text(["text"=>urldecode($ptext),"width"=>1920,"height"=>1080]);
//return view('room',["number"=>$roomNumber]);
exit;
}
protected function create_png_from_text($args){
$font = "/usr/local/freeswitch/fonts/montserrat/Montserrat-Italic.otf";
if( empty($args) ){ $args = "Default";}
if( !is_array($args) ){
$args = array( 'text' => $args );
}
$width = ( !empty($args["width"]) ) ? (int)$args["width"] : 640; //1920; //640;
$height = ( !empty($args["height"]) ) ? (int)$args["height"] : 480; //1080; //480;
$text = $args["text"];
$file = ( !empty($args["file"]) ) ? $args["file"] : false;
if( $width > 1000 ){
$fontsize = 25;
} else {
$fontsize = 20;
}
$imgTxtBlock = imagecreate($width, 50);
$imgTxtBack = imagecreate($width, 50);
$img = imagecreate($width, $height);
imagecolorallocate($imgTxtBlock, 0, 0, 0);
imagecolorallocate($imgTxtBack, 255, 255, 255);
$black = imagecolorallocate($img, 3, 169, 244);
//imagecolortransparent($imgTxtBlock, $blue);
imagecolortransparent($img, $black);
$txtInTransparent = imagecolorallocate($imgTxtBlock, 255, 255, 255);
//$txtInTransparent = imagecolorallocate($img, 255, 255, 255);
$image_width = imagesx($img);
$image_height = imagesy($img);
$text_box = imagettfbbox($fontsize, 0, $font, $text);
$text_width = $text_box[0] - $text_box[2];
$text_height = $text_box[1] - $text_box[7];
$x = 100; //$image_width - ($text_width / 2);
$y = $image_height - ($text_height + 45);
imagettftext($imgTxtBlock, $fontsize, 0, 20, 30, $txtInTransparent, $font, $text);
//imagettftext($imgTxtBlock, $fontsize, 0, $x, $y, $txtInTransparent, $font, $text);
//imagettftext($img, $fontsize, 0, $x, $y, $txtInTransparent, $font, $text);
//imagettftext($img, $fontsize, 0, $x, $y, $txtInTransparent, $font, $text.'-['.$image_height.']-['.$text_height.']-['.$y.']' ); //For tests
// Copy and merge
imagecopymerge( $imgTxtBack, $imgTxtBlock, 0, 0, 0, 0, $image_width, 40, 80);
imagecopymerge( $img, $imgTxtBack, 0, $y, 0, 0, $image_width, 40, 100);
if( !empty($file) ){
imagepng($img, $file);
} else {
header('Content-Type: image/png');
imagepng($img);
}
imagedestroy($img);
imagedestroy($imgTxtBlock);
imagedestroy($imgTxtBack);
}
}
?>
\ No newline at end of file
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class UsersController extends Controller
{
protected function Begin(){
if( !Auth::check() ){
return redirect('/');
}
//$user = \Auth::user();
$unumber = \Session::get('unumber');
$upass = \Session::get('upass');
$utocall = \Session::get('utocall');
return view('users');
//} else {
//}
}
}
<?php
namespace App\Http\Controllers;
use App\Vms;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
class VmjchatController extends Controller
{
//static protected $vms;
protected function doAction(){ //Request $request
$arData = (!empty($GLOBALS["datas"]) ) ? $GLOBALS["datas"] : false;
if(!$arData){ return '{}';}
$msgDate = time();
if( !empty( $arData["messageId"] ) ){
$vid = (!empty($arData["vid"])) ? $arData["vid"] : "";
if(empty($vid)){
$vid = (!empty($arData["wid"])) ? $arData["wid"] : "";
}
$arMsg = array(
"date" => $msgDate,
"from" => (!empty($arData["name"])) ? $arData["name"] : "Unknown",
"fromid" => (!empty($arData["vid"])) ? $arData["vid"] : "",
"to" => (!empty($arData["to"])) ? $arData["to"] : "",
"room" => (!empty($arData["room"])) ? $arData["room"] : "",
"msg" => (!empty($arData["message"])) ? $arData["message"] : "NoText",
);
$newMsgId = DB::table('messages')->insertGetId($arMsg);
$toName = ($arData["room"] !== $arData["to"] ) ? DB::table('visits')->where("id", $arData["to"])->value("name") : '';
$arVisitorKeys = DB::table('visits')->select('id')->whereIn("id", $arData["userkeys"])->where('room', $arData["room"])->get();
$arKeysVtr = array();
foreach ($arVisitorKeys as $vkes ){
$arKeysVtr[] = $vkes->id;
}
return json_encode(array("newMsgId"=>$newMsgId,"newMsgDate"=>$msgDate,"toName"=>$toName,"vkeys"=>$arKeysVtr));
}
if( !empty( $arData["cmd"] ) ){
$vid = (!empty($arData["vid"])) ? $arData["vid"] : "";
if(empty($vid)){
$vid = (!empty($arData["wid"])) ? $arData["wid"] : "";
}
if($arData['cmd'] == "getLastMessages" ){
if (empty($arData['msgscnt'])){ $arData['msgscnt'] = 15; }
}
if($arData['cmd'] == "getAllVisitors" ){
if (empty($arData['msgscnt'])){ $arData['msgscnt'] = 15; }
if(!empty($arData["vid"])){
$arVstr = DB::table('visits')->where('id', $vid)->get();
} elseif(!empty($arData["wid"])){
$arVstr = array(array("wid"=>$vid));
} else {
$arVstr = array(array("error"=>"Unknown you"));
}
$newvisit = (!empty($arVstr)) ? $arVstr[0] : "";
$arLastMessages = DB::table('messages')
->join('visits', 'messages.to', '=', 'visits.id')
->select('messages.*', 'visits.name as toName')
->where('messages.room', $arData["room"])
->orderBy('id', 'desc')
->limit($arData['msgscnt'])
->get();
$arVisitors = DB::table('visits')->whereIn("id", $arData["userkeys"])->where('room', $arData["room"])->get();
//$arVisitors = DB::table('visits')->whereIn("active", "Y")->where('room', $arData["room"])->get();
$arLastMessages = array_reverse($arLastMessages);
return json_encode(array("count"=>count($arVisitors), "allvisitors"=> $arVisitors, "arLastMessages"=> $arLastMessages, "newvisit"=> $newvisit));
}
}
}
}
<?php
namespace App\Http\Controllers;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class WebRTCController extends Controller
{
// use AuthenticatesAndRegistersUsers, ThrottlesLogins;
protected function Check(){
return "OK";
}
protected function Begin(){
if( !Auth::check() ){
return redirect('/');
}
$curLayout = \Session::get('current_layout');
//$lyt = str_replace("layouts/","", $request->path());
//$vData = ["all"=>$allLayouts];
$vData = [];
if( !empty($curLayout) ){ $vData["current"] = $curLayout; }
return view('layouts',$vData);
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* @var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
];
/**
* The application's route middleware.
*
* @var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'checkLang' => \App\Http\Middleware\checkLang::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
];
}
This diff is collapsed.
<?php
namespace App\Http\Middleware;
use Illuminate\Cookie\Middleware\EncryptCookies as BaseEncrypter;
class EncryptCookies extends BaseEncrypter
{
/**
* The names of the cookies that should not be encrypted.
*
* @var array
*/
protected $except = [
//
];
}
This diff is collapsed.
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
* The URIs that should be excluded from CSRF verification.
*
* @var array
*/
protected $except = [
'/ajax',
];
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment