collab-project / videojs-record

video.js plugin for recording audio/video/image files
https://collab-project.github.io/videojs-record
MIT License
1.39k stars 314 forks source link

.fileupload (jQuery) doesn't works with audio+video player #190

Closed priMo-ex3m closed 6 years ago

priMo-ex3m commented 6 years ago

I just spend whole day to install this package via npm first (w/o succes), then with bower... and the links from example was different with current directories. So, finally I solve it. I use to remake ur code to reproduce audio-player & upload to server obrained audio file. I did absolutely same with video player, I changed all like in example " audio + video", video is obtaining (console.log), it shows me size of obtained file, format, but returns me error 500 from the server. Note that I use absolute the same code at backend like with audio-only(it worked with audio). I'm working with Laravel 5.4, console.log shows me following stepts :

started recording video stream. RecordRTC.js:1012 Using recorderType: MediaStreamRecorder RecordRTC.js:2016 Passing following config over MediaRecorder API. {type: "video", video: {…}, canvas: {…}, frameInterval: 10, disableLogs: false, …} RecordRTC.js:693 Recorder state changed: recording RecordRTC.js:93 Initialized recorderType: MediaStreamRecorder for output-type: video (index):79 started recording! RecordRTC.js:119 Stopped recording video stream. RecordRTC.js:693 Recorder state changed: stopped RecordRTC.js:160 video/webm -> 308 KB (index):85 finished recording: {video: Blob(308296)} jquery.min.js:5 POST http://localhost:8000/test 500 (Internal Server Error)

My back-end code :

> 
> >     /**
> >      * Store a newly created resource in storage.
> >      *
> >      * @param  \Illuminate\Http\Request  $request
> >      * @return \Illuminate\Http\Response
> >      */
> >     public function test(Request $request) // POST /cvs
> >     {   
> >         print_r($_FILES);
> >         $path = '/video/'.uniqid();
> > 
> >         Storage::disk('local')->putFileAs('public'.$path, $request->file('files'), "filename.webm");
> >                      return response()->json("x",200);
> > 
> >     }

Response from /test route in my debugger :
Array () , so it means that obtained video doesn't hit the Request object.

My entire code of player and jQuery (worked for audio-only)

<head> 
       <title> Project </title>
       <link href="/videojs-record/node_modules/video.js/dist/video-js.min.css" rel="stylesheet">
        <link href="/videojs-record/dist/css/videojs.record.css" rel="stylesheet">

        <script src="/videojs-record/node_modules/video.js/dist/video.min.js"></script>
        <script src="/videojs-record/node_modules/recordrtc/RecordRTC.js"></script>
        <script src="/videojs-record/node_modules/webrtc-adapter/out/adapter.js"></script>

        <script src="/videojs-record/dist/videojs.record.js"></script>

        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script src="/videojs-record/node_modules/blueimp-file-upload/js/vendor/jquery.ui.widget.js"></script>
        <script src="/videojs-record/node_modules/blueimp-file-upload/js/jquery.iframe-transport.js"></script>
        <script src="/videojs-record/node_modules/blueimp-file-upload/js/jquery.fileupload.js"></script>

        <style>
        /* change player background color */
        #myVideo {
            background-color: #ff6b6b;
        }
        /* hide file upload button */
        #fileupload {
            display:block;
        }
        </style>
</head>

<body>
        <video id="myVideo" class="video-js vjs-default-skin"></video>

          Select a video: <input id="fileupload" type="file" name="files">

<script>
        $(function () {
            $('#fileupload').fileupload({
                url: '/test',
                method: "POST",
                done: function (e, data) {
                    $.each(data.files, function (index, file) {
                        var message = 'Upload complete: ' + file.name + ' (' +
                            file.size + ' bytes)';
                        $('<p/>').text(message).appendTo(document.body);
                        console.log(message);
                    });
                }
            });
var player = videojs("myVideo", {
    controls: true,
    width: 320,
    height: 240,
    fluid: false,
    plugins: {
        record: {
            audio: true,
            video: true,
            maxLength: 60,
            debug: true
        }
    }
}, function(){
    // print version information at startup
    videojs.log('Using video.js', videojs.VERSION,
        'with videojs-record', videojs.getPluginVersion('record'));
});
// error handling
player.on('deviceError', function() {
    console.log('device error:', player.deviceErrorCode);
});
player.on('error', function(error) {
    console.log('error:', error);
});
// user clicked the record button and started recording
player.on('startRecord', function() {
    console.log('started recording!');
});
// user completed recording and stream is available
            player.on('finishRecord', function() {
                // the blob object contains the audio data
                var videoFile = player.recordedData;
                console.log('finished recording: ', videoFile);
                // upload data to server
                var filesList = [videoFile];
                $('#fileupload').fileupload('add', {files: filesList});
            });
        });
</script>

UPDATE : I added if (jQuery('#fileupload').val()) { console.log("YES"); } else { console.log("NO");} after

            player.on('finishRecord', function() {
                // the blob object contains the audio data
                var videoFile = player.recordedData;
                console.log('finished recording: ', videoFile);
                // upload data to server
                var filesList = [videoFile];
                $('#fileupload').fileupload('add', {files: filesList});

and it outputed me "NO" at console.log

So, here is the problem : $('#fileupload').fileupload('add', {files: filesList}); doesn't add obtained file to the input. Do you have idea - why?

priMo-ex3m commented 6 years ago

So, that was because :

  1. in Firefox we have to use player.recordedData
  2. in Chrome(as I used), that object has one more object key - video. So, to access that object we have to use : player.recordedData.video

To salve this cross-browser incompatibility with code :

 player.on('finishRecord', function() {
                if(player.recordedData.video == undefined) {
                    var videoFile = player.recordedData;
                } else {
                   var videoFile = player.recordedData.video;
                }
                console.log('finished recording: ', videoFile);
                // upload data to server
                var filesList = [videoFile];
                $('#fileupload').fileupload('add', {files: filesList});
            });
thijstriemstra commented 6 years ago

@priMo-ex3m thanks for that fix, can you make a pull request for that?

thijstriemstra commented 6 years ago

You're using audio+video, and the examples use audio-only, so I cannot update these examples, closing as is.