- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我目前正在开发一个实用程序,该实用程序负责从云中提取音频和视频文件并通过 FFMPEG 将它们合并在一起。由于我是 FFMPEG 的新手,因此我将把问题分成 FFMPEG 部分和 C# 部分,以便人们可以回答其中一个部分或另一个部分(或两者都回答!)。
FFMPEG 部分
目前,如果只有 1 个视频文件存在并且需要与多个文件合并,我有一个有效的 FFMPEG 参数。
ffmpeg -i input1.mkv -i input1.mka -i input2.mka -i input3.mka -i input4.mka -filter_complex "[1:a]adelay=0s:all=1[a1pad];[2:a]adelay=20s:all=1[a2pad];[3:a]adelay=30s:all=1[a3pad];[4:a]adelay=40s:all=1[a4pad];[a1pad][a2pad][a3pad][a4pad]amix=inputs=4:weights=1|1|1|1[aout]" -map [aout] -map 0:0 output4.mkv
您在那里看到的延迟是通过从最早创建的音频或视频文件的开始时间减去每个文件的开始时间来确定的。我知道如果我想创建多个视频的水平堆栈,我可以这样做
ffmpeg -i input1.mkv -i input1.mka -i input2.mkv -i input2.mka -i input3.mka -i input4.mka
-filter_complex
"[2:v]tpad=start_duration=120:color=black[vpad];
[3:a]adelay=120000:all=1[a2pad];
[4:a]adelay=180000:all=1[a3pad];
[5:a]adelay=200000:all=1[a4pad];
[0:v][vpad]hstack=inputs=2[vout];
[1:a][a2pad][a3pad][a4pad]amix=inputs=4:weights=1|1|1|1[aout]"
-map [vout] -map [aout]
output.mkv
但我想做的是既保留音频和视频文件的延迟,又连接(而不是堆叠)这些视频,我该怎么做呢?
List<FileModel> _records;
public class FileModel {
public string Id { get; set; }
public string FileType { get; set; }
public string StartTime { get; set; }
}
然后,该实用程序必须遍历该列表并创建要由 Xabe.FFMPEG 包执行的 arg(如 FFMPEG 部分所示)。我想解决这个问题的方法基本上是创建 2 个字符串生成器。一个字符串生成器将负责处理输入,另一个字符串生成器。这是我到目前为止所拥有的
private async Task CombineAsync()
{
var minTime = _records.Min(y => Convert.ToDateTime(y.StartTime));
var frontBuilder = new StringBuilder("-y ");
var middleBuilder = new StringBuilder("-filter_complex \"");
var endString = $" -map [vout] -map [aout] {_folderPath}\\CombinedOutput.mkv";
for (var i = 0; i < _records.Count; i++)
{
var type = _records[i].FileType.ToLower();
var delay = (Convert.ToDateTime(_records[i].StartTime).Subtract(minTime)).TotalSeconds;
frontBuilder.Append($"-i {_folderPath + "\\" + _records[i].Id} ");
var addColon = i != _records.Count - 1 ? ";" : "";
middleBuilder.Append(type.Equals("video") ? $"[{i}:v]tpad=start_duration={delay}:color=black[v{i}pad]{addColon} " : $"[{i}:a]adelay={delay}s:all=1[a{i}pad]{addColon} ");
}
middleBuilder.Append("\"");
Console.WriteLine(frontBuilder.ToString() + middleBuilder.ToString() + endString);
// var args = frontBuilder + middleBuilder + endString;
// try
// {
// var conversionResult = await FFmpeg.Conversions.New().Start(args);
// Console.WriteLine(JsonConvert.SerializeObject(conversionResult));
// }
// catch (Exception e)
// {
// Console.WriteLine(e);
// }
}
[0:v][vpad]hstack=inputs=2[vout]; // This part will change for video concatenation depending on what gets answered above
[1:a][a2pad][a3pad][a4pad]amix=inputs=4:weights=1|1|1|1[aout]
最佳答案
在混合 documentNote that this filter only supports float samples(the amerge and pan audio filters support many formats).
可能你的文件格式很多,试试amerge
要使用如此多的过滤器轻松生成参数,请尝试 FFmpegArgs
FFmpegArg ffmpegArg = new FFmpegArg().OverWriteOutput();
List<ImageMap> imageMaps = new List<ImageMap>();
List<AudioMap> audioMaps = new List<AudioMap>();
foreach (var item in _records)
{
if (item.IsVideo)
{
imageMaps.Add(ffmpegArg.AddImageInput(new ImageFileInput(item.FilePath))
.TpadFilter().StartDuration(item.Delay).MapOut);
}
else
{
audioMaps.Add(ffmpegArg.AddAudioInput(new AudioFileInput(item.FilePath))
.AdelayFilter().Delays(item.Delay).All(true).MapOut);
}
}
var imageMap = imageMaps.HstackFilter().MapOut;
var audioMap = audioMaps.AmergeFilter().MapOut;
ffmpegArg.AddOutput(new VideoFileOutput("out.mp4", imageMap, audioMap));
var result = ffmpegArg
.Render(c => c
.WithFFmpegBinaryPath("path to ffmpeg.exe")
.WithWorkingDirectory("working dir"))
.Execute();
result.EnsureSuccess();
或通过 kesh 评论
FFmpegArg ffmpegArg = new FFmpegArg().OverWriteOutput();
List<ImageMap> imageMaps = new List<ImageMap>();
List<AudioMap> audioMaps = new List<AudioMap>();
foreach (var item in _records)
{
if (item.IsVideo)
{
imageMaps.Add(ffmpegArg.AddImageInput(new ImageFileInput(item.FilePath))
.TpadFilter().StartDuration(item.Delay).MapOut);
}
else
{
audioMaps.Add(ffmpegArg.AddAudioInput(new AudioFileInput(item.FilePath)));
//audioMaps.Add(ffmpegArg.AddAudioInput(new AudioFileInput(item.FilePath).SsPosition(item.Skip)));
}
}
var imageMap = imageMaps.HstackFilter().MapOut;
var concatFilter = audioMaps.Select(x => new ConcatGroup(x)).ConcatFilter();
ffmpegArg.AddOutput(new VideoFileOutput("out.mp4", imageMap, concatFilter.AudioMapsOut.First()));
var result = ffmpegArg
.Render(c => c
.WithFFmpegBinaryPath("path to ffmpeg.exe")
.WithWorkingDirectory("working dir"))
.Execute();
result.EnsureSuccess();
关于c# - 将多个视频文件与延迟的音频文件连接起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71605780/
我正在尝试执行 vagrant up 但一直遇到此错误: ==> default: IOError: [Errno 13] Permission denied: '/usr/local/lib/pyt
我在容器 div 中有一系列动态创建的不同高度的 div。 Varying text... Varying text... Varying text... Varying text.
通过 cygwin 运行 vagrant up 时遇到以下错误。 stderr: /bin/bash: /home/vagrant/.ansible/tmp/ansible-tmp-14872260
今天要向小伙伴们介绍的是一个能够快速地把数据制作成可视化、交互页面的 Python 框架:Streamlit,分分钟让你的数据动起来! 犹记得我在做机器学习和数据分析方面的毕设时,
我是 vagrant 的新手,正在尝试将第二个磁盘添加到我正在用 vagrant 制作的虚拟机中。 我想出了如何在第一次启动虚拟机时连接磁盘,但是当我关闭机器时 然后再次备份(使用 'vagrant
我是一名优秀的程序员,十分优秀!