簡體   English   中英

緩沖區作為輸入,output 用於 fluent-ffmpeg

[英]Buffer as input and output for fluent-ffmpeg

下面看起來很多,但主要只是 output。

我試圖在 fluent-ffmpeg 轉換之前使用 multer(通過 Alamofire 從 iPhone 發送包含視頻(.mov 格式)的請求)作為輸入,然后我希望它作為緩沖區 output,然后將結果發送到 S3。 我想我已經接近了,但我不認為 fluent-ffmpeg 可以傳入緩沖區。這是使用此 buildpack 在 heroku 上部署的: https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest。 ... 如何正確傳遞?

const multer = require('multer')
const upload = multer({ limits: { fieldSize: 100_000_000 } })
app.post('/create', upload.single('video'), async function (request, response, next) {
  let data = request.body
  console.log(data) // prints [Object: null prototype] { param1: '' }
  let bufferStream = new stream.PassThrough();
  console.log(request.file.buffer) // prints '<Buffer 00 00 00 14 66 74 79 70 71 74 20 20 00 00 00 00 71 74 20 20 00 00 00 08 77 69 64 65 01 0e 28 55 6d 64 61 74 21 20 03 40 68 1c 21 4e ff 3c 59 96 7c 82 ... 17718642 more bytes>'

  new ffmpeg({
    source: stream.Readable.from(request.file.buffer, { objectMode: false })
  })
  // .format('mp4')
  .on('error', function (err) {
    console.log(Error: ${err})
  })
  .on('progress', function (progress) {
    console.log("progress")
  })
  .on('end', function () {
    console.log('Formatting finished!');
    console.log("after");
  })
  .writeToStream(bufferStream);

  // Read the passthrough stream
  const buffers = [];
  bufferStream.on('data', function (buf) {
    buffers.push(buf);
  });
  bufferStream.on('end', function () {
    const outputBuffer = Buffer.concat(buffers);
  // use outputBuffer
  });
  console.log("Added.")
  response.send("Success")
});

output 是您在下面看到的(沒有.format('mp4')):

2022-09-03T13:12:24.194384+00:00 heroku[router]: at=info method=POST path="/createBusiness" host=sparrow-testing.herokuapp.com request_id=2774a4ec-e21e-4c2f-8086-460a4cba7d1d fwd="74.71.236.5" dyno=web.1 connect=0ms service=13157ms status=200 bytes=762 protocol=https
2022-09-03T13:12:24.186257+00:00 app[web.1]: [Object: null prototype] { title: '' }
2022-09-03T13:12:24.187296+00:00 app[web.1]: <Buffer 00 00 00 14 66 74 79 70 71 74 20 20 00 00 00 00 71 74 20 20 00 00 00 08 77 69 64 65 01 0e 28 55 6d 64 61 74 21 20 03 40 68 1c 21 4e ff 3c 59 96 7c 82 ... 17718642 more bytes>
2022-09-03T13:12:24.189891+00:00 app[web.1]: Added.
2022-09-03T13:12:24.891564+00:00 app[web.1]: Error: Error: ffmpeg exited with code 1: pipe:1: Invalid argument
2022-09-03T13:12:24.891570+00:00 app[web.1]: 

這個 output 就是你看到的.format('mp4'):

2022-09-03T13:17:07.380415+00:00 app[web.1]: [Object: null prototype] { title: '' }
2022-09-03T13:17:07.381335+00:00 app[web.1]: <Buffer 00 00 00 14 66 74 79 70 71 74 20 20 00 00 00 00 71 74 20 20 00 00 00 08 77 69 64 65 01 0e 28 55 6d 64 61 74 21 20 03 40 68 1c 21 4e ff 3c 59 96 7c 82 ... 17718642 more bytes>
2022-09-03T13:17:07.384047+00:00 app[web.1]: Added.
2022-09-03T13:17:07.388457+00:00 heroku[router]: at=info method=POST path="/createBusiness" host=sparrow-testing.herokuapp.com request_id=84e69ead-09b1-4668-8fc8-b9fc9d5f229d fwd="74.71.236.5" dyno=web.1 connect=0ms service=13079ms status=200 bytes=762 protocol=https
2022-09-03T13:17:08.339746+00:00 app[web.1]: Error: Error: ffmpeg exited with code 1: Conversion failed!
2022-09-03T13:17:08.339783+00:00 app[web.1]: 

我的uploadFile function 工作正常,因為我在其他地方使用它——通常我只是傳入request.file.buffer,但這里它需要是ffmpeg 轉換后的緩沖區

編輯:

在 Heiko 的建議下,我嘗試將 multer 初始化更改為

multer({ limits: { fieldSize: 100_000_000 }, dest: "uploads/" })

我傳遞給 ffmpeg 的源代碼

new ffmpeg({
  source: request.file.path // request.file.path seems to be a path of a Multer-generated file, I'd assume the one I'm sending to the server
})
.format('mp4')

但它仍然出錯

Error: ffmpeg exited with code 1: Conversion failed!

當 request.file 是:

{
  fieldname: 'video',
  originalname: 'video',
  encoding: '7bit',
  mimetype: 'clientMime',
  destination: 'uploads/',
  filename: '08d5d3bbdcf1ac29fb97800136a306e9',
  path: 'uploads/08d5d3bbdcf1ac29fb97800136a306e9',
  size: 1567480
}

我嘗試使用您的代碼,得到相同的結果。 搜索了一會兒,我找到了一個解釋。

好吧,問題在於 MP4 和流媒體。

我不是視頻專家,但似乎在處理 MP4 文件時,ffmpeg 需要搜索文件並且搜索本質上與流不兼容。

因此,您需要 output 從 ffmpeg 中創建一個文件系統文件(使用后將其刪除以使該文件成為臨時文件),然后根據您的需要使用該文件。

要獲得有關 ffmpeg 錯誤的更多調試信息,您需要像這樣修改錯誤事件偵聽器代碼:

// .format('mp4')
  .on('error', function (err, stdout, stderr) {
    console.log(Error: ${err})
    console.log('Stdout: %o', stdout);
    console.log('Stderr: %o', stderr);
  })
  .on('progress', function (progress) {

你會在執行 ffmpeg 進程的 stderr 日志時看到。

您可以在此處確認:

https://stackoverflow.com/a/39679975/8807231

https://superuser.com/a/760287

MP4、MOV 和 3GP在文件末尾都包含一些重要的元數據。 這源於早於流媒體的時代,並且默認情況下使這些格式不適合它。

解決方案是將所謂的moov atom存儲在文件的開頭 這意味着您必須預處理 iPhone 視頻才能對它們進行 stream。

使用 ffmpeg 例如通過FFmpegKit選項-movflags faststart
使用 AVAssetWriter/AVAssetExportSession 它是標志shouldOptimizeForNetworkUse ( via )。
這些需要寫入設備上的文件,也許您可以使用 Alamofire 讀取的命名 pipe 來解決這個問題。

VLC 和 iOS 分別傳輸moov 原子以理解 rest。 如果您可以將此策略應用於 ffmpeg,您只需要在手機上找到 moov atom。 但是沒有找到 ffmpeg 以這種方式設置的示例。

您的服務器代碼看起來不錯,可能也只需要-movflags faststart as output 選項。 為了測試上傳一個 MKV 或 WEBM 文件,ffmpeg 可以讀取開箱即用的流。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM