【问题标题】:Uploading video on Twitter in node.js - 400 error media type unrecognized在 node.js 中在 Twitter 上上传视频 - 400 错误媒体类型无法识别
【发布时间】:2016-11-19 11:09:35
【问题描述】:

这里是生成文件的配置(添加音频文件,并导出到video.mp4)。

我使用 NodeJS 包:videoshow

var videoshow = require('videoshow')

var images = [
  'tovelo.jpg'
]

var videoOptions = {
  fps: 25,
  loop: 20, // seconds 
  transition: true,
  transitionDuration: 1, // seconds 
  videoBitrate: 1024,
  videoCodec: 'libx264',
  size: '640x?',
  audioBitrate: '128k',
  audioCodec: 'libfdk_aac',
  audioChannels: 2,
  format: 'mp4'
}

videoshow(images, videoOptions)
  .audio('tovelo.mp3')
  .save('video.mp4')
  .on('start', function (command) {
    console.log('ffmpeg process started:', command)
  })
  .on('error', function (err, stdout, stderr) {
    console.error('Error:', err)
    console.error('ffmpeg stderr:', stderr)
  })
  .on('end', function (output) {
    console.error('Video created in:', output)
  })

并上传到 Twitter 代码:

var bufferLength, filePath, finished, fs, oauthCredentials, offset, request, segment_index, theBuffer;

request = require('request');
fs = require('fs');
filePath = './video.mp4';
bufferLength = 1000000;
theBuffer = new Buffer(bufferLength);
offset = 0;
segment_index = 0;
finished = 0;
oauthCredentials = {
    consumer_key: '',
    consumer_secret: '',
    token: '',
    token_secret: ''
};

fs.stat(filePath, function(err, stats) {
    var formData, normalAppendCallback, options;

    formData = {
        command: "INIT",
        media_type: 'video/mp4',
        total_bytes: stats.size
    };
    options = {
        url: 'https://upload.twitter.com/1.1/media/upload.json',
        oauth: oauthCredentials,
        formData: formData
    };

    normalAppendCallback = function(media_id) {
        return function(err, response, body) {

            finished++;
            if (finished === segment_index) {

                options.formData = {
                    command: 'FINALIZE',
                    media_id: media_id
                };
                request.post(options, function(err, response, body) {
                    console.log('FINALIZED',response.statusCode,body);

                    delete options.formData;

                    //Note: This is not working as expected yet.
                    options.qs = {
                        command: 'STATUS',
                        media_id: media_id
                    };
                    request.get(options, function(err, response, body) {
                        console.log('STATUS: ', response.statusCode, body);
                    });
                });
            }
        };
    };


    request.post(options, function(err, response, body) {
        var media_id;
        media_id = JSON.parse(body).media_id_string;

        fs.open(filePath, 'r', function(err, fd) {
            var bytesRead, data;

            while (offset < stats.size) {

                bytesRead = fs.readSync(fd, theBuffer, 0, bufferLength, null);
                data = bytesRead < bufferLength ? theBuffer.slice(0, bytesRead) : theBuffer;
                options.formData = {
                    command: "APPEND",
                    media_id: media_id,
                    segment_index: segment_index,
                    media_data: data.toString('base64')
                };
                request.post(options, normalAppendCallback(media_id));
                offset += bufferLength;
                segment_index++
            }
        });
    });
});

上传文件无法识别:

FINALIZED 400 {"request": "\ / 1.1 \ / media \ /upload.json", "error": "InvalidContent."}
STATUS: 400 {"request": "\ / 1.1 \ / media \ /upload.json", "error": "Invalid MediaID."}

你能帮帮我吗?

