好吧,我正在使用这个项目来创建一个 Telegram bot,它接收 mp4 文件的 URL,将它们下载到服务器上并将它们上传到 Telegram。
到目前为止一切正常,除了转换某些 .mp4 文件。
例如,如果我使用来自https://sample-videos.com/的示例 mp4 视频,它可以正常工作并成功转换,但如果我使用,例如某个随机网站的视频,它也是简单的 .mp4 文件,它不起作用并引发此错误:
[mov,mp4,m4a,3gp,3g2,mj2 @ 0x1932420] 格式 mov,mp4,m4a,3gp,3g2,mj2 仅检测到低分 1,可能误检测![mov,mp4,m4a,3gp,3g2,mj2 @ 0x1932420] moov atom not found data/720P_1500K_210306701.mp4:处理输入时发现无效数据
我一直试图解决这个问题好几天了,非常感谢你对这个问题的任何帮助.
我能够通过将文件的位置作为字符串传递并将其转码为mp3,使用fluent-ffmpeg成功传输存储在Node.js服务器上的mp4音频文件.如果我从同一个文件创建一个文件流并将其传递给fluent-ffmpeg,则它适用于mp3输入文件,但不适用于mp4文件.在mp4文件的情况下,没有抛出错误,它声称流已成功完成,但浏览器中没有播放任何内容.我猜这与存储在mp4文件末尾的元数据有关,但我不知道如何编写代码.当它的位置传递给ffmpeg而不是流时,这是完全相同的文件.当我尝试将流传递给s3上的mp4文件时,再次没有引发错误,但没有任何内容流到浏览器.这并不奇怪,因为ffmpeg不能在本地作为流使用该文件,所以期望它处理来自s3的流是一厢情愿的想法.
如何从s3流式传输mp4文件,而不将其作为文件首先存储在本地?如何在不转码文件的情况下让ffmpeg执行此操作?以下是我目前无法使用的代码.请注意,它尝试将s3文件作为流传递给ffmpeg,并且它还将其转码为mp3,我不想这样做.
.get(function(req,res) {
aws.s3(s3Bucket).getFile(s3Path, function (err, result) {
if (err) {
return next(err);
}
var proc = new ffmpeg(result)
.withAudioCodec('libmp3lame')
.format('mp3')
.on('error', function (err, stdout, stderr) {
console.log('an error happened: ' + err.message);
console.log('ffmpeg stdout: ' + stdout);
console.log('ffmpeg stderr: ' + stderr);
})
.on('end', function () {
console.log('Processing finished !');
})
.on('progress', function (progress) {
console.log('Processing: ' + progress.percent + '% done');
})
.pipe(res, {end: true});
});
});
Run Code Online (Sandbox Code Playgroud)
这是在调用aws.s3时使用knox库...我也尝试使用Node.js的标准aws sdk编写它,如下所示,但我得到与上面相同的结果.
var AWS = require('aws-sdk');
var s3 = …Run Code Online (Sandbox Code Playgroud) 我试图将mp3文件转换为wav文件,但我不知道如何做到这一点,我尝试使用fluent-ffmpeg库,但我不知道如何使用它.
我正在尝试使用 Node.js Express 编写一个流视频服务器。视频服务器的主要任务是在视频上应用水印。这是我的代码
const express = require("express");
const fs = require("fs");
const path = require("path");
const ffmpeg = require("fluent-ffmpeg");
const ffmpegInstaller = require("@ffmpeg-installer/ffmpeg");
ffmpeg.setFfmpegPath(ffmpegInstaller.path);
const app = express();
app.get("/", function (req, res) {
const path = req.query.video;
const WATERMARK_PATH = req.query.id + `.png`;
const stat = fs.statSync(path);
const fileSize = stat.size;
const range = req.headers.range;
if (range) {
const parts = range.replace(/bytes=/, "").split("-");
const start = parseInt(parts[0], 10);
const end = parts[1] ? parseInt(parts[1], 10) : fileSize - 1; …Run Code Online (Sandbox Code Playgroud) 当他们上传到firebase存储时,我必须将视频从webm转码到mp4.我在这里有一个代码演示,但如果上传的视频太大,firebase功能将在转换完成之前超时.我知道可以增加该功能的超时限制,但这看起来很麻烦,因为我无法确认该过程所需的时间比超时限制少.
有没有办法阻止firebase超时,而不仅仅是增加最大超时限制?
如果没有,有没有办法完成耗时的过程(如视频转换),同时仍然让每个进程开始使用firebase函数触发器?
如果即使使用firebase函数完成耗时的过程也不是真正存在的东西,有没有办法加速fluent-ffmpeg的转换而不会影响质量那么多?(我意识到这一部分有很多问题.如果我绝对必须,我打算降低质量,因为网络转换为mp4的原因是针对IOS设备)
作为参考,这是我提到的演示的主要部分.正如我之前所说的,这里可以看到完整的代码,但复制过的代码的这一部分是创建Promise以确保转码完成的部分.完整的代码只有70行,所以如果需要它应该相对容易.
const functions = require('firebase-functions');
const mkdirp = require('mkdirp-promise');
const gcs = require('@google-cloud/storage')();
const Promise = require('bluebird');
const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');
Run Code Online (Sandbox Code Playgroud)
(这里有一堆文本解析代码,然后是onChange事件中的下一个代码块)
function promisifyCommand (command) {
return new Promise( (cb) => {
command
.on( 'end', () => { cb(null) } )
.on( 'error', (error) => { cb(error) } )
.run();
})
}
return mkdirp(tempLocalDir).then(() => {
console.log('Directory Created')
//Download item from bucket
const bucket …Run Code Online (Sandbox Code Playgroud) javascript ffmpeg firebase fluent-ffmpeg google-cloud-functions
我正在使用fluent-ffmpegNode.js 库对视频文件执行批处理操作。裁剪 16:9 输入的视频过滤器,添加填充并将字幕刻录到填充中。
在下一步中,我想使用复杂的过滤器将图像叠加为水印。
ff.input(video.mp4)
ff.input(watermark.png)
ff.videoFilter([
'crop=in_w-2*150:in_h',
'pad=980:980:x=0:y=0:color=black',
'subtitles=subtitles.ass'
])
ff.complexFilter([
'overlay=0:0'
])
ff.output(output.mp4)
Run Code Online (Sandbox Code Playgroud)
但是,运行它,我收到以下错误:
Filtergraph 'crop=in_w-2*150:in_h,pad=980:980:x=0:y=0:color=black,subtitles=subtitles.ass' was specified through the -vf/-af/-filter option for output stream 0:0, which is fed from a comple.
-vf/-af/-filter and -filter_complex cannot be used together for the same stream.
Run Code Online (Sandbox Code Playgroud)
据我了解,视频过滤器和复杂过滤器选项不能一起使用。如何解决这个问题?
我有一组视频,我想对每个视频进行屏幕截图,然后对这些生成的图像进行一些处理,最后存储它们。
为了能够进行处理,我需要将屏幕截图作为缓冲区。
这是我的代码
ffmpeg(videoFilePath)
.screenshots({
count: 1,
timestamps: ['5%'],
folder: DestinationFolderPath,
size: thumbnailWidth + 'x' + thumbnailHeight,
})
.on('err', function (error) {
console.log(err)
});
Run Code Online (Sandbox Code Playgroud)
如您所见,输出直接存储在 DestinationFolderPath 中。相反,我想将输出作为缓冲区。
在FFMPEG中,我实际上正在修剪和结束24 FPS视频.当我应用复杂的过滤器
ffmpeg -i sample.mp4 -filter_complex \
"[0:v]setpts = PTS-STARTPTS[bv];
[bv]split=6[v0][v1][v2][v3][v4][v5];
[v0]trim=start_frame=1:end_frame=142,loop=1:1:1,setpts=N/FRAME_RATE/TB[0v];
[v1]trim=start_frame=846:end_frame=878,loop=1:1:1,setpts=N/FRAME_RATE/TB[1v];
[v2]trim=start_frame=57:end_frame=114,loop=1:1:1,setpts=N/FRAME_RATE/TB[2v];
[v3]trim=start_frame=865:end_frame=885,loop=1:1:1,setpts=N/FRAME_RATE/TB[3v];
[v4]trim=start_frame=70:end_frame=155,loop=1:1:1,setpts=N/FRAME_RATE/TB[4v];
[v5]trim=start_frame=155:end_frame=909,loop=1:1:1,setpts=N/FRAME_RATE/TB[5v];
[0:a]asplit=6[a0][a1][a2][a3][a4][a5];
[a0]atrim=0.041666666666666664:5.917,asetpts=N/SR/TB[0a];
[a1]atrim=35.256:36.603,asetpts=N/SR/TB[1a];
[a2]atrim=2.379:4.767,asetpts=N/SR/TB[2a];
[a3]atrim=36.024:36.859,asetpts=N/SR/TB[3a];
[a4]atrim=2.93:6.438172,asetpts=N/SR/TB[4a];
[a5]atrim=6.438172:37.895,asetpts=N/SR/TB[5a];
[0v][0a][1v][1a][2v][2a][3v][3a][4v][4a][5v][5a]concat=n=6:v=1:a=1[vv][aa]"\
-map "[vv]" -map "[aa]" output.mp4
Run Code Online (Sandbox Code Playgroud)
我收到"缓冲区队列溢出,丢弃"错误.由此产生的视频和音频仍然无法正常工作.
ffmpeg version 3.2-1~16.04.york1 Copyright (c) 2000-2016 the FFmpeg developers
built with gcc 5.4.1 (Ubuntu 5.4.1-3ubuntu1~ubuntu16.04.1york0) 20161019
configuration: --prefix=/usr --extra-version='1~16.04.york1' --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --enable-gpl --disable-libtesseract --disable-stripping --disable-decoder=libschroedinger --enable-avresample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libebur128 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libmodplug --enable-libmp3lame --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librubberband --enable-libschroedinger …Run Code Online (Sandbox Code Playgroud) 我想用来fluent-ffmpeg创建一个目录或数据库条目的最后n个图像的视频.
哪种语法正确?
这些是我的尝试:
模仿shell命令
ffmpeg()
.addInput('ls *png | tail -n 17')
.inputOptions("-pattern_type glob")
.output("output.mp4").run()
Run Code Online (Sandbox Code Playgroud)
但它不接受shell命令;
空间分隔的路径
ffmpeg()
.addInput('a*.png b*.png ')
.inputOptions("-pattern_type glob")
.output("output.mp4").run()
Run Code Online (Sandbox Code Playgroud)
但它不接受以空格分隔的文件列表;
图像路径数组
ffmpeg()
.addInput(array) // ['aa.png', 'a1.png',,,'bbb.png']
.inputOptions("-pattern_type glob")
.output("output.mp4").run()
Run Code Online (Sandbox Code Playgroud)
但它不接受数组.
编辑:
此外,从使用节点fluent ffmpeg合并多个视频,我可以使用文件数组添加多个输入
var ffmpeg= require('fluent-ffmpeg');
var f=ffmpeg()
pngarr.forEach(p => f.input(p)) /// pngarr is my array of png paths
Run Code Online (Sandbox Code Playgroud)
但跑步
f.output("./output.mp4").run()
Run Code Online (Sandbox Code Playgroud)
我只获得一个0秒的视频,其中包含列表的第一个png.
fluent-ffmpeg ×10
ffmpeg ×8
node.js ×7
amazon-s3 ×1
firebase ×1
javascript ×1
mongodb ×1
mp4 ×1
streaming ×1
telegram ×1
telegram-bot ×1