├── README.md ├── Scripts ├── WSAudioRecorder.js ├── WSVideoRecorder.js ├── adapter.js ├── audioWorker.js ├── main.js └── videoWorker.js ├── WebSocketServer ├── Debug │ ├── makefile │ ├── objects.mk │ ├── sources.mk │ └── subdir.mk ├── Release │ ├── WebSocketServer │ ├── main.d │ ├── main.o │ ├── makefile │ ├── objects.mk │ ├── sources.mk │ └── subdir.mk └── main.c └── index.html /README.md: -------------------------------------------------------------------------------- 1 | WebSocketWebRTCRecorders 2 | ======================== 3 | 4 | These are modifications of existing recording scripts that allow recording through websockets, not just downloading Blobs 5 | 6 | 7 | WebSocketServer 8 | =============== 9 | 10 | The Server implementation is a simple C program that utilizes [libwebsockets](http://libwebsockets.org/trac/libwebsockets) and [gstreamer](http://gstreamer.com/), specifically version 0.10 to get and play the media sent down from the front end javascript. 11 | 12 | To compile the following are needed: 13 | -gstreamer-0.10 14 | -glib-2.0 15 | -gstreamer-app-0.10 16 | -pthread 17 | -libwebsockets 18 | -------------------------------------------------------------------------------- /Scripts/WSAudioRecorder.js: -------------------------------------------------------------------------------- 1 |  2 | //NOTE, Websockets in workers ONLY WORKS IN CHROME. Script will have to be modified to work in FireFox. 3 | (function (window) { 4 | 5 | var WORKER_PATH = 'audioWorker.js'; 6 | function floatTo16BitPCM(output, offset, input) { 7 | for (var i = 0; i < input.length; i++, offset += 2) { 8 | var s = Math.max(-1, Math.min(1, input[i])); 9 | output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); 10 | } 11 | } 12 | /** 13 | * Most of this code is copied wholesale from https://github.com/mattdiamond/Recorderjs 14 | * This is not Stereo, on the right channel is grabbed but that is enough for me 15 | */ 16 | var WSAudioRecorder = function (source, wsURL, wsProtocol) { 17 | var recording = false; 18 | var worker = new Worker(WORKER_PATH); 19 | worker.postMessage({ 20 | command: 'init', 21 | config: { 22 | uri: wsURL, protocol: wsProtocol 23 | } 24 | }); 25 | var config = {}; 26 | var bufferLen = 4096; 27 | this.context = source.context; 28 | this.node = (this.context.createScriptProcessor || 29 | this.context.createJavaScriptNode).call(this.context, 30 | bufferLen, 2, 2); 31 | this.node.onaudioprocess = function (e) { 32 | if (!recording) return; 33 | var sample = e.inputBuffer.getChannelData(0); 34 | //Moved the float to 16 bit translation down to codebehind 35 | worker.postMessage({ 36 | command: 'record', 37 | samples: sample 38 | }); 39 | } 40 | 41 | this.record = function () { 42 | recording = true; 43 | } 44 | 45 | this.stop = function () { 46 | recording = false; 47 | } 48 | 49 | this.isRecording = function () { 50 | return recording; 51 | } 52 | 53 | source.connect(this.node); 54 | this.node.connect(this.context.destination); //this should not be necessary, but it is 55 | }; 56 | window.WSAudioRecorder = WSAudioRecorder; 57 | })(window); -------------------------------------------------------------------------------- /Scripts/WSVideoRecorder.js: -------------------------------------------------------------------------------- 1 |  2 | var WORKER_PATH = 'videoWorker.js'; 3 | 4 | function dataURItoView(dataURI) { 5 | // convert base64 to raw binary data held in a string 6 | // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this 7 | var byteString = atob(dataURI.split(',')[1]); 8 | 9 | var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 10 | var ab = new ArrayBuffer(byteString.length); 11 | var view = new DataView(ab); 12 | var ia = new Uint8Array(ab); 13 | for (var i = 0; i < byteString.length; i++) { 14 | view.setUint8(i, byteString.charCodeAt(i), true); 15 | } 16 | return view; 17 | } 18 | 19 | /*Some of this code is taken wholesale from WhammyRecorder.js 20 | * However, images are not encoded to webp format in JS and are instead pushed through a webSocket 21 | * for performance improvements. 22 | * Some hipster may read this and think that JavaScript is practically as fast as 23 | * C or C++, well, you are an idiot mister hipster 24 | **/ 25 | function WSVideoRecorder(mediaStream, wsURL, wsProtocol) { 26 | var recording = false; 27 | var previousImage; //so that we do not burden the network or receiver with dupes. 28 | this.isRecording = function () { 29 | return recording 30 | } 31 | var config = {}; 32 | var worker = new Worker(config.workerPath || WORKER_PATH); 33 | worker.postMessage({ 34 | command: 'init', 35 | config: { 36 | uri: wsURL, protocol: wsProtocol 37 | } 38 | }); 39 | this.record = function () { 40 | recording = true; 41 | 42 | if (!this.width) this.width = video.offsetWidth || 320; 43 | if (!this.height) this.height = video.offsetHeight || 240; 44 | 45 | if (!this.video) { 46 | this.video = { 47 | width: this.width, 48 | height: this.height 49 | }; 50 | } 51 | if (!this.canvas) { 52 | this.canvas = { 53 | width: this.width, 54 | height: this.height 55 | }; 56 | } 57 | 58 | canvas.width = this.canvas.width; 59 | canvas.height = this.canvas.height; 60 | 61 | video.width = this.video.width; 62 | video.height = this.video.height; 63 | 64 | startTime = Date.now(); 65 | 66 | (function drawVideoFrame(time) { 67 | lastAnimationFrame = requestAnimationFrame(drawVideoFrame); 68 | if (typeof lastFrameTime === undefined) { 69 | lastFrameTime = time; 70 | } 71 | var toDraw = false; 72 | if (time < 1e12) { //High Res timer 73 | //~10 fpsish...i think...to make it look OK on the backend make sure it is treated as 10. 74 | toDraw = !(time - lastFrameTime < 90); 75 | } else { //integer milliseconds, may need to adjust "algorithm" 76 | toDraw = !(time - lastFrameTime < 90); 77 | } 78 | if (!toDraw) return; 79 | if (recording) { 80 | context.drawImage(video, 0, 0, canvas.width, canvas.height); 81 | //get the image we just drew to the Canvas, quality can be improved above 0.5 if desired 82 | var image = canvas.toDataURL("image/jpeg", 0.5); 83 | if (typeof previousImage === undefined) { 84 | previousImage = image; 85 | worker.postMessage({ 86 | command: 'record', 87 | uri: image 88 | }); 89 | } else if (previousImage !== image) { 90 | previousImage = image; 91 | worker.postMessage({ 92 | command: 'record', 93 | uri: image 94 | }); 95 | } 96 | } 97 | lastFrameTime = time; 98 | })(); 99 | }; 100 | 101 | this.stop = function () { 102 | recording = false; 103 | if (lastAnimationFrame) cancelAnimationFrame(lastAnimationFrame); 104 | endTime = Date.now(); 105 | }; 106 | 107 | var canvas = document.createElement('canvas'); 108 | var context = canvas.getContext('2d'); 109 | 110 | var video = document.createElement('video'); 111 | video.muted = true; 112 | video.volume = 0; 113 | video.autoplay = true; 114 | video.src = URL.createObjectURL(mediaStream); 115 | video.play(); 116 | 117 | var lastAnimationFrame = null; 118 | var startTime, endTime, lastFrameTime; 119 | } -------------------------------------------------------------------------------- /Scripts/adapter.js: -------------------------------------------------------------------------------- 1 | var RTCPeerConnection = null; 2 | var getUserMedia = null; 3 | var attachMediaStream = null; 4 | var reattachMediaStream = null; 5 | var webrtcDetectedBrowser = null; 6 | var webrtcDetectedVersion = null; 7 | window.AudioContext = window.AudioContext || window.webkitAudioContext; 8 | window.URL = window.URL || window.webkitURL; 9 | 10 | function trace(text) { 11 | // This function is used for logging. 12 | if (text[text.length - 1] == '\n') { 13 | text = text.substring(0, text.length - 1); 14 | } 15 | console.log((performance.now() / 1000).toFixed(3) + ": " + text); 16 | } 17 | 18 | if (navigator.mozGetUserMedia) { 19 | console.log("This appears to be Firefox"); 20 | 21 | webrtcDetectedBrowser = "firefox"; 22 | 23 | webrtcDetectedVersion = 24 | parseInt(navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1], 10); 25 | 26 | // The RTCPeerConnection object. 27 | RTCPeerConnection = mozRTCPeerConnection; 28 | 29 | // The RTCSessionDescription object. 30 | RTCSessionDescription = mozRTCSessionDescription; 31 | 32 | // The RTCIceCandidate object. 33 | RTCIceCandidate = mozRTCIceCandidate; 34 | 35 | // Get UserMedia (only difference is the prefix). 36 | // Code from Adam Barth. 37 | getUserMedia = navigator.mozGetUserMedia.bind(navigator); 38 | 39 | // Creates iceServer from the url for FF. 40 | createIceServer = function (url, username, password) { 41 | var iceServer = null; 42 | var url_parts = url.split(':'); 43 | if (url_parts[0].indexOf('stun') === 0) { 44 | // Create iceServer with stun url. 45 | iceServer = { 'url': url }; 46 | } else if (url_parts[0].indexOf('turn') === 0) { 47 | if (webrtcDetectedVersion < 27) { 48 | // Create iceServer with turn url. 49 | // Ignore the transport parameter from TURN url for FF version <=27. 50 | var turn_url_parts = url.split("?"); 51 | // Return null for createIceServer if transport=tcp. 52 | if (turn_url_parts[1].indexOf('transport=udp') === 0) { 53 | iceServer = { 'url': turn_url_parts[0], 54 | 'credential': password, 55 | 'username': username 56 | }; 57 | } 58 | } else { 59 | // FF 27 and above supports transport parameters in TURN url, 60 | // So passing in the full url to create iceServer. 61 | iceServer = { 'url': url, 62 | 'credential': password, 63 | 'username': username 64 | }; 65 | } 66 | } 67 | return iceServer; 68 | }; 69 | 70 | // Attach a media stream to an element. 71 | attachMediaStream = function (element, stream) { 72 | console.log("Attaching media stream"); 73 | element.mozSrcObject = stream; 74 | element.play(); 75 | }; 76 | 77 | reattachMediaStream = function (to, from) { 78 | console.log("Reattaching media stream"); 79 | to.mozSrcObject = from.mozSrcObject; 80 | to.play(); 81 | }; 82 | 83 | // Fake get{Video,Audio}Tracks 84 | if (!MediaStream.prototype.getVideoTracks) { 85 | MediaStream.prototype.getVideoTracks = function () { 86 | return []; 87 | }; 88 | } 89 | 90 | if (!MediaStream.prototype.getAudioTracks) { 91 | MediaStream.prototype.getAudioTracks = function () { 92 | return []; 93 | }; 94 | } 95 | } else if (navigator.webkitGetUserMedia) { 96 | console.log("This appears to be Chrome"); 97 | 98 | webrtcDetectedBrowser = "chrome"; 99 | webrtcDetectedVersion = 100 | parseInt(navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./)[2], 10); 101 | 102 | // Creates iceServer from the url for Chrome. 103 | createIceServer = function (url, username, password) { 104 | var iceServer = null; 105 | var url_parts = url.split(':'); 106 | if (url_parts[0].indexOf('stun') === 0) { 107 | // Create iceServer with stun url. 108 | iceServer = { 'url': url }; 109 | } else if (url_parts[0].indexOf('turn') === 0) { 110 | // Chrome M28 & above uses below TURN format. 111 | iceServer = { 'url': url, 112 | 'credential': password, 113 | 'username': username 114 | }; 115 | } 116 | return iceServer; 117 | }; 118 | 119 | // The RTCPeerConnection object. 120 | RTCPeerConnection = webkitRTCPeerConnection; 121 | 122 | // Get UserMedia (only difference is the prefix). 123 | // Code from Adam Barth. 124 | getUserMedia = navigator.webkitGetUserMedia.bind(navigator); 125 | 126 | // Attach a media stream to an element. 127 | attachMediaStream = function (element, stream) { 128 | if (typeof element.srcObject !== 'undefined') { 129 | element.srcObject = stream; 130 | } else if (typeof element.mozSrcObject !== 'undefined') { 131 | element.mozSrcObject = stream; 132 | } else if (typeof element.src !== 'undefined') { 133 | element.src = URL.createObjectURL(stream); 134 | } else { 135 | console.log('Error attaching stream to element.'); 136 | } 137 | }; 138 | 139 | reattachMediaStream = function (to, from) { 140 | to.src = from.src; 141 | }; 142 | } else { 143 | console.log("Browser does not appear to be WebRTC-capable"); 144 | } -------------------------------------------------------------------------------- /Scripts/audioWorker.js: -------------------------------------------------------------------------------- 1 | var ws; 2 | 3 | this.onmessage = function (e) { 4 | switch (e.data.command) { 5 | case 'init': 6 | init(e.data.config); 7 | break; 8 | case 'record': 9 | record(e.data.samples); 10 | break; 11 | } 12 | }; 13 | 14 | function init(config) { 15 | ws = new WebSocket(config.uri, config.protocol); 16 | } 17 | 18 | function record(samples) { 19 | ws.send(samples); 20 | } -------------------------------------------------------------------------------- /Scripts/main.js: -------------------------------------------------------------------------------- 1 | //holding place until example can be written -------------------------------------------------------------------------------- /Scripts/videoWorker.js: -------------------------------------------------------------------------------- 1 |  2 | var ws; 3 | function dataURItoView(dataURI) { 4 | // convert base64 to raw binary data held in a string 5 | // doesn't handle URLEncoded DataURIs - see SO answer #6850276 for code that does this 6 | var byteString = atob(dataURI.split(',')[1]); 7 | 8 | var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; 9 | var ab = new ArrayBuffer(byteString.length); 10 | var view = new DataView(ab); 11 | var ia = new Uint8Array(ab); 12 | for (var i = 0; i < byteString.length; i++) { 13 | view.setUint8(i, byteString.charCodeAt(i), true); 14 | } 15 | return view; 16 | } 17 | 18 | this.onmessage = function (e) { 19 | switch (e.data.command) { 20 | case 'init': 21 | init(e.data.config); 22 | break; 23 | case 'record': 24 | record(e.data.uri); 25 | break; 26 | } 27 | }; 28 | 29 | function init(config) { 30 | ws = new WebSocket(config.uri, config.protocol); 31 | } 32 | 33 | function record(uri) { 34 | var view = dataURItoView(uri); 35 | ws.send(view); 36 | } -------------------------------------------------------------------------------- /WebSocketServer/Debug/makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | -include ../makefile.init 6 | 7 | RM := rm -rf 8 | 9 | # All of the sources participating in the build are defined here 10 | -include sources.mk 11 | -include subdir.mk 12 | -include objects.mk 13 | 14 | ifneq ($(MAKECMDGOALS),clean) 15 | ifneq ($(strip $(C_DEPS)),) 16 | -include $(C_DEPS) 17 | endif 18 | endif 19 | 20 | -include ../makefile.defs 21 | 22 | # Add inputs and outputs from these tool invocations to the build variables 23 | 24 | # All Target 25 | all: WebSocketServer 26 | 27 | # Tool invocations 28 | WebSocketServer: $(OBJS) $(USER_OBJS) 29 | @echo 'Building target: $@' 30 | @echo 'Invoking: GCC C Linker' 31 | gcc -o "WebSocketServer" $(OBJS) $(USER_OBJS) $(LIBS) -pthread -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lxml2 -lglib-2.0 -lgstapp-0.10 -lgstbase-0.10 -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lxml2 -lglib-2.0 -lgstapp-0.10 -lgstbase-0.10 -lgstreamer-0.10 -lgobject-2.0 -lgmodule-2.0 -lgthread-2.0 -lxml2 -lglib-2.0 32 | @echo 'Finished building target: $@' 33 | @echo ' ' 34 | 35 | # Other Targets 36 | clean: 37 | -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) WebSocketServer 38 | -@echo ' ' 39 | 40 | .PHONY: all clean dependents 41 | .SECONDARY: 42 | 43 | -include ../makefile.targets 44 | -------------------------------------------------------------------------------- /WebSocketServer/Debug/objects.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | USER_OBJS := 6 | 7 | LIBS := -lwebsockets 8 | 9 | -------------------------------------------------------------------------------- /WebSocketServer/Debug/sources.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | O_SRCS := 6 | C_SRCS := 7 | S_UPPER_SRCS := 8 | OBJ_SRCS := 9 | ASM_SRCS := 10 | OBJS := 11 | C_DEPS := 12 | EXECUTABLES := 13 | 14 | # Every subdirectory with source files must be described here 15 | SUBDIRS := \ 16 | . \ 17 | 18 | -------------------------------------------------------------------------------- /WebSocketServer/Debug/subdir.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | # Add inputs and outputs from these tool invocations to the build variables 6 | C_SRCS += \ 7 | ../main.c 8 | 9 | OBJS += \ 10 | ./main.o 11 | 12 | C_DEPS += \ 13 | ./main.d 14 | 15 | 16 | # Each subdirectory must supply rules for building sources it contributes 17 | %.o: ../%.c 18 | @echo 'Building file: $<' 19 | @echo 'Invoking: GCC C Compiler' 20 | gcc -I/usr/include/glib-2.0 -I/usr/include/gstreamer-0.10 -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" `pkg-config gstreamer-0.10 glib-2.0 gstreamer-app-0.10 --cflags` -o "$@" "$<" 21 | @echo 'Finished building: $<' 22 | @echo ' ' 23 | 24 | 25 | -------------------------------------------------------------------------------- /WebSocketServer/Release/WebSocketServer: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benwtrent/WebSocketWebRTCRecorders/33759dbc3de26fec8caffa434625f55313da4bc9/WebSocketServer/Release/WebSocketServer -------------------------------------------------------------------------------- /WebSocketServer/Release/main.d: -------------------------------------------------------------------------------- 1 | main.d: ../main.c /usr/include/gstreamer-0.10/gst/gst.h \ 2 | /usr/include/glib-2.0/glib.h /usr/include/glib-2.0/glib/galloca.h \ 3 | /usr/include/glib-2.0/glib/gtypes.h \ 4 | /usr/lib/i386-linux-gnu/glib-2.0/include/glibconfig.h \ 5 | /usr/include/glib-2.0/glib/gmacros.h \ 6 | /usr/include/glib-2.0/glib/gversionmacros.h \ 7 | /usr/include/glib-2.0/glib/garray.h \ 8 | /usr/include/glib-2.0/glib/gasyncqueue.h \ 9 | /usr/include/glib-2.0/glib/gthread.h \ 10 | /usr/include/glib-2.0/glib/gatomic.h /usr/include/glib-2.0/glib/gerror.h \ 11 | /usr/include/glib-2.0/glib/gquark.h \ 12 | /usr/include/glib-2.0/glib/gbacktrace.h \ 13 | /usr/include/glib-2.0/glib/gbase64.h \ 14 | /usr/include/glib-2.0/glib/gbitlock.h \ 15 | /usr/include/glib-2.0/glib/gbookmarkfile.h \ 16 | /usr/include/glib-2.0/glib/gbytes.h \ 17 | /usr/include/glib-2.0/glib/gcharset.h \ 18 | /usr/include/glib-2.0/glib/gchecksum.h \ 19 | /usr/include/glib-2.0/glib/gconvert.h \ 20 | /usr/include/glib-2.0/glib/gdataset.h /usr/include/glib-2.0/glib/gdate.h \ 21 | /usr/include/glib-2.0/glib/gdatetime.h \ 22 | /usr/include/glib-2.0/glib/gtimezone.h /usr/include/glib-2.0/glib/gdir.h \ 23 | /usr/include/glib-2.0/glib/genviron.h \ 24 | /usr/include/glib-2.0/glib/gfileutils.h \ 25 | /usr/include/glib-2.0/glib/ggettext.h /usr/include/glib-2.0/glib/ghash.h \ 26 | /usr/include/glib-2.0/glib/glist.h /usr/include/glib-2.0/glib/gmem.h \ 27 | /usr/include/glib-2.0/glib/gnode.h /usr/include/glib-2.0/glib/ghmac.h \ 28 | /usr/include/glib-2.0/glib/gchecksum.h \ 29 | /usr/include/glib-2.0/glib/ghook.h \ 30 | /usr/include/glib-2.0/glib/ghostutils.h \ 31 | /usr/include/glib-2.0/glib/giochannel.h \ 32 | /usr/include/glib-2.0/glib/gmain.h /usr/include/glib-2.0/glib/gpoll.h \ 33 | /usr/include/glib-2.0/glib/gslist.h /usr/include/glib-2.0/glib/gstring.h \ 34 | /usr/include/glib-2.0/glib/gunicode.h \ 35 | /usr/include/glib-2.0/glib/gutils.h \ 36 | /usr/include/glib-2.0/glib/gkeyfile.h \ 37 | /usr/include/glib-2.0/glib/gmappedfile.h \ 38 | /usr/include/glib-2.0/glib/gmarkup.h \ 39 | /usr/include/glib-2.0/glib/gmessages.h \ 40 | /usr/include/glib-2.0/glib/goption.h \ 41 | /usr/include/glib-2.0/glib/gpattern.h \ 42 | /usr/include/glib-2.0/glib/gprimes.h /usr/include/glib-2.0/glib/gqsort.h \ 43 | /usr/include/glib-2.0/glib/gqueue.h /usr/include/glib-2.0/glib/grand.h \ 44 | /usr/include/glib-2.0/glib/gregex.h \ 45 | /usr/include/glib-2.0/glib/gscanner.h \ 46 | /usr/include/glib-2.0/glib/gsequence.h \ 47 | /usr/include/glib-2.0/glib/gshell.h /usr/include/glib-2.0/glib/gslice.h \ 48 | /usr/include/glib-2.0/glib/gspawn.h \ 49 | /usr/include/glib-2.0/glib/gstrfuncs.h \ 50 | /usr/include/glib-2.0/glib/gstringchunk.h \ 51 | /usr/include/glib-2.0/glib/gtestutils.h \ 52 | /usr/include/glib-2.0/glib/gthreadpool.h \ 53 | /usr/include/glib-2.0/glib/gtimer.h \ 54 | /usr/include/glib-2.0/glib/gtrashstack.h \ 55 | /usr/include/glib-2.0/glib/gtree.h \ 56 | /usr/include/glib-2.0/glib/gurifuncs.h \ 57 | /usr/include/glib-2.0/glib/gvarianttype.h \ 58 | /usr/include/glib-2.0/glib/gvariant.h \ 59 | /usr/include/glib-2.0/glib/gversion.h \ 60 | /usr/include/glib-2.0/glib/deprecated/gallocator.h \ 61 | /usr/include/glib-2.0/glib/deprecated/gcache.h \ 62 | /usr/include/glib-2.0/glib/deprecated/gcompletion.h \ 63 | /usr/include/glib-2.0/glib/deprecated/gmain.h \ 64 | /usr/include/glib-2.0/glib/deprecated/grel.h \ 65 | /usr/include/glib-2.0/glib/deprecated/gthread.h \ 66 | /usr/include/gstreamer-0.10/gst/glib-compat.h \ 67 | /usr/include/gstreamer-0.10/gst/gstenumtypes.h \ 68 | /usr/include/glib-2.0/glib-object.h \ 69 | /usr/include/glib-2.0/gobject/gbinding.h \ 70 | /usr/include/glib-2.0/gobject/gobject.h \ 71 | /usr/include/glib-2.0/gobject/gtype.h \ 72 | /usr/include/glib-2.0/gobject/gvalue.h \ 73 | /usr/include/glib-2.0/gobject/gparam.h \ 74 | /usr/include/glib-2.0/gobject/gclosure.h \ 75 | /usr/include/glib-2.0/gobject/gsignal.h \ 76 | /usr/include/glib-2.0/gobject/gmarshal.h \ 77 | /usr/include/glib-2.0/gobject/gboxed.h \ 78 | /usr/include/glib-2.0/gobject/glib-types.h \ 79 | /usr/include/glib-2.0/gobject/genums.h \ 80 | /usr/include/glib-2.0/gobject/gparamspecs.h \ 81 | /usr/include/glib-2.0/gobject/gsourceclosure.h \ 82 | /usr/include/glib-2.0/gobject/gtypemodule.h \ 83 | /usr/include/glib-2.0/gobject/gtypeplugin.h \ 84 | /usr/include/glib-2.0/gobject/gvaluearray.h \ 85 | /usr/include/glib-2.0/gobject/gvaluetypes.h \ 86 | /usr/include/gstreamer-0.10/gst/gstversion.h \ 87 | /usr/include/gstreamer-0.10/gst/gstatomicqueue.h \ 88 | /usr/include/gstreamer-0.10/gst/gstbin.h \ 89 | /usr/include/gstreamer-0.10/gst/gstelement.h \ 90 | /usr/include/gstreamer-0.10/gst/gstconfig.h \ 91 | /usr/include/libxml2/libxml/parser.h \ 92 | /usr/include/libxml2/libxml/xmlversion.h \ 93 | /usr/include/libxml2/libxml/xmlexports.h \ 94 | /usr/include/libxml2/libxml/tree.h \ 95 | /usr/include/libxml2/libxml/xmlstring.h \ 96 | /usr/include/libxml2/libxml/xmlregexp.h \ 97 | /usr/include/libxml2/libxml/dict.h /usr/include/libxml2/libxml/hash.h \ 98 | /usr/include/libxml2/libxml/valid.h \ 99 | /usr/include/libxml2/libxml/xmlerror.h \ 100 | /usr/include/libxml2/libxml/list.h \ 101 | /usr/include/libxml2/libxml/xmlautomata.h \ 102 | /usr/include/libxml2/libxml/entities.h \ 103 | /usr/include/libxml2/libxml/encoding.h \ 104 | /usr/include/libxml2/libxml/xmlIO.h \ 105 | /usr/include/libxml2/libxml/globals.h /usr/include/libxml2/libxml/SAX.h \ 106 | /usr/include/libxml2/libxml/xlink.h /usr/include/libxml2/libxml/SAX2.h \ 107 | /usr/include/libxml2/libxml/xmlmemory.h \ 108 | /usr/include/libxml2/libxml/threads.h \ 109 | /usr/include/gstreamer-0.10/gst/gstobject.h \ 110 | /usr/include/gstreamer-0.10/gst/gstpad.h \ 111 | /usr/include/gstreamer-0.10/gst/gstbuffer.h \ 112 | /usr/include/gstreamer-0.10/gst/gstminiobject.h \ 113 | /usr/include/gstreamer-0.10/gst/gstclock.h \ 114 | /usr/include/gstreamer-0.10/gst/gstcaps.h \ 115 | /usr/include/gstreamer-0.10/gst/gststructure.h \ 116 | /usr/include/gstreamer-0.10/gst/gstdatetime.h \ 117 | /usr/include/gstreamer-0.10/gst/gstbufferlist.h \ 118 | /usr/include/gstreamer-0.10/gst/gstevent.h \ 119 | /usr/include/gstreamer-0.10/gst/gstformat.h \ 120 | /usr/include/gstreamer-0.10/gst/gstiterator.h \ 121 | /usr/include/gstreamer-0.10/gst/gsttaglist.h \ 122 | /usr/include/gstreamer-0.10/gst/gstquery.h \ 123 | /usr/include/gstreamer-0.10/gst/gsttask.h \ 124 | /usr/include/gstreamer-0.10/gst/gsttaskpool.h \ 125 | /usr/include/gstreamer-0.10/gst/gstpadtemplate.h \ 126 | /usr/include/gstreamer-0.10/gst/gstbus.h \ 127 | /usr/include/gstreamer-0.10/gst/gstmessage.h \ 128 | /usr/include/gstreamer-0.10/gst/gstelementfactory.h \ 129 | /usr/include/gstreamer-0.10/gst/gstplugin.h \ 130 | /usr/include/glib-2.0/gmodule.h \ 131 | /usr/include/gstreamer-0.10/gst/gstmacros.h \ 132 | /usr/include/gstreamer-0.10/gst/gstpluginfeature.h \ 133 | /usr/include/gstreamer-0.10/gst/gstindex.h \ 134 | /usr/include/gstreamer-0.10/gst/gstindexfactory.h \ 135 | /usr/include/gstreamer-0.10/gst/gstchildproxy.h \ 136 | /usr/include/gstreamer-0.10/gst/gstdebugutils.h \ 137 | /usr/include/gstreamer-0.10/gst/gsterror.h \ 138 | /usr/include/gstreamer-0.10/gst/gstghostpad.h \ 139 | /usr/include/gstreamer-0.10/gst/gstinfo.h \ 140 | /usr/include/gstreamer-0.10/gst/gstinterface.h \ 141 | /usr/include/gstreamer-0.10/gst/gstmarshal.h \ 142 | /usr/include/gstreamer-0.10/gst/gstparamspecs.h \ 143 | /usr/include/gstreamer-0.10/gst/gstvalue.h \ 144 | /usr/include/gstreamer-0.10/gst/gstpipeline.h \ 145 | /usr/include/gstreamer-0.10/gst/gstpoll.h \ 146 | /usr/include/gstreamer-0.10/gst/gstpreset.h \ 147 | /usr/include/gstreamer-0.10/gst/gstregistry.h \ 148 | /usr/include/gstreamer-0.10/gst/gstsegment.h \ 149 | /usr/include/gstreamer-0.10/gst/gstsystemclock.h \ 150 | /usr/include/gstreamer-0.10/gst/gsttagsetter.h \ 151 | /usr/include/gstreamer-0.10/gst/gsttrace.h \ 152 | /usr/include/gstreamer-0.10/gst/gsttypefind.h \ 153 | /usr/include/gstreamer-0.10/gst/gsttypefindfactory.h \ 154 | /usr/include/gstreamer-0.10/gst/gsturi.h \ 155 | /usr/include/gstreamer-0.10/gst/gstutils.h \ 156 | /usr/include/gstreamer-0.10/gst/gstparse.h \ 157 | /usr/include/gstreamer-0.10/gst/gstxml.h \ 158 | /usr/include/gstreamer-0.10/gst/gstcompat.h \ 159 | /usr/include/gstreamer-0.10/gst/app/gstappbuffer.h \ 160 | /usr/include/gstreamer-0.10/gst/app/gstappsrc.h \ 161 | /usr/include/gstreamer-0.10/gst/base/gstpushsrc.h \ 162 | /usr/include/gstreamer-0.10/gst/base/gstbasesrc.h 163 | 164 | /usr/include/gstreamer-0.10/gst/gst.h: 165 | 166 | /usr/include/glib-2.0/glib.h: 167 | 168 | /usr/include/glib-2.0/glib/galloca.h: 169 | 170 | /usr/include/glib-2.0/glib/gtypes.h: 171 | 172 | /usr/lib/i386-linux-gnu/glib-2.0/include/glibconfig.h: 173 | 174 | /usr/include/glib-2.0/glib/gmacros.h: 175 | 176 | /usr/include/glib-2.0/glib/gversionmacros.h: 177 | 178 | /usr/include/glib-2.0/glib/garray.h: 179 | 180 | /usr/include/glib-2.0/glib/gasyncqueue.h: 181 | 182 | /usr/include/glib-2.0/glib/gthread.h: 183 | 184 | /usr/include/glib-2.0/glib/gatomic.h: 185 | 186 | /usr/include/glib-2.0/glib/gerror.h: 187 | 188 | /usr/include/glib-2.0/glib/gquark.h: 189 | 190 | /usr/include/glib-2.0/glib/gbacktrace.h: 191 | 192 | /usr/include/glib-2.0/glib/gbase64.h: 193 | 194 | /usr/include/glib-2.0/glib/gbitlock.h: 195 | 196 | /usr/include/glib-2.0/glib/gbookmarkfile.h: 197 | 198 | /usr/include/glib-2.0/glib/gbytes.h: 199 | 200 | /usr/include/glib-2.0/glib/gcharset.h: 201 | 202 | /usr/include/glib-2.0/glib/gchecksum.h: 203 | 204 | /usr/include/glib-2.0/glib/gconvert.h: 205 | 206 | /usr/include/glib-2.0/glib/gdataset.h: 207 | 208 | /usr/include/glib-2.0/glib/gdate.h: 209 | 210 | /usr/include/glib-2.0/glib/gdatetime.h: 211 | 212 | /usr/include/glib-2.0/glib/gtimezone.h: 213 | 214 | /usr/include/glib-2.0/glib/gdir.h: 215 | 216 | /usr/include/glib-2.0/glib/genviron.h: 217 | 218 | /usr/include/glib-2.0/glib/gfileutils.h: 219 | 220 | /usr/include/glib-2.0/glib/ggettext.h: 221 | 222 | /usr/include/glib-2.0/glib/ghash.h: 223 | 224 | /usr/include/glib-2.0/glib/glist.h: 225 | 226 | /usr/include/glib-2.0/glib/gmem.h: 227 | 228 | /usr/include/glib-2.0/glib/gnode.h: 229 | 230 | /usr/include/glib-2.0/glib/ghmac.h: 231 | 232 | /usr/include/glib-2.0/glib/gchecksum.h: 233 | 234 | /usr/include/glib-2.0/glib/ghook.h: 235 | 236 | /usr/include/glib-2.0/glib/ghostutils.h: 237 | 238 | /usr/include/glib-2.0/glib/giochannel.h: 239 | 240 | /usr/include/glib-2.0/glib/gmain.h: 241 | 242 | /usr/include/glib-2.0/glib/gpoll.h: 243 | 244 | /usr/include/glib-2.0/glib/gslist.h: 245 | 246 | /usr/include/glib-2.0/glib/gstring.h: 247 | 248 | /usr/include/glib-2.0/glib/gunicode.h: 249 | 250 | /usr/include/glib-2.0/glib/gutils.h: 251 | 252 | /usr/include/glib-2.0/glib/gkeyfile.h: 253 | 254 | /usr/include/glib-2.0/glib/gmappedfile.h: 255 | 256 | /usr/include/glib-2.0/glib/gmarkup.h: 257 | 258 | /usr/include/glib-2.0/glib/gmessages.h: 259 | 260 | /usr/include/glib-2.0/glib/goption.h: 261 | 262 | /usr/include/glib-2.0/glib/gpattern.h: 263 | 264 | /usr/include/glib-2.0/glib/gprimes.h: 265 | 266 | /usr/include/glib-2.0/glib/gqsort.h: 267 | 268 | /usr/include/glib-2.0/glib/gqueue.h: 269 | 270 | /usr/include/glib-2.0/glib/grand.h: 271 | 272 | /usr/include/glib-2.0/glib/gregex.h: 273 | 274 | /usr/include/glib-2.0/glib/gscanner.h: 275 | 276 | /usr/include/glib-2.0/glib/gsequence.h: 277 | 278 | /usr/include/glib-2.0/glib/gshell.h: 279 | 280 | /usr/include/glib-2.0/glib/gslice.h: 281 | 282 | /usr/include/glib-2.0/glib/gspawn.h: 283 | 284 | /usr/include/glib-2.0/glib/gstrfuncs.h: 285 | 286 | /usr/include/glib-2.0/glib/gstringchunk.h: 287 | 288 | /usr/include/glib-2.0/glib/gtestutils.h: 289 | 290 | /usr/include/glib-2.0/glib/gthreadpool.h: 291 | 292 | /usr/include/glib-2.0/glib/gtimer.h: 293 | 294 | /usr/include/glib-2.0/glib/gtrashstack.h: 295 | 296 | /usr/include/glib-2.0/glib/gtree.h: 297 | 298 | /usr/include/glib-2.0/glib/gurifuncs.h: 299 | 300 | /usr/include/glib-2.0/glib/gvarianttype.h: 301 | 302 | /usr/include/glib-2.0/glib/gvariant.h: 303 | 304 | /usr/include/glib-2.0/glib/gversion.h: 305 | 306 | /usr/include/glib-2.0/glib/deprecated/gallocator.h: 307 | 308 | /usr/include/glib-2.0/glib/deprecated/gcache.h: 309 | 310 | /usr/include/glib-2.0/glib/deprecated/gcompletion.h: 311 | 312 | /usr/include/glib-2.0/glib/deprecated/gmain.h: 313 | 314 | /usr/include/glib-2.0/glib/deprecated/grel.h: 315 | 316 | /usr/include/glib-2.0/glib/deprecated/gthread.h: 317 | 318 | /usr/include/gstreamer-0.10/gst/glib-compat.h: 319 | 320 | /usr/include/gstreamer-0.10/gst/gstenumtypes.h: 321 | 322 | /usr/include/glib-2.0/glib-object.h: 323 | 324 | /usr/include/glib-2.0/gobject/gbinding.h: 325 | 326 | /usr/include/glib-2.0/gobject/gobject.h: 327 | 328 | /usr/include/glib-2.0/gobject/gtype.h: 329 | 330 | /usr/include/glib-2.0/gobject/gvalue.h: 331 | 332 | /usr/include/glib-2.0/gobject/gparam.h: 333 | 334 | /usr/include/glib-2.0/gobject/gclosure.h: 335 | 336 | /usr/include/glib-2.0/gobject/gsignal.h: 337 | 338 | /usr/include/glib-2.0/gobject/gmarshal.h: 339 | 340 | /usr/include/glib-2.0/gobject/gboxed.h: 341 | 342 | /usr/include/glib-2.0/gobject/glib-types.h: 343 | 344 | /usr/include/glib-2.0/gobject/genums.h: 345 | 346 | /usr/include/glib-2.0/gobject/gparamspecs.h: 347 | 348 | /usr/include/glib-2.0/gobject/gsourceclosure.h: 349 | 350 | /usr/include/glib-2.0/gobject/gtypemodule.h: 351 | 352 | /usr/include/glib-2.0/gobject/gtypeplugin.h: 353 | 354 | /usr/include/glib-2.0/gobject/gvaluearray.h: 355 | 356 | /usr/include/glib-2.0/gobject/gvaluetypes.h: 357 | 358 | /usr/include/gstreamer-0.10/gst/gstversion.h: 359 | 360 | /usr/include/gstreamer-0.10/gst/gstatomicqueue.h: 361 | 362 | /usr/include/gstreamer-0.10/gst/gstbin.h: 363 | 364 | /usr/include/gstreamer-0.10/gst/gstelement.h: 365 | 366 | /usr/include/gstreamer-0.10/gst/gstconfig.h: 367 | 368 | /usr/include/libxml2/libxml/parser.h: 369 | 370 | /usr/include/libxml2/libxml/xmlversion.h: 371 | 372 | /usr/include/libxml2/libxml/xmlexports.h: 373 | 374 | /usr/include/libxml2/libxml/tree.h: 375 | 376 | /usr/include/libxml2/libxml/xmlstring.h: 377 | 378 | /usr/include/libxml2/libxml/xmlregexp.h: 379 | 380 | /usr/include/libxml2/libxml/dict.h: 381 | 382 | /usr/include/libxml2/libxml/hash.h: 383 | 384 | /usr/include/libxml2/libxml/valid.h: 385 | 386 | /usr/include/libxml2/libxml/xmlerror.h: 387 | 388 | /usr/include/libxml2/libxml/list.h: 389 | 390 | /usr/include/libxml2/libxml/xmlautomata.h: 391 | 392 | /usr/include/libxml2/libxml/entities.h: 393 | 394 | /usr/include/libxml2/libxml/encoding.h: 395 | 396 | /usr/include/libxml2/libxml/xmlIO.h: 397 | 398 | /usr/include/libxml2/libxml/globals.h: 399 | 400 | /usr/include/libxml2/libxml/SAX.h: 401 | 402 | /usr/include/libxml2/libxml/xlink.h: 403 | 404 | /usr/include/libxml2/libxml/SAX2.h: 405 | 406 | /usr/include/libxml2/libxml/xmlmemory.h: 407 | 408 | /usr/include/libxml2/libxml/threads.h: 409 | 410 | /usr/include/gstreamer-0.10/gst/gstobject.h: 411 | 412 | /usr/include/gstreamer-0.10/gst/gstpad.h: 413 | 414 | /usr/include/gstreamer-0.10/gst/gstbuffer.h: 415 | 416 | /usr/include/gstreamer-0.10/gst/gstminiobject.h: 417 | 418 | /usr/include/gstreamer-0.10/gst/gstclock.h: 419 | 420 | /usr/include/gstreamer-0.10/gst/gstcaps.h: 421 | 422 | /usr/include/gstreamer-0.10/gst/gststructure.h: 423 | 424 | /usr/include/gstreamer-0.10/gst/gstdatetime.h: 425 | 426 | /usr/include/gstreamer-0.10/gst/gstbufferlist.h: 427 | 428 | /usr/include/gstreamer-0.10/gst/gstevent.h: 429 | 430 | /usr/include/gstreamer-0.10/gst/gstformat.h: 431 | 432 | /usr/include/gstreamer-0.10/gst/gstiterator.h: 433 | 434 | /usr/include/gstreamer-0.10/gst/gsttaglist.h: 435 | 436 | /usr/include/gstreamer-0.10/gst/gstquery.h: 437 | 438 | /usr/include/gstreamer-0.10/gst/gsttask.h: 439 | 440 | /usr/include/gstreamer-0.10/gst/gsttaskpool.h: 441 | 442 | /usr/include/gstreamer-0.10/gst/gstpadtemplate.h: 443 | 444 | /usr/include/gstreamer-0.10/gst/gstbus.h: 445 | 446 | /usr/include/gstreamer-0.10/gst/gstmessage.h: 447 | 448 | /usr/include/gstreamer-0.10/gst/gstelementfactory.h: 449 | 450 | /usr/include/gstreamer-0.10/gst/gstplugin.h: 451 | 452 | /usr/include/glib-2.0/gmodule.h: 453 | 454 | /usr/include/gstreamer-0.10/gst/gstmacros.h: 455 | 456 | /usr/include/gstreamer-0.10/gst/gstpluginfeature.h: 457 | 458 | /usr/include/gstreamer-0.10/gst/gstindex.h: 459 | 460 | /usr/include/gstreamer-0.10/gst/gstindexfactory.h: 461 | 462 | /usr/include/gstreamer-0.10/gst/gstchildproxy.h: 463 | 464 | /usr/include/gstreamer-0.10/gst/gstdebugutils.h: 465 | 466 | /usr/include/gstreamer-0.10/gst/gsterror.h: 467 | 468 | /usr/include/gstreamer-0.10/gst/gstghostpad.h: 469 | 470 | /usr/include/gstreamer-0.10/gst/gstinfo.h: 471 | 472 | /usr/include/gstreamer-0.10/gst/gstinterface.h: 473 | 474 | /usr/include/gstreamer-0.10/gst/gstmarshal.h: 475 | 476 | /usr/include/gstreamer-0.10/gst/gstparamspecs.h: 477 | 478 | /usr/include/gstreamer-0.10/gst/gstvalue.h: 479 | 480 | /usr/include/gstreamer-0.10/gst/gstpipeline.h: 481 | 482 | /usr/include/gstreamer-0.10/gst/gstpoll.h: 483 | 484 | /usr/include/gstreamer-0.10/gst/gstpreset.h: 485 | 486 | /usr/include/gstreamer-0.10/gst/gstregistry.h: 487 | 488 | /usr/include/gstreamer-0.10/gst/gstsegment.h: 489 | 490 | /usr/include/gstreamer-0.10/gst/gstsystemclock.h: 491 | 492 | /usr/include/gstreamer-0.10/gst/gsttagsetter.h: 493 | 494 | /usr/include/gstreamer-0.10/gst/gsttrace.h: 495 | 496 | /usr/include/gstreamer-0.10/gst/gsttypefind.h: 497 | 498 | /usr/include/gstreamer-0.10/gst/gsttypefindfactory.h: 499 | 500 | /usr/include/gstreamer-0.10/gst/gsturi.h: 501 | 502 | /usr/include/gstreamer-0.10/gst/gstutils.h: 503 | 504 | /usr/include/gstreamer-0.10/gst/gstparse.h: 505 | 506 | /usr/include/gstreamer-0.10/gst/gstxml.h: 507 | 508 | /usr/include/gstreamer-0.10/gst/gstcompat.h: 509 | 510 | /usr/include/gstreamer-0.10/gst/app/gstappbuffer.h: 511 | 512 | /usr/include/gstreamer-0.10/gst/app/gstappsrc.h: 513 | 514 | /usr/include/gstreamer-0.10/gst/base/gstpushsrc.h: 515 | 516 | /usr/include/gstreamer-0.10/gst/base/gstbasesrc.h: 517 | -------------------------------------------------------------------------------- /WebSocketServer/Release/main.o: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benwtrent/WebSocketWebRTCRecorders/33759dbc3de26fec8caffa434625f55313da4bc9/WebSocketServer/Release/main.o -------------------------------------------------------------------------------- /WebSocketServer/Release/makefile: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | -include ../makefile.init 6 | 7 | RM := rm -rf 8 | 9 | # All of the sources participating in the build are defined here 10 | -include sources.mk 11 | -include subdir.mk 12 | -include objects.mk 13 | 14 | ifneq ($(MAKECMDGOALS),clean) 15 | ifneq ($(strip $(C_DEPS)),) 16 | -include $(C_DEPS) 17 | endif 18 | endif 19 | 20 | -include ../makefile.defs 21 | 22 | # Add inputs and outputs from these tool invocations to the build variables 23 | 24 | # All Target 25 | all: WebSocketServer 26 | 27 | # Tool invocations 28 | WebSocketServer: $(OBJS) $(USER_OBJS) 29 | @echo 'Building target: $@' 30 | @echo 'Invoking: GCC C Linker' 31 | gcc -o "WebSocketServer" $(OBJS) $(USER_OBJS) $(LIBS) -pthread `pkg-config gstreamer-0.10 gstreamer-app-0.10 --libs` 32 | @echo 'Finished building target: $@' 33 | @echo ' ' 34 | 35 | # Other Targets 36 | clean: 37 | -$(RM) $(OBJS)$(C_DEPS)$(EXECUTABLES) WebSocketServer 38 | -@echo ' ' 39 | 40 | .PHONY: all clean dependents 41 | .SECONDARY: 42 | 43 | -include ../makefile.targets 44 | -------------------------------------------------------------------------------- /WebSocketServer/Release/objects.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | USER_OBJS := 6 | 7 | LIBS := -lwebsockets 8 | 9 | -------------------------------------------------------------------------------- /WebSocketServer/Release/sources.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | O_SRCS := 6 | C_SRCS := 7 | S_UPPER_SRCS := 8 | OBJ_SRCS := 9 | ASM_SRCS := 10 | OBJS := 11 | C_DEPS := 12 | EXECUTABLES := 13 | 14 | # Every subdirectory with source files must be described here 15 | SUBDIRS := \ 16 | . \ 17 | 18 | -------------------------------------------------------------------------------- /WebSocketServer/Release/subdir.mk: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Automatically-generated file. Do not edit! 3 | ################################################################################ 4 | 5 | # Add inputs and outputs from these tool invocations to the build variables 6 | C_SRCS += \ 7 | ../main.c 8 | 9 | OBJS += \ 10 | ./main.o 11 | 12 | C_DEPS += \ 13 | ./main.d 14 | 15 | 16 | # Each subdirectory must supply rules for building sources it contributes 17 | %.o: ../%.c 18 | @echo 'Building file: $<' 19 | @echo 'Invoking: GCC C Compiler' 20 | gcc -I/usr/include/glib-2.0 -I/usr/include/gstreamer-0.10 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"$(@:%.o=%.d)" -MT"$(@:%.o=%.d)" `pkg-config gstreamer-0.10 glib-2.0 gstreamer-app-0.10 --cflags` -o "$@" "$<" 21 | @echo 'Finished building: $<' 22 | @echo ' ' 23 | 24 | 25 | -------------------------------------------------------------------------------- /WebSocketServer/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Quick and easy websocket server for a backend for Javascript websocket scripts. 3 | * This is NOT optimal and NOT production code, only utilize this as an example 4 | * There is NO error checking. 5 | * 6 | * Created on: Mar 28, 2014 7 | * Author: ben.w.trent@gmail.com 8 | * 9 | * The MIT License (MIT) 10 | * 11 | * Copyright (c) 12 | * 13 | * Permission is hereby granted, free of charge, to any person obtaining a copy 14 | * of this software and associated documentation files (the "Software"), to deal 15 | * in the Software without restriction, including without limitation the rights 16 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | * copies of the Software, and to permit persons to whom the Software is 18 | * furnished to do so, subject to the following conditions: 19 | 20 | * The above copyright notice and this permission notice shall be included in 21 | * all copies or substantial portions of the Software. 22 | 23 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | * THE SOFTWARE. 30 | */ 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | static int callback_http1(struct libwebsocket_context * this, 40 | struct libwebsocket *wsi, 41 | enum libwebsocket_callback_reasons reason, void *user, 42 | void *in, size_t len) 43 | { 44 | return 0; 45 | } 46 | 47 | static int callback_http2(struct libwebsocket_context * this, 48 | struct libwebsocket *wsi, 49 | enum libwebsocket_callback_reasons reason, void *user, 50 | void *in, size_t len) 51 | { 52 | return 0; 53 | } 54 | 55 | static int callback_video(struct libwebsocket_context * this, 56 | struct libwebsocket *wsi, 57 | enum libwebsocket_callback_reasons reason, 58 | void *user, void *in, size_t len) { 59 | switch(reason) { 60 | case LWS_CALLBACK_ESTABLISHED: 61 | printf("video stream WS connected\n"); 62 | break; 63 | case LWS_CALLBACK_RECEIVE: { 64 | guchar* temp = NULL; 65 | temp = (guchar*)malloc(len); 66 | memcpy(temp, in, len); 67 | GstElement* stream = (GstElement*)libwebsocket_context_user(this); 68 | GstElement* appsrc = gst_bin_get_by_name(GST_BIN(stream), "AppSrc"); 69 | GstBuffer* buffer = gst_app_buffer_new(temp, len, (GstAppBufferFinalizeFunc)g_free, temp); 70 | gst_app_src_push_buffer(GST_APP_SRC(appsrc), buffer); 71 | break; 72 | } 73 | default: 74 | break; 75 | } 76 | return 0; 77 | } 78 | 79 | static int callback_audio(struct libwebsocket_context * this, 80 | struct libwebsocket *wsi, 81 | enum libwebsocket_callback_reasons reason, 82 | void *user, void *in, size_t len) 83 | { 84 | switch (reason) { 85 | case LWS_CALLBACK_ESTABLISHED: // just log message that someone is connecting 86 | printf("audio stream WS connected\n"); 87 | break; 88 | case LWS_CALLBACK_RECEIVE: { 89 | gfloat* temp = NULL; 90 | temp = (gfloat*)g_malloc(len); 91 | memcpy(temp, in, len); 92 | GstElement* stream = (GstElement*)libwebsocket_context_user(this); 93 | GstElement* appsrc = gst_bin_get_by_name(GST_BIN(stream), "AppSrc"); 94 | GstBuffer* buffer = gst_app_buffer_new(temp, len, (GstAppBufferFinalizeFunc)g_free, temp); 95 | GstFlowReturn ret = gst_app_src_push_buffer(GST_APP_SRC(appsrc), buffer); 96 | break; 97 | } 98 | default: 99 | break; 100 | } 101 | 102 | return 0; 103 | } 104 | 105 | static struct libwebsocket_protocols protocolsAudio[] = { 106 | /* first protocol must always be HTTP handler */ 107 | { 108 | "http-only", 109 | callback_http1, 110 | 0 111 | }, 112 | { 113 | "audio-protocol", 114 | callback_audio, 115 | 0 116 | }, 117 | { 118 | NULL, NULL, 0 /* End of list */ 119 | } 120 | }; 121 | 122 | static struct libwebsocket_protocols protocolsLocalVideo[] = { 123 | /* first protocol must always be HTTP handler */ 124 | { 125 | "http-only", // name 126 | callback_http2, // callback 127 | 0 // per_session_data_size 128 | }, 129 | { 130 | "video-protocol", 131 | callback_video, 132 | 0 133 | }, 134 | { 135 | NULL, NULL, 0 /* End of list */ 136 | } 137 | }; 138 | 139 | void* AudioWebSocketLoop(void *context) 140 | { 141 | while(1) 142 | { 143 | libwebsocket_service((struct libwebsocket_context *)context, 40); 144 | } 145 | } 146 | 147 | void* VideoWebSocketLoop(void *context) 148 | { 149 | while(1) 150 | { 151 | libwebsocket_service((struct libwebsocket_context *)context, 50); 152 | } 153 | } 154 | 155 | int main(void) { 156 | // server url will be ws://:9000 for audio, 9002 for video 157 | struct libwebsocket_context *Audiocontext; 158 | struct libwebsocket_context *Videocontext; 159 | 160 | 161 | gst_init(NULL, NULL); 162 | pthread_t Audiothread, Videothread; 163 | GstElement* audiopipeline; 164 | GstElement* videopipeline; 165 | GMainLoop* loop; 166 | struct lws_context_creation_info Audioinfo, Videoinfo; 167 | GError* error=NULL; 168 | 169 | //change multiudpclient destinations to send the jpeg stream or the raw float stream. 170 | gchar* audiopipelinestr = g_strdup_printf ("appsrc is-live=true do-timestamp=true name=AppSrc ! audio/x-raw-float, channels=1, rate=44100, endianness=1234, width=32 ! audioconvert ! audio/x-raw-int, depth=16, width=16, rate=44100, channels=1, signed=true, endianness=1234 ! queue ! level ! multiudpsink clients=127.0.0.1:7000 sync=false async=false"); 171 | gchar* videostr = g_strdup_printf("appsrc is-live=true do-timestamp=true name=AppSrc ! image/jpeg, height=240, width=320, framerate=10/1 ! multipartmux ! multiudpsink clients=127.0.0.1:7002 sync=false async=false"); 172 | 173 | /** 174 | * Example client pipelines 175 | * udpsrc port=7000 caps="audio/x-raw-int, depth=16, width=16, endianness=1234, channels=1, signed=true, rate=44100 ! autoaudiosink sync=false async=false 176 | * udpsrc port=7002 caps="image/jpeg, height=240, width=360, framerate=10/1" ! jpegparse ! jpegdec ! ffmpegcolorspace ! autovideosink sync=false async=false 177 | */ 178 | 179 | audiopipeline = gst_parse_launch(audiopipelinestr, &error); 180 | videopipeline = gst_parse_launch(videostr, &error); 181 | 182 | loop = g_main_loop_new(NULL, FALSE); 183 | memset(&Audioinfo, 0, sizeof Audioinfo); 184 | memset(&Videoinfo, 0, sizeof Videoinfo); 185 | 186 | Audioinfo.port = 9000; 187 | Audioinfo.iface = "lo"; //change to eth0 or external NIC if external access is needed. 188 | Audioinfo.ssl_ca_filepath = NULL; 189 | Audioinfo.ssl_private_key_filepath = NULL; 190 | Audioinfo.protocols = protocolsAudio; 191 | Audioinfo.options = 0; 192 | Audioinfo.extensions = libwebsocket_get_internal_extensions(); 193 | Audioinfo.gid = -1; 194 | Audioinfo.uid = -1; 195 | Audioinfo.user = (void*)audiopipeline; 196 | 197 | Videoinfo.port = 9002; 198 | Videoinfo.iface = "lo"; //same here as above 199 | Videoinfo.ssl_ca_filepath = NULL; 200 | Videoinfo.ssl_private_key_filepath = NULL; 201 | Videoinfo.protocols = protocolsLocalVideo; 202 | Videoinfo.options = 0; 203 | Videoinfo.extensions = libwebsocket_get_internal_extensions(); 204 | Videoinfo.gid = -1; 205 | Videoinfo.uid = -1; 206 | Videoinfo.user = (void*)videopipeline; 207 | 208 | Audiocontext = libwebsocket_create_context(&Audioinfo); 209 | Videocontext = libwebsocket_create_context(&Videoinfo); 210 | 211 | printf("starting server...\n"); 212 | 213 | gst_element_set_state(audiopipeline, GST_STATE_PLAYING); 214 | gst_element_set_state(videopipeline, GST_STATE_PLAYING); 215 | 216 | pthread_create(&Audiothread, NULL, AudioWebSocketLoop, (void*)Audiocontext); 217 | pthread_create(&Videothread, NULL, VideoWebSocketLoop, (void*)Videocontext); 218 | 219 | pthread_join(Videothread, NULL); 220 | pthread_join(Audiothread, NULL); 221 | g_main_loop_run(loop); 222 | 223 | 224 | libwebsocket_context_destroy(Audiocontext); 225 | libwebsocket_context_destroy(Videocontext); 226 | 227 | return 0; 228 | } 229 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | WebRTC Recorder Example 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 62 | 63 | --------------------------------------------------------------------------------