node.js / Youtube API / Upload

感情迁移 提交于 2019-12-22 17:23:11

问题


Using the following code I'm tring to upload a video youtube via direct upload. I already have the access token (auth_key). I'm pretty sure I'm sending the post data incorrectly...

function upload(auth_key, devKey, callback){

    fs.readFile('test.mp4', function(err, movie){

        var boundary = randomString();

        var xml =
            '<?xml version="1.0"?>' +
            '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">' +
            '<media:group>' + 
            '<media:title type="plain">Bad Wedding Toast</media:title>' +
            '<media:description type="plain">I gave a bad toast at my friends wedding.</media:description>' +
            '<media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">People</media:category>' +
            '<media:keywords>toast, wedding</media:keywords>' + 
            '</media:group>' + 
            '</entry>'
        ;

        var post_data = 
            '--' + boundary + '\n' +
            'Content-Type: application/atom+xml; charset=UTF-8' + '\n' +
            xml + '\n' +
            '--' + boundary + '\n' +
            'Content-Type: video/mp4' + '\n' +
            'Content-Transfer-Encoding: binary' + '\n' +
            movie + '\n' +
            '--' + boundary + '--' + '\n'
        ;   

        var options = {
          host: 'uploads.gdata.youtube.com',
          port: 443,
          path: '/feeds/api/users/default/uploads',
          method: 'POST',
            headers: {
                'Authorization:': 'GoogleLogin auth=' + auth_key,
                'GData-Version': '2',
                'X-GData-Key': 'key=' + devKey,
                'Slug': 'test.mp4',
                'Content-Type': 'multipart/related; boundary="' + boundary + '"',
                'Content-Length': post_data.length,
                'Connection': 'close'
            }
        }

        var req = https.request(options, function(res) {
            var response = '';
          res.on('data', function(chunk) {
                response += chunk;
          });
            res.on('end', function(){
                callback(response);
            });
        });

        if(post_data){
            req.write(post_data);
        }

        req.end();

        req.on('error', function(e) {
          console.error(e);
        });

    });

}

Is failing with "Invalid Request"?


回答1:


You have some errors in your code, the syntax of the html request is missing "\r\n". You should also use the http library and port 80. Your Authorization header is invalid, it should not contain an ":" at the end. And I think the way your are adding the data and calculating the content length also messes things up.

I've successfully uploaded videos to youtube with the following code:

var file_reader = fs.createReadStream(file_path, {encoding: 'binary'});
var file_contents = '';
file_reader.on('data', function(data)
{
    file_contents += data;
});
file_reader.on('end', function()
{
    var xml =
        '<?xml version="1.0"?>' +
        '<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007">' +
        '   <media:group>' + 
        '       <media:title type="plain">' + title + '</media:title>' +
        '       <media:description type="plain">' + description + '</media:description>' +
        '       <media:category scheme="http://gdata.youtube.com/schemas/2007/categories.cat">' + category + '</media:category>' +
        '       <media:keywords>' + keywords + '</media:keywords>' + 
        '   </media:group>' + 
        '</entry>';

    var boundary = Math.random();
    var post_data = [];
    var part = '';

    part = "--" + boundary + "\r\nContent-Type: application/atom+xml; charset=UTF-8\r\n\r\n" + xml + "\r\n";
    post_data.push(new Buffer(part, "utf8"));

    part = "--" + boundary + "\r\nContent-Type: video/mp4\r\nContent-Transfer-Encoding: binary\r\n\r\n";
    post_data.push(new Buffer(part, 'ascii'));
    post_data.push(new Buffer(file_contents, 'binary'));
    post_data.push(new Buffer("\r\n--" + boundary + "--"), 'ascii');

    var post_length = 0;
    for(var i = 0; i < post_data.length; i++)
    {
        post_length += post_data[i].length;
    }

    var options = {
      host: 'uploads.gdata.youtube.com',
      port: 80,
      path: '/feeds/api/users/default/uploads?alt=json',
      method: 'POST',
        headers: {
            'Authorization': 'GoogleLogin auth=' + auth_key,
            'GData-Version': '2',
            'X-GData-Key': 'key=' + exports.developer_key,
            'Slug': 'video.mp4',
            'Content-Type': 'multipart/related; boundary="' + boundary + '"',
            'Content-Length': post_length,
            'Connection': 'close'
        }
    }

    var req = http.request(options, function(res)
    {
        res.setEncoding('utf8');

        var response = '';
        res.on('data', function(chunk)
        {
            response += chunk;
        });
        res.on('end', function()
        {
            console.log(response);
            response = JSON.parse(response);

            callback(response);
        });
    });

    for (var i = 0; i < post_data.length; i++)
    {
        req.write(post_data[i]);
    }

    req.on('error', function(e) {
      console.error(e);
    });

    req.end();
});


来源:https://stackoverflow.com/questions/7368232/node-js-youtube-api-upload

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!