gpt4 book ai didi

c# - 将多个视频文件与延迟的音频文件连接起来

转载 作者:行者123 更新时间:2023-12-04 23:10:03 25 4
gpt4 key购买 nike

我目前正在开发一个实用程序,该实用程序负责从云中提取音频和视频文件并通过 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
但我想做的是既保留音频和视频文件的延迟,又连接(而不是堆叠)这些视频,我该怎么做呢?
C#部分
你看到上面那个巨大的arg了吗?该实用程序应该根据录音列表生成。这是模型。
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/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com