Wednesday, 31 May 2017

Nodejs stream.read returns null before file is completely read

I'm trying to upload a video to facebook by reading and uploading chunks from file stream. But after first read and upload, when it tries to read second chunk, it returns null ending upload session. Thanks for the help

function uploadVideo(parent_id, video_path) {
    var defer = q.defer();

    var stream = fs.createReadStream(video_path);
    var file_size = fs.statSync(video_path).size;
    var session_id, video_id;

    // stream.on('readable', () => {
        fbApi.api('POST', `https://graph-video.facebook.com/v2.9/${parent_id}/advideos`, {
            file_size,
            upload_phase: 'start'
        }, true).then(response => {
            session_id = response.upload_session_id;
            video_id = response.video_id;
            uploadChunk(response);
        }).catch(error => {
            console.error(error);
        })
    // });

    function uploadChunk(args) {
        console.log("Uploading: %s% ", (args.end_offset / file_size) * 100 );
        chunk_size = Number(args.end_offset) - Number(args.start_offset);
        var chunk = stream.read(chunk_size);
        if(chunk === null) return finishUpload();
        fbApi.rp({ 
            method: 'POST', 
            uri: `https://graph-video.facebook.com/v2.9/${parent_id}/advideos`, 
            qs: {access_token: conf.accessToken},
            formData: {
                upload_phase: 'transfer',
                start_offset: args.start_offset,
                upload_session_id: session_id,
                video_file_chunk: {
                    value: chunk,
                    options: {
                        filename: 'chunk'
                    }
                }
            }
        }).then(uploadChunk).catch(error => {
            console.log("Failed to upload chunk. retrying in 60 seconds");
            setTimeout(uploadChunk, 60*1000); 
        })
    }

    function finishUpload() {
        fbApi.api('POST', `https://graph-video.facebook.com/v2.9/${parent_id}/advideos`, {
            upload_phase: 'finish',
            upload_session_id: session_id
        }, true).then(response => {
            defer.resolve(video_id);
        }).catch(error => {
            console.error(error);
        });
    }

    return defer.promise;
}



via Prakash GPz

No comments:

Post a Comment