Search code examples
phpsocketswebrtcmediastreamrecordrtc

Why The Program Writes To Socket Empty?


I am making a program which records video, and sends its blobs to a socket every 5 secs.It seems working properly but when i look at the files received by the server, i see all the programs written by socket client are empty= 0kb.Can you help me please? My HTML/JS and PHP codes are below.

 <!DOCTYPE html>
<html lang="en">

<head>
    <title>WebRTC Video Recording using MediaStreamRecorder</title>

    <script src="https://cdn.WebRTC-Experiment.com/MediaStreamRecorder.js"></script>

    <!-- for Edige/FF/Chrome/Opera/etc. getUserMedia support -->
    <script src="https://cdn.WebRTC-Experiment.com/gumadapter.js"></script>

    <link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
    <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
    <meta name="author" content="Muaz Khan">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    <style>
        input {
            border: 1px solid rgb(46, 189, 235);
            border-radius: 3px;
            font-size: 1em;
            outline: none;
            padding: .2em .4em;
            width: 60px;
            text-align: center;
        }

        select {
            vertical-align: middle;
            line-height: 1;
            padding: 2px 5px;
            height: auto;
            font-size: inherit;
            margin: 0;
        }
    </style>
</head>

<body>
    <article>
        <header style="text-align: center;">
            <h1>
                <a href="https://www.webrtc-experiment.com/">WebRTC</a> Video Recording using <a href="https://github.com/streamproc/MediaStreamRecorder" target="_blank">MediaStreamRecorder</a>
            </h1>
            <p>
                <a href="https://www.webrtc-experiment.com/">HOME</a>
                <span> &copy; </span>
                <a href="https://www.webrtc-experiment.com/">WebRTC Experiment</a> .

            </p>
        </header>



        <section class="experiment" style="padding: 5px;">
            <label for="time-interval">Time Interval (milliseconds):</label>
            <input type="text" id="time-interval" value="5000">

            <br>
            <br> recorderType:

            <select id="video-recorderType" style="font-size:22px;vertical-align: middle;margin-right: 5px;">
                <option value="[Best Available Recorder]">[Best Available Recorder]</option>
                <option value="MediaRecorder API">MediaRecorder API</option>
                <option value="WebP encoding into WebM">WebP encoding into WebM</option>
            </select>

            <br>
            <br>

            <button id="start-recording">Start</button>
            <button id="stop-recording" disabled>Stop</button>

            <button id="pause-recording" disabled>Pause</button>
            <button id="resume-recording" disabled>Resume</button>

            <button id="save-recording" disabled>Save</button>

            <br>
            <br>

            <label for="video-width">Video Width:</label>
            <input type="text" id="video-width" value="320">

            <label for="video-height">Video Height:</label>
            <input type="text" id="video-height" value="240">
        </section>

        <section class="experiment">
            <div id="videos-container">
            </div>
        </section>
        <script>
            function captureUserMedia(mediaConstraints, successCallback, errorCallback) {
                navigator.mediaDevices.getUserMedia(mediaConstraints).then(successCallback).catch(errorCallback);
            }

            var mediaConstraints = {
                audio: !IsOpera && !IsEdge, // record both audio/video in Firefox/Chrome
                video: true
            };

            document.querySelector('#start-recording').onclick = function() {
                this.disabled = true;
                captureUserMedia(mediaConstraints, onMediaSuccess, onMediaError);
            };

            document.querySelector('#stop-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.stop();
                mediaRecorder.stream.stop();

                document.querySelector('#pause-recording').disabled = true;
                document.querySelector('#start-recording').disabled = false;
            };

            document.querySelector('#pause-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.pause();

                document.querySelector('#resume-recording').disabled = false;
            };

            document.querySelector('#resume-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.resume();

                document.querySelector('#pause-recording').disabled = false;
            };

            document.querySelector('#save-recording').onclick = function() {
                this.disabled = true;
                mediaRecorder.save();

                // alert('Drop WebM file on Chrome or Firefox. Both can play entire file. VLC player or other players may not work.');
            };

            var mediaRecorder;

            function onMediaSuccess(stream) {
                var video = document.createElement('video');

                var videoWidth = document.getElementById('video-width').value || 320;
                var videoHeight = document.getElementById('video-height').value || 240;

                video = mergeProps(video, {
                    controls: true,
                    muted: true,
                    width: videoWidth,
                    height: videoHeight,
                    src: URL.createObjectURL(stream)
                });
                video.play();

                videosContainer.appendChild(video);
                videosContainer.appendChild(document.createElement('hr'));

                mediaRecorder = new MediaStreamRecorder(stream);
                mediaRecorder.stream = stream;

                var recorderType = document.getElementById('video-recorderType').value;

                if (recorderType === 'MediaRecorder API') {
                    mediaRecorder.recorderType = MediaRecorderWrapper;
                }

                if (recorderType === 'WebP encoding into WebM') {
                    mediaRecorder.recorderType = WhammyRecorder;
                }

                // don't force any mimeType; use above "recorderType" instead.
                // mediaRecorder.mimeType = 'video/webm'; // video/webm or video/mp4


                mediaRecorder.videoWidth = videoWidth;
                mediaRecorder.videoHeight = videoHeight;
                mediaRecorder.ondataavailable = function(blob) {
                    var a = document.createElement('a');
                    a.target = '_blank';
                    a.innerHTML = 'Open Recorded Video No. ' + (index++) + ' (Size: ' + bytesToSize(blob.size) + ') Time Length: ' + getTimeLength(timeInterval);

                    a.href = URL.createObjectURL(blob);

                    videosContainer.appendChild(a);
                    videosContainer.appendChild(document.createElement('hr'));

                    // EKLENEN

                    var myRequest = new XMLHttpRequest();
                    myRequest.open('POST', 'save.php' , true);
                    myRequest.send(blob);

                };

                var timeInterval = document.querySelector('#time-interval').value;
                if (timeInterval) timeInterval = parseInt(timeInterval);
                else timeInterval = 5 * 1000;

                // get blob after specific time interval
                mediaRecorder.start(timeInterval);

                document.querySelector('#stop-recording').disabled = false;
                document.querySelector('#pause-recording').disabled = false;
                document.querySelector('#save-recording').disabled = false;
            }

            function onMediaError(e) {
                console.error('media error', e);
            }

            var videosContainer = document.getElementById('videos-container');
            var index = 1;


            function bytesToSize(bytes) {
                var k = 1000;
                var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
                if (bytes === 0) return '0 Bytes';
                var i = parseInt(Math.floor(Math.log(bytes) / Math.log(k)), 10);
                return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i];
            }


            function getTimeLength(milliseconds) {
                var data = new Date(milliseconds);
                return data.getUTCHours() + " hours, " + data.getUTCMinutes() + " minutes and " + data.getUTCSeconds() + " second(s)";
            }

            window.onbeforeunload = function() {
                document.querySelector('#start-recording').disabled = false;
            };
        </script>

        <pre style="border-left: 2px solid red; margin-left:2em; padding-left: 1em;">
// cdn.webrtc-experiment.com/MediaStreamRecorder.js

var mediaConstraints = {
    audio: true,
    video: true  // if firefox or chrome
};

navigator.getUserMedia(mediaConstraints, onMediaSuccess, onMediaError);

function onMediaSuccess(stream) {
    var mediaRecorder = new MediaStreamRecorder(stream);
    mediaRecorder.mimeType = 'video/webm';
    mediaRecorder.ondataavailable = function (blob) {
        // POST/PUT "Blob" using FormData/XHR2
        var blobURL = URL.createObjectURL(blob);
        document.write('<a href="' + blobURL + '">' + blobURL + '</a>');
    };
    mediaRecorder.start(3000);
}

function onMediaError(e) {
    console.error('media error', e);
}
</pre>

        <a href="https://www.webrtc-experiment.com/msr/" style="border-bottom: 1px solid red; color: red; font-size: 1.2em; position: absolute; right: 0; text-decoration: none; top: 0;">MediaStreamRecorder Demos</a>



        <script>
            window.useThisGithubPath = 'streamproc/MediaStreamRecorder';
        </script>
        <script src="https://cdn.webrtc-experiment.com/commits.js" async></script>
    </article>


    <footer>

            <a href="https://www.webrtc-experiment.com/licence/">MIT License</a>
        <table>
     <tr> <td>
            </td>
            </tr>
        </p>
    </footer>
</body>

</html>

And PHP Socket Client below :

<?php

$portnum = 'portnum';
$ipnum = 'Ipnum';

// No Timeout
set_time_limit(0);

if ( ($socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) == FALSE ) {
    $message = "Socket not created";
    echo "<script type='text/javascript'>alert('$message');</script>";
}


        $context = stream_context_create($opts);
        if ( ($file = file_get_contents($_FILES['blob'], false, $context ) )  == FALSE ) {
            $message = "File_get_contents not working.";
            echo "<script type='text/javascript'>alert('$message');</script>";
        }
         $ss = fopen ( file, "r");
         $streamvid = fread ( $ss );


        if ( ( $tt = fsockopen($ipnum, $portnum, $errno, $errstr, 30)) == FALSE ) {
            $message = "fsockopen not working";
            echo "<script type='text/javascript'>alert('$message');</script>";
        }




       if  ( (fwrite ( $tt , $streamvid  ) )  == FALSE ) { //  DIŞARI ALINDI
            $message = "fwrite failed";
            echo "<script type='text/javascript'>alert('$message');</script>";
        }



        fclose( $tt );

?>

Solution

  • mediaRecorder.ondataavailable = function(blob) {
        // upload blob to PHP server
        uploadToPHPServer(blob);
    };
    
    function uploadToPHPServer(blob) {
        var file = new File([blob], 'msr-' + (new Date).toISOString().replace(/:|\./g, '-') + '.webm', {
            type: 'video/webm'
        });
    
        // create FormData
        var formData = new FormData();
        formData.append('video-filename', file.name);
        formData.append('video-blob', file);
    
        makeXMLHttpRequest('https://path-to-your-server/save.php', formData, function() {
            var downloadURL = 'https://path-to-your-server/uploads/' + file.name;
            console.log('File uploaded to this path:', downloadURL);
        });
    }
    
    function makeXMLHttpRequest(url, data, callback) {
        var request = new XMLHttpRequest();
        request.onreadystatechange = function() {
            if (request.readyState == 4 && request.status == 200) {
                callback();
            }
        };
        request.open('POST', url);
        request.send(data);
    }
    

    Here is save.php:

    <?php
    // via: https://github.com/muaz-khan/RecordRTC/blob/master/RecordRTC-to-PHP/save.php
    header("Access-Control-Allow-Origin: *");
    function selfInvoker()
    {
        if (!isset($_POST['audio-filename']) && !isset($_POST['video-filename'])) {
            echo 'PermissionDeniedError';
            return;
        }
    
        $fileName = '';
        $tempName = '';
    
        if (isset($_POST['audio-filename'])) {
            $fileName = $_POST['audio-filename'];
            $tempName = $_FILES['audio-blob']['tmp_name'];
        } else {
            $fileName = $_POST['video-filename'];
            $tempName = $_FILES['video-blob']['tmp_name'];
        }
    
        if (empty($fileName) || empty($tempName)) {
            echo 'PermissionDeniedError';
            return;
        }
        $filePath = 'uploads/' . $fileName;
    
        // make sure that one can upload only allowed audio/video files
        $allowed = array(
            'webm',
            'wav',
            'mp4',
            'mp3',
            'ogg'
        );
        $extension = pathinfo($filePath, PATHINFO_EXTENSION);
        if (!$extension || empty($extension) || !in_array($extension, $allowed)) {
            echo 'PermissionDeniedError';
            continue;
        }
    
        if (!move_uploaded_file($tempName, $filePath)) {
            echo ('Problem saving file.');
            return;
        }
    
        echo ($filePath);
    }
    selfInvoker();
    ?>
    

    Regarding PHP upload issues,

    PS. Don't forget to create uploads directory here: