微小的节点js视频转换服务器,管理线程的最佳方式

时间:2017-06-23 12:20:41

标签: node.js ffmpeg video-processing

我正在开发一个小型服务器来转换网络视频,我开始使用TCP服务器(也许它不是最好的解决方案,但它现在不是我的问题的一部分)我发送的路径要转换的视频,然后添加到数据库系统中的队列,在本例中为mysql,但我想在它工作时迁移到MongoDB

var net = require('net'),
    Sequelize = require('sequelize'),
    async = require('async'),
    JsonSocket = require('json-socket'),
    ffmpeg = require('fluent-ffmpeg');

var configDB = require('./config/database.js');
var sequelize = new Sequelize(configDB.url);

var Videos    = sequelize.import('app/models/video');
Videos.sync();

var port = 9838;

var server = net.createServer();
server.listen(port);
server.on('connection', function(socket) {
    socket = new JsonSocket(socket);
    socket.on('message', function(video) {
        console.log(video.video);
        db_data = {
            'name': video.video,
            'converted': false,
            'progress': 0,
            'status': 'Q',
        }
        Videos.create(db_data).then(function () {
            socket.sendMessage('New Video Added');
        }).catch(function () {
            console.log('Error adding Video');
            socket.sendMessage('Error adding video')
        });
    });
});

一旦我在数据库中有一个视频列表,过程就从这段代码开始:

// Function to update the video status on the database
var databaseUpdate = function(status, callback) {
    name = status.name;
    delete status["name"];
    Videos.update(status, {
        where: {
            name: name
        }
    }).then(function (video) {
        if (typeof callback === 'function' && callback) callback();
    });
}

//convert the video:
// If the video status are:
//   - 'Q' for in queue
//   - 'R' for running conversion
//   - 'C' for complete
//   - 'E' for error on the conversion proccess
function ffmpegConvert(video, output, callback)
{
    var filename = video.split('/').reverse()[0].split('.')[0],
        output = output  + filename + '.mp4';  

    ffmpeg(video)
        .videoCodec('libx264')
        .audioCodec('libmp3lame')
        .on('error', function(err) {
            db_data = {
                'name': video,
                'status': 'E',   //<- set status if error ocurre
            }
            databaseUpdate(db_data)
            console.log('An error occurred: ' + err.message);
        })
        .on('end', function(stdout, stderr) {
            db_data = {
                'name': video,
                'converted': true,       //<- set status complete conversion
                'status': 'C',           //<- set status complete conversion
            }
            databaseUpdate(db_data, function(){convertVideos(1)}) // <- put a next video in the queue to convert
        })
        .on('progress', function(progress) {
            db_data = {
                'name': video,
                'status': 'R',                //<- set status ass running conversion
                'progress': progress.percent, //<- set the video processes %
            }
            databaseUpdate(db_data)
        })
        .save(output);
}

// get videos not converted `converted: false` and with
// queque status `status: 'Q'` from the database 
// the send to the ffmpegConvert function in a num of async task
var convertVideos = function(num){
    Videos.findAll(
        {
            where: {
                converted: false,
                status: 'Q'
            }, 
            limit : num, 
            order: '"createdAt" DESC'
        }
    ).then(function (videos) {
        if (videos && videos.length){
            async.each(videos,
                function(item){
                    ffmpegConvert(item.name, output_folder )
                },
            function(err){
            });
        }
    });
}


// Start vidieo conversion with threads number equal to number of cpu    
threads  = require('os').cpus().length,
convertVideos(threads);

所以在这一点上一切都很好,队列中的所有视频都被转换了,但我的问题是:

1 - 如果在首次在服务器上运行后将新视频添加到数据库中,如何将新视频转换为

我无法运行socket.on('message', function(video) {},因为如果我在队列未完成时发送新视频,则会启动一个新的分离线程。我还认为我必须找到一种方法来监控异步任务,以便在发送新任务之前查看正在运行的任务数

2 - 如果服务器出现故障,如何管理未完成的视频?

如果由于某种原因关闭服务器,数据库中当前视频的状态将保留在“R&#39; R&#39;所以将它添加到转换方面的查询没有看到它,并使其损坏。

0 个答案:

没有答案