【问题讨论】:

    标签: node.js twitter upload twitter-oauth


    【解决方案1】:

    这是我一年前使用 Twitter API 在 Node Js 中上传视频的代码:

        // The main function
    var doPublishVideoTweet = function(access_token, text, file) {
    
      var stats = fs.statSync(file.path);
    
      var formData = {
        command: 'INIT',
        media_type: file.mimetype,
        total_bytes: stats.size
      };
    
      var oAuthData = {
        consumer_key: 'TWITTER_KEY',
        consumer_secret: 'TWITTER_SECRET',
        token: access_token.token,
        token_secret: access_token.token_secret
      };
    
      // First step, we send the video size
      request.post({ url: 'https://upload.twitter.com/1.1/media/upload.json', oauth: oAuthData,
        form: formData, json: true }, function(err, response, body) {
        if (!err) {
          // With the response, we start the video transfer in chunks
          transferProcess(0, body.media_id_string, file, stats.size, access_token, function(err) {
            if (!err) {
    
              var formData = {
                command: 'FINALIZE',
                media_id: body.media_id_string
              };
    
              // Once the transfer ended, we finalize it
              request.post({ url: 'https://upload.twitter.com/1.1/media/upload.json', oauth: oAuthData,
                form: formData, json: true }, function(err, response, body) {
                if (!err && !body.error) {
                  var qs = {};
                  if (text) {
                    qs.status = text;
                  }
                  if (mediaId) {
                    qs.media_ids = mediaId;
                  }
    
                  // And the last step, we publish the video as a status update
                  request.post({ url: 'https://api.twitter.com/1.1/statuses/update.json', oauth: oAuthData,
                   qs: qs, json: true }, function(err, response) {
                    if (!err) {
                      console.log('Yeeeaah!');
                    }
                  });
                }
              });
            }
          });
        }
      });
    };
    
    // It processes each part of the video until its end
    var transferProcess = function(index, mediaId, file, fileSize, access_token, callback) {
    
      // First we generate a copy of the file in order to be independent to the original file
      // because it can have problems when opening it at the same time from other file
      var copyFileName = file.path + '-twitter';
      fse.copySync(file.path, copyFileName);
    
      // Once we have the copy, we open it
      var fd = fs.openSync(copyFileName, 'r');
    
      var bytesRead, data, bufferLength = 268435456;
      var buffer = new Buffer(1000000000);
    
      var startOffset = index * bufferLength;
      var length = startOffset + bufferLength > fileSize ? fileSize - startOffset : bufferLength;
    
      // We read the amount of bytes specified from startOffset until length
      bytesRead = fs.readSync(fd, buffer, startOffset, length, null);
    
      // Here, completed tells us that we are transferring the last part or not
      var completed  = bytesRead < bufferLength;
      data = completed ? buffer.slice(0, bytesRead) : buffer;
    
      // We generate a file with the recently read data, and with a name of copyFileName-chunked-0
      var chunkFileName = copyFileName + '-chunked-' + index;
    
      // We create the file so then we can read it and send it
      fs.writeFile(chunkFileName, data, function(err) {
        if (err) {
          callback(err);
        }
        else {
    
          var formData = {
            command: 'APPEND',
            media_id: mediaId,
            segment_index: index
          };
    
          formData.media = fs.createReadStream(chunkFileName);
    
          var oAuthData = {
            consumer_key: 'TWITTER_KEY',
            consumer_secret: 'TWITTER_SECRET',
            token: access_token.token,
            token_secret: access_token.token_secret
          };
    
          // Once we have the file written, we upload it
          request.post({ url: 'https://upload.twitter.com/1.1/media/upload.json', oauth: oAuthData,
            formData: formData, json: true }, function (err, response) {
            // If there was an error or the reading process of the file has ended, we go back to the initial process to finalize the video upload
            if (err) {
              callback(err);
            }
            else if (completed) {
              callback(null);
            }
            // Else, we must continue reading the file, incrementing the reading index
            else {
              transferProcess(index + 1, mediaId, file, fileSize, access_token, callback);
            }
          });
        }
      });
    };
    

    希望你可以使用它。

    【讨论】:

    • 你希望file 在这个例子中是什么类型?
    猜你喜欢
    • 2018-10-20
    • 2015-10-10
    • 1970-01-01
    • 2018-08-07
    • 1970-01-01
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2019-10-26
    相关资源
    最近更新 更多