You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用FFmpeg按多时间戳分割音视频后时间轴偏移的问题求助

FFmpeg按多时间戳分割音视频后时间轴偏移的问题求助

我想要根据多个时间戳分割音频(mp3或同类格式)或视频文件,就像用常规剪辑软件那样,通过选择开始和结束时间来裁剪文件。

我目前的实现代码

下面是我用来处理音频的后端接口代码:

[HttpPost]
public async Task<string> ProcessFullAudio([FromBody] ProcessFullAudioRequest processFullAudioRequest)
{
    if (processFullAudioRequest == null || processFullAudioRequest.StartEndTimes == null || processFullAudioRequest.StartEndTimes.Length == 0)
    {
        throw new ArgumentException("Invalid request: StartEndTimes cannot be null or empty.");
    }

    var timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
    var fileName = $"{Guid.NewGuid()}_{timestamp}.mp3";
    var outputFilePath = Path.Combine(customFolder, fileName);

    int amntOfTimeStamps = processFullAudioRequest.StartEndTimes.Length;
    int step = 0;
    string lineOfCodeForFirstTime = " \"aselect='not(between(t,<START>,<END>)";
    string lineOfCodeForRestOfTimes = "+between(t,<START>,<END>)";
    string argument = "";
    string result = null;
    string filterComplex = GenerateAtrims(processFullAudioRequest.StartEndTimes);

    while (step != amntOfTimeStamps)
    {
        step++;
        if (step == 1)
        {
            result = ReplacePlaceholders(lineOfCodeForFirstTime, HhMmSsToSeconds(processFullAudioRequest.StartEndTimes[step - 1].Start).ToString() , HhMmSsToSeconds(processFullAudioRequest.StartEndTimes[step - 1].End).ToString());
            argument += result;
        }
        else
        {
            result = ReplacePlaceholders(lineOfCodeForRestOfTimes, HhMmSsToSeconds(processFullAudioRequest.StartEndTimes[step - 1].Start).ToString() , HhMmSsToSeconds(processFullAudioRequest.StartEndTimes[step - 1].End).ToString());
            argument += result;
        }

    }
    var FFMPEG_PATH = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "ffmpeg.exe");
    if (!System.IO.File.Exists(FFMPEG_PATH))
    {
        return "ffmpeg.exe IS NULL";
    }
    var arguments = $"-i {processFullAudioRequest.InputFilePath} -af {argument})' ,asetpts=N/SR/TB\" -acodec libmp3lame {outputFilePath}";

    await ProcessAsyncHelper.ExecuteShellCommand(FFMPEG_PATH, arguments, Timeout.Infinite);

    return outputFilePath;
}

代码的逻辑应该比较直观,最终拼接出来的FFmpeg命令参数argument期望是类似这样的格式:

-i C:\Users\User\Desktop\AudioEditorBackEnmd\AudioEditorAPI\wwwroot\mp3\TestAudio_123.mp3 -af  "aselect='not(between(t,120,240))' ,asetpts=N/SR/TB" -acodec libmp3lame C:\Users\User\Desktop\AudioEditorBackEnmd\AudioEditorAPI\wwwroot\mp3\aa887f21-0a90-4ec5-80ba-2b265cb445b4_20250219_123804.mp3

处理完成后,我会把输出文件路径传给下载接口:

[HttpGet]
public async Task<IActionResult> DownloadProcessedFile([FromQuery] string fileName)
{
    if (string.IsNullOrWhiteSpace(fileName))
    {
        return BadRequest("File name is required.");
    }

    var filePath = Path.Combine(customFolder, fileName);

    if (!System.IO.File.Exists(filePath))
    {
        return NotFound(new { fileName });
    }

    try
    {
        var fileBytes = await System.IO.File.ReadAllBytesAsync(filePath);

        return File(fileBytes, "audio/mpeg", fileName);

    }
    catch (Exception ex)
    {
        throw;
    }

}

遇到的问题

现在的情况是,代码能正常运行,也能生成比原文件短的处理后音频,但时间轴总是不对。举个例子:
原音频时长是01:06:53,我要裁剪掉120秒到240秒(也就是2分钟到4分钟的片段),按道理应该得到时长01:04:53的音频,但实际输出的音频时长是1:05:22,和预期不符。

更头疼的是,之前我明明得到过正确的结果,不确定是不是后来把文件路径改成wwwroot文件夹导致的问题。我试过很多种FFmpeg命令的变体,比如:

var arguments = $"-i {processFullAudioRequest.InputFilePath} -af {argument})' , asetpts=N/SR/TB\" -c:a libmp3lame -q:a 2  {outputFilePath}";

还有其他不少调整,但都记不清了,现在实在卡壳了,不知道问题出在哪。

有没有大佬能帮我看看?我尽量把细节都列出来了,如果还有需要补充的地方,随时告诉我。

备注:内容来源于stack exchange,提问作者badr2001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:39:31