VB.Net下用FFmpeg实现固定200秒视频的重复拼接裁剪方案咨询
Got it, let's tackle this problem step by step. Your current ffmpeg command only handles trimming a single clip—no looping involved, which is why you can't extend short videos to 200 seconds. Here's how to implement the loop-and-trim functionality properly in VB.NET:
First: Understand the Right FFmpeg Command
The key here is telling ffmpeg to loop your input video indefinitely, then trim the result to exactly 200 seconds. We can use the -stream_loop parameter for this, which is simpler than manual concat lists for most cases. The command looks like this:
ffmpeg -stream_loop -1 -i "input.m2ts" -t 200 -c copy -an -y "output.m2ts"
-stream_loop -1: Loops the input video infinitely-t 200: Trims the output to the first 200 seconds-c copy: Copies video streams directly (fast, no re-encoding)-an: Removes audio (matches your original command)-y: Overwrites the output file without prompting
Second: Add VB.NET Logic to Handle Both Short & Long Videos
We should first check if the original video is already longer than 200 seconds—if so, we just trim it instead of looping. Here's a complete code example:
Step 1: Helper Function to Get Video Duration
First, we need to fetch the original video's length to make our decision:
Imports System.Diagnostics Imports System.Text.RegularExpressions Imports System.IO Private Function GetVideoDuration(ffmpegPath As String, inputPath As String) As Double Dim psi As New ProcessStartInfo With { .FileName = ffmpegPath, .Arguments = $"-i ""{inputPath}""", .RedirectStandardError = True, .RedirectStandardOutput = True, .UseShellExecute = False, .CreateNoWindow = True } Using proc As Process = Process.Start(psi) Dim errorOutput As String = proc.StandardError.ReadToEnd() proc.WaitForExit() ' Parse the duration line from ffmpeg's output Dim durationMatch As Match = Regex.Match(errorOutput, "Duration: (\d{2}):(\d{2}):(\d{2}\.\d{2})") If durationMatch.Success Then Dim hours = Double.Parse(durationMatch.Groups(1).Value) Dim minutes = Double.Parse(durationMatch.Groups(2).Value) Dim seconds = Double.Parse(durationMatch.Groups(3).Value) Return hours * 3600 + minutes * 60 + seconds Else Return -1 ' Return -1 if duration can't be fetched End If End Using End Function
Step 2: Main Processing Logic
Now use that helper function to build the correct ffmpeg command and execute it:
Sub ProcessVideoTo200Seconds() Dim ffexe As String = "C:\path\to\your\ffmpeg.exe" Dim inf As String = "C:\path\to\your\input.m2ts" Dim ouF As String = "C:\path\to\your\output" Dim targetDuration As Double = 200.0 Dim videoLength As Double = GetVideoDuration(ffexe, inf) Dim cmd As String = "" If videoLength >= targetDuration Then ' Video is already long enough—just trim to 200s cmd = $"""{ffexe}"" -i ""{inf}"" -c copy -t {targetDuration} -an -y ""{ouF}.m2ts""" ElseIf videoLength > 0 Then ' Video is too short—loop infinitely then trim cmd = $"""{ffexe}"" -stream_loop -1 -i ""{inf}"" -t {targetDuration} -c copy -an -y ""{ouF}.m2ts""" Else Console.WriteLine("Failed to get video duration. Check input path or ffmpeg installation.") Return End If ' Execute the command Dim procStartInfo As New ProcessStartInfo("cmd.exe", "/c " & cmd) With { .UseShellExecute = False, .CreateNoWindow = True } Using proc As Process = Process.Start(procStartInfo) proc.WaitForExit() If proc.ExitCode = 0 Then Console.WriteLine("Video processed successfully! Output saved to " & ouF & ".m2ts") Else Console.WriteLine("Processing failed. Check your ffmpeg command and paths.") End If End Using End Sub
Fallback: Concat Demuxer (If -stream_loop Doesn't Work)
In rare cases, some video formats might not support -stream_loop. If that happens, use the concat demuxer instead:
- Generate a text file listing the input video multiple times (enough to exceed 200 seconds)
- Tell ffmpeg to concatenate those entries and trim to 200 seconds
Add this logic to the ElseIf videoLength > 0 block:
' Calculate how many times we need to repeat the video Dim repeatCount As Integer = Math.Ceiling(targetDuration / videoLength) Dim listPath As String = Path.Combine(Path.GetTempPath(), "video_list.txt") Dim listContent As String = "" For i As Integer = 0 To repeatCount - 1 listContent &= $"file '{inf}'{Environment.NewLine}" Next File.WriteAllText(listPath, listContent) cmd = $"""{ffexe}"" -f concat -safe 0 -i ""{listPath}"" -t {targetDuration} -c copy -an -y ""{ouF}.m2ts""" ' Clean up the temp list file after processing File.Delete(listPath)
Key Notes
- Always wrap file paths in double quotes (
"") to avoid errors with spaces in paths -c copyis fast, but if you get format compatibility issues, remove it to let ffmpeg re-encode (slower but more reliable)- Make sure ffmpeg is in your system PATH or use the full path to the executable
内容的提问来源于stack exchange,提问作者DVELPR

