[英]Convert or wrap h264 file to mp4 with Node JS
我正在 Raspberry Pi 上拍攝視頻,並希望將原始 h264 文件轉換為 mp4 文件,或者像使用命令行/Python 那樣將其包裝在 mp4 中。 但是,我希望在 NodeJS 中做到這一點。 似乎有很多 node JS 庫在 npm 上使用了 Raspberry Pi 的 mp4-box 庫。 但是,它們都沒有適當的文檔或似乎適合我的項目的需要。 我不知道我是否遺漏了什么或者這是不可能的。
沒有直接的方法可以將 H.264 編碼的文件嵌入到 MP4 容器中,而無需從頭開始實際構建整個文件結構。 這是可行的,但為了做到這一點,您需要了解 mp4 容器格式(主要基於 Quicktime MOV 容器)並使用TypedArrays
構建它,結果您可以將其保存為 MP4 文件(我在這里創建了一個粘貼描述容器文件結構)。
另一種方法是從 Node.js 生成FFmpeg (或直接使用該軟件)並提供 H.264 作為輸入並將其保存為 MP4 文件。 這很直接。 該命令將類似於:
ffmpeg -i yourH264encodedFileHere -c:v copy mp4FileContainer.mp4
要從 Node 運行它,可以使用spawn
(參見示例)。
這種基本方法的替代方法是安裝和使用fluent-ffmpeg NPM 模塊,它可以完成所有繁重的工作。
var ffmpeg = require("fluent-ffmpeg");
var inFilename = "video.h264";
var outFilename = "video.mp4";
ffmpeg(inFilename)
.outputOptions("-c:v", "copy") // this will copy the data instead or reencode it
.save(outFilename);
一些注意事項:
ffmpeg.setFfmpegPath(pathToFFmpegBin)
代替。嘗試在我的 pi 零上安裝 ffmpeg 花了兩個多小時並以錯誤告終,所以這里有一種包裝 mp4 的替代方法:
sudo apt install -y gpac
exec
調用MP4Box
命令,如Raspivid 文檔所說import raspivid from 'raspivid';
import { createWriteStream, unlinkSync } from 'fs'
import { exec } from 'child_process'
import internal from 'stream'
// Helper: promisify streaming to a file
const streamToFile = (inputStream: internal.Readable, filePath: string) => {
return new Promise((resolve, reject) => {
const fileWriteStream = createWriteStream(filePath)
inputStream
.pipe(fileWriteStream)
.on('finish', resolve)
.on('error', reject)
})
}
// Helper: promisify executing shell command
const execPromise = (command: string) => {
return new Promise((resolve, reject) => {
exec(command, (error, stdout, stderr) => {
doLogInfo(stdout)
if (error) {
console.error(error.message)
reject(error)
}
if (stderr) {
console.error(stderr)
resolve(stderr)
}
resolve()
})
})
}
// Driver
const getMp4FromRaspivid = async () => {
// Record vid w raspivid
const h264Path = './myVid.h264'
const readVideoStream = await raspivid(VIDEO_OPTIONS) as internal.Readable;
await streamToFile(readVideoStream, h264Path)
// Wrap in mp4
const mp4Path = './myVid.mp4'
const execCommand = ['MP4Box', '-add', h264Path, mp4Path].join(' ')
await execPromise(execCommand)
// Delete h264
unlinkSync(h264Path)
}
了解 mp4(如 mkv)是一個容器非常重要。 您可以向這些容器添加視頻、音頻、字幕“層”。 而 H.264 已經是一種壓縮格式,它不是原始視頻格式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.