diff --git a/RecordRTC-Development/RecordRTC.js b/RecordRTC-Development/RecordRTC.js index a4994325..153aa931 100644 --- a/RecordRTC-Development/RecordRTC.js +++ b/RecordRTC-Development/RecordRTC.js @@ -74,11 +74,38 @@ function RecordRTC(mediaStream, config) { function getDataURL(callback, _mediaRecorder) { if (!callback) throw 'Pass a callback function over getDataURL.'; - var reader = new FileReader(); - reader.readAsDataURL(_mediaRecorder ? _mediaRecorder.recordedBlob : mediaRecorder.recordedBlob); - reader.onload = function(event) { - callback(event.target.result); - }; + _getDataURL(); + + function _getDataURL() { + if (!!window.Worker) { + var webWorker = processInWebWorker(function readFile(_blob) { + postMessage(new FileReaderSync().readAsDataURL(_blob)); + }); + + webWorker.onmessage = function(event) { + callback(event.data); + }; + + webWorker.postMessage(_mediaRecorder ? _mediaRecorder.recordedBlob : mediaRecorder.recordedBlob); + } else { + var reader = new FileReader(); + reader.readAsDataURL(_mediaRecorder ? _mediaRecorder.recordedBlob : mediaRecorder.recordedBlob); + reader.onload = function(event) { + callback(event.target.result); + }; + } + } + + function processInWebWorker(_function) { + var blob = URL.createObjectURL(new Blob([_function.toString(), + 'this.onmessage = function (e) {readFile(e.data);}'], { + type: 'application/javascript' + })); + + var worker = new Worker(blob); + URL.revokeObjectURL(blob); + return worker; + } } var WARNING = 'It seems that "startRecording" is not invoked for ' + config.type + ' recorder.'; diff --git a/RecordRTC/PHP-and-FFmpeg/.htaccess b/RecordRTC/PHP-and-FFmpeg/.htaccess new file mode 100644 index 00000000..8b4795cb --- /dev/null +++ b/RecordRTC/PHP-and-FFmpeg/.htaccess @@ -0,0 +1,5 @@ +php_value session.gc_maxlifetime 10800 +php_value max_input_time 10800 +php_value max_execution_time 10800 +php_value upload_max_filesize 500M +php_value post_max_size 500M \ No newline at end of file diff --git a/RecordRTC/PHP-and-FFmpeg/index.html b/RecordRTC/PHP-and-FFmpeg/index.html new file mode 100644 index 00000000..c7b98e83 --- /dev/null +++ b/RecordRTC/PHP-and-FFmpeg/index.html @@ -0,0 +1,173 @@ + + + + + + RecordRTC / PHP / FFmpeg + + + + + + + + + + + + + + +

+ RecordRTC + PHP + FFmpeg +

+
+

+ +

+ + + + +
+
+ + + + diff --git a/RecordRTC/PHP-and-FFmpeg/save.php b/RecordRTC/PHP-and-FFmpeg/save.php new file mode 100644 index 00000000..c8b56c27 --- /dev/null +++ b/RecordRTC/PHP-and-FFmpeg/save.php @@ -0,0 +1,88 @@ + 'Win16', + 'Windows 95' => '(Windows 95)|(Win95)|(Windows_95)', + 'Windows 98' => '(Windows 98)|(Win98)', + 'Windows 2000' => '(Windows NT 5.0)|(Windows 2000)', + 'Windows XP' => '(Windows NT 5.1)|(Windows XP)', + 'Windows Server 2003' => '(Windows NT 5.2)', + 'Windows Vista' => '(Windows NT 6.0)', + 'Windows 7' => '(Windows NT 7.0)', + 'Windows NT 4.0' => '(Windows NT 4.0)|(WinNT4.0)|(WinNT)|(Windows NT)', + 'Windows ME' => 'Windows ME', + 'Open BSD' => 'OpenBSD', + 'Sun OS' => 'SunOS', + 'Linux' => '(Linux)|(X11)', + 'Mac OS' => '(Mac_PowerPC)|(Macintosh)', + 'QNX' => 'QNX', + 'BeOS' => 'BeOS', + 'OS/2' => 'OS/2', + 'Search Bot'=>'(nuhk)|(Googlebot)|(Yammybot)|(Openbot)|(Slurp)|(MSNBot)|(Ask Jeeves/Teoma)|(ia_archiver)' + ); + // Loop through the array of user agents and matching operating systems + foreach($OSList as $CurrOS=>$Match) + { + // Find a match + if (eregi($Match, $_SERVER['HTTP_USER_AGENT'])) + { + // We found the correct match + break; + } + } + + // if it is audio-blob + if (isset($_FILES["audio-blob"])) { + $uploadDirectory = 'uploads/'.$_POST["filename"].'.wav'; + if (!move_uploaded_file($_FILES["audio-blob"]["tmp_name"], $uploadDirectory)) { + echo("Problem writing audio file to disk!"); + } + else { + // if it is video-blob + if (isset($_FILES["video-blob"])) { + $uploadDirectory = 'uploads/'.$_POST["filename"].'.webm'; + if (!move_uploaded_file($_FILES["video-blob"]["tmp_name"], $uploadDirectory)) { + echo("Problem writing video file to disk!"); + } + else { + $audioFile = 'uploads/'.$_POST["filename"].'.wav'; + $videoFile = 'uploads/'.$_POST["filename"].'.webm'; + + $mergedFile = 'uploads/'.$_POST["filename"].'-merged.webm'; + + // ffmpeg depends on yasm + // libvpx depends on libvorbis + // libvorbis depends on libogg + // make sure that you're using newest ffmpeg version! + + if(!strrpos($CurrOS, "Windows")) { + $cmd = '-i '.$audioFile.' -itsoffset -00:00:02 -i '.$videoFile.' -map 0:0 -map 1:0 '.$mergedFile; + } + else { + $cmd = ' -i '.$audioFile.' -itsoffset -00:00:02 -i '.$videoFile.' -c:v mpeg4 -c:a vorbis -b:v 64k -b:a 12k -strict experimental '.$mergedFile; + } + + exec('ffmpeg '.$cmd.' 2>&1', $out, $ret); + if ($ret){ + echo "There was a problem!\n"; + print_r($cmd.'\n'); + print_r($out); + } else { + echo "Ffmpeg successfully merged audi/video files into single WebM container!\n"; + + unlink($audioFile); + unlink($videoFile); + } + } + } + } + } +?> diff --git a/RecordRTC/RecordRTC.js b/RecordRTC/RecordRTC.js index e1fd8dea..780a236e 100644 --- a/RecordRTC/RecordRTC.js +++ b/RecordRTC/RecordRTC.js @@ -1,4 +1,4 @@ -// Last time updated at 27 March 2014, 16:32:23 +// Last time updated at 31 March 2014, 16:32:23 // Muaz Khan - www.MuazKhan.com // MIT License - www.WebRTC-Experiment.com/licence @@ -88,11 +88,38 @@ function RecordRTC(mediaStream, config) { function getDataURL(callback, _mediaRecorder) { if (!callback) throw 'Pass a callback function over getDataURL.'; - var reader = new FileReader(); - reader.readAsDataURL(_mediaRecorder ? _mediaRecorder.recordedBlob : mediaRecorder.recordedBlob); - reader.onload = function(event) { - callback(event.target.result); - }; + _getDataURL(); + + function _getDataURL() { + if (!!window.Worker) { + var webWorker = processInWebWorker(function readFile(_blob) { + postMessage(new FileReaderSync().readAsDataURL(_blob)); + }); + + webWorker.onmessage = function(event) { + callback(event.data); + }; + + webWorker.postMessage(_mediaRecorder ? _mediaRecorder.recordedBlob : mediaRecorder.recordedBlob); + } else { + var reader = new FileReader(); + reader.readAsDataURL(_mediaRecorder ? _mediaRecorder.recordedBlob : mediaRecorder.recordedBlob); + reader.onload = function(event) { + callback(event.target.result); + }; + } + } + + function processInWebWorker(_function) { + var blob = URL.createObjectURL(new Blob([_function.toString(), + 'this.onmessage = function (e) {readFile(e.data);}'], { + type: 'application/javascript' + })); + + var worker = new Worker(blob); + URL.revokeObjectURL(blob); + return worker; + } } var WARNING = 'It seems that "startRecording" is not invoked for ' + config.type + ' recorder.'; @@ -816,6 +843,7 @@ function WhammyRecorder(mediaStream) { // should we provide an option to record via Whammy.js or MediaRecorder API is a better solution? var Whammy = (function() { + function toWebM(frames) { var info = checkFrames(frames);