2020-12-23 18:21:31 +01:00
using Flowframes.AudioVideo ;
using Flowframes.Data ;
2020-12-02 14:27:41 +01:00
using Flowframes.IO ;
2020-12-23 00:07:06 +01:00
using Flowframes.Main ;
2020-12-29 16:01:24 +01:00
using Flowframes.MiscUtils ;
2020-12-07 12:34:12 +01:00
using System ;
2021-01-16 02:30:46 +01:00
using System.Collections.Generic ;
2020-11-23 16:51:05 +01:00
using System.Drawing ;
using System.Globalization ;
using System.IO ;
2020-12-22 19:52:37 +01:00
using System.Linq ;
2020-11-23 16:51:05 +01:00
using System.Threading.Tasks ;
2021-02-01 16:23:35 +01:00
using static Flowframes . AvProcess ;
2020-12-23 16:13:04 +01:00
using Utils = Flowframes . AudioVideo . FFmpegUtils ;
2020-11-23 16:51:05 +01:00
namespace Flowframes
{
class FFmpegCommands
{
2021-02-01 16:23:35 +01:00
public static string divisionFilter = "\"pad=width=ceil(iw/2)*2:height=ceil(ih/2)*2:color=black@0\"" ;
public static string pngComprArg = "-compression_level 3" ;
public static string mpDecDef = "\"mpdecimate\"" ;
public static string mpDecAggr = "\"mpdecimate=hi=64*32:lo=64*32:frac=0.1\"" ;
2020-11-25 12:40:17 +01:00
2021-01-06 17:41:18 +01:00
public static async Task ConcatVideos ( string concatFile , string outPath , int looptimes = - 1 )
2020-11-30 02:14:04 +01:00
{
2021-01-06 21:44:09 +01:00
Logger . Log ( $"Merging videos..." , false , Logger . GetLastLine ( ) . Contains ( "frame" ) ) ;
2020-11-30 02:14:04 +01:00
string loopStr = ( looptimes > 0 ) ? $"-stream_loop {looptimes}" : "" ;
2020-11-30 20:32:33 +01:00
string vfrFilename = Path . GetFileName ( concatFile ) ;
2021-01-06 21:47:25 +01:00
string args = $" {loopStr} -vsync 1 -f concat -i {vfrFilename} -c copy -movflags +faststart {outPath.Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , concatFile . GetParentDir ( ) , LogMode . Hidden , TaskType . Merge ) ;
2020-11-30 02:14:04 +01:00
}
2021-02-01 14:50:08 +01:00
public static async Task FramesToGifConcat ( string framesFile , string outPath , float fps , bool palette , int colors = 64 , float resampleFps = - 1 , LogMode logMode = LogMode . OnlyLastLine )
2020-12-08 14:43:03 +01:00
{
2021-02-01 14:50:08 +01:00
if ( logMode ! = LogMode . Hidden )
2021-01-06 17:41:18 +01:00
Logger . Log ( ( resampleFps < = 0 ) ? $"Encoding GIF..." : $"Encoding GIF resampled to {resampleFps.ToString().Replace(" , ", " . ")} FPS..." ) ;
2020-12-08 14:43:03 +01:00
string vfrFilename = Path . GetFileName ( framesFile ) ;
2021-01-06 17:41:18 +01:00
string paletteFilter = palette ? $"-vf \" split [ s0 ] [ s1 ] ; [ s0 ] palettegen = { colors } [ p ] ; [ s1 ] [ p ] paletteuse = dither = floyd_steinberg : diff_mode = rectangle \ "" : "" ;
string fpsFilter = ( resampleFps < = 0 ) ? "" : $"fps=fps={resampleFps.ToStringDot()}" ;
string vf = FormatUtils . ConcatStrings ( new string [ ] { paletteFilter , fpsFilter } ) ;
string rate = fps . ToStringDot ( ) ;
string args = $"-loglevel error -f concat -r {rate} -i {vfrFilename.Wrap()} -f gif {vf} {outPath.Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , framesFile . GetParentDir ( ) , LogMode . OnlyLastLine , TaskType . Encode ) ;
2020-12-08 14:43:03 +01:00
}
2021-01-30 13:14:57 +01:00
public static async Task ExtractAlphaDir ( string rgbDir , string alphaDir )
{
Directory . CreateDirectory ( alphaDir ) ;
foreach ( FileInfo file in IOUtils . GetFileInfosSorted ( rgbDir ) )
{
string args = $"-i {file.FullName.Wrap()} -vf format=yuva444p16le,alphaextract,format=yuv420p {Path.Combine(alphaDir, file.Name).Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
2021-01-30 13:14:57 +01:00
}
}
public static async Task RemoveAlpha ( string inputDir , string outputDir , string fillColor = "black" )
{
Directory . CreateDirectory ( outputDir ) ;
foreach ( FileInfo file in IOUtils . GetFileInfosSorted ( inputDir ) )
{
string outFilename = Path . Combine ( outputDir , "_" + file . Name ) ;
Size res = IOUtils . GetImage ( file . FullName ) . Size ;
string args = $" -f lavfi -i color={fillColor}:s={res.Width}x{res.Height} -i {file.FullName.Wrap()} " +
$"-filter_complex overlay=0:0:shortest=1 -pix_fmt rgb24 {outFilename.Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
2021-01-30 13:14:57 +01:00
file . Delete ( ) ;
File . Move ( outFilename , file . FullName ) ;
}
}
2021-01-27 21:05:49 +01:00
public static async Task MergeAlphaIntoRgb ( string rgbDir , int rgbPad , string alphaDir , int aPad , bool deleteAlphaDir )
2020-11-23 16:51:05 +01:00
{
2021-01-18 15:32:45 +01:00
string filter = "-filter_complex [0:v:0][1:v:0]alphamerge[out] -map [out]" ;
string args = $"-i \" { rgbDir } / % { rgbPad } d . png \ " -i \"{alphaDir}/%{aPad}d.png\" {filter} \"{rgbDir}/%{rgbPad}d.png\"" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
2021-01-27 21:05:49 +01:00
if ( deleteAlphaDir )
IOUtils . TryDeleteIfExists ( alphaDir ) ;
2020-11-23 16:51:05 +01:00
}
2021-01-18 15:32:45 +01:00
public static async Task LoopVideo ( string inputFile , int times , bool delSrc = false )
2020-11-23 16:51:05 +01:00
{
string pathNoExt = Path . ChangeExtension ( inputFile , null ) ;
string ext = Path . GetExtension ( inputFile ) ;
2021-01-18 15:32:45 +01:00
string args = $" -stream_loop {times} -i {inputFile.Wrap()} -c copy \" { pathNoExt } - Loop { times } { ext } \ "" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
2020-11-23 16:51:05 +01:00
if ( delSrc )
DeleteSource ( inputFile ) ;
}
2020-12-15 14:46:33 +01:00
public static async Task ChangeSpeed ( string inputFile , float newSpeedPercent , bool delSrc = false )
2020-11-23 16:51:05 +01:00
{
string pathNoExt = Path . ChangeExtension ( inputFile , null ) ;
string ext = Path . GetExtension ( inputFile ) ;
float val = newSpeedPercent / 100f ;
string speedVal = ( 1f / val ) . ToString ( "0.0000" ) . Replace ( "," , "." ) ;
string args = " -itsscale " + speedVal + " -i \"" + inputFile + "\" -c copy \"" + pathNoExt + "-" + newSpeedPercent + "pcSpeed" + ext + "\"" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . OnlyLastLine ) ;
2020-11-23 16:51:05 +01:00
if ( delSrc )
DeleteSource ( inputFile ) ;
}
2020-12-15 14:46:33 +01:00
public static async Task ExtractAudio ( string inputFile , string outFile ) // https://stackoverflow.com/a/27413824/14274419
2020-11-23 16:51:05 +01:00
{
2021-01-15 22:43:13 +01:00
string audioExt = Utils . GetAudioExt ( inputFile ) ;
outFile = Path . ChangeExtension ( outFile , audioExt ) ;
2020-11-23 16:51:05 +01:00
Logger . Log ( $"[FFCmds] Extracting audio from {inputFile} to {outFile}" , true ) ;
2021-01-15 22:43:13 +01:00
string args = $" -loglevel panic -i {inputFile.Wrap()} -vn -c:a copy {outFile.Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
2021-01-15 22:43:13 +01:00
if ( File . Exists ( outFile ) & & IOUtils . GetFilesize ( outFile ) < 512 )
{
Logger . Log ( "Failed to extract audio losslessly! Trying to re-encode." ) ;
2020-11-23 16:51:05 +01:00
File . Delete ( outFile ) ;
2021-01-15 22:43:13 +01:00
outFile = Path . ChangeExtension ( outFile , Utils . GetAudioExtForContainer ( Path . GetExtension ( inputFile ) ) ) ;
args = $" -loglevel panic -i {inputFile.Wrap()} -vn {Utils.GetAudioFallbackArgs(Path.GetExtension(inputFile))} {outFile.Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
2021-01-15 22:43:13 +01:00
2021-02-01 16:23:35 +01:00
if ( ( File . Exists ( outFile ) & & IOUtils . GetFilesize ( outFile ) < 512 ) | | lastOutputFfmpeg . Contains ( "Invalid data" ) )
2021-01-15 22:43:13 +01:00
{
Logger . Log ( "Failed to extract audio, even with re-encoding. Output will not have audio." ) ;
IOUtils . TryDeleteIfExists ( outFile ) ;
return ;
}
Logger . Log ( $"Source audio has been re-encoded as it can't be extracted losslessly. This may decrease the quality slightly." , false , true ) ;
}
2020-11-23 16:51:05 +01:00
}
2021-01-16 14:42:47 +01:00
public static async Task ExtractSubtitles ( string inputFile , string outFolder , Interpolate . OutMode outMode )
2021-01-16 01:49:10 +01:00
{
2021-02-01 14:50:08 +01:00
Dictionary < int , string > subtitleTracks = await GetSubtitleTracks ( inputFile ) ;
foreach ( KeyValuePair < int , string > subTrack in subtitleTracks )
2021-01-16 01:49:10 +01:00
{
2021-01-16 02:30:46 +01:00
string trackName = subTrack . Value . Length > 4 ? CultureInfo . CurrentCulture . TextInfo . ToTitleCase ( subTrack . Value . ToLower ( ) ) : subTrack . Value . ToUpper ( ) ;
string outPath = Path . Combine ( outFolder , $"{subTrack.Key}-{trackName}.srt" ) ;
string args = $" -loglevel error -i {inputFile.Wrap()} -map 0:s:{subTrack.Key} {outPath.Wrap()}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , LogMode . Hidden ) ;
if ( lastOutputFfmpeg . Contains ( "matches no streams" ) ) // Break if there are no more subtitle tracks
2021-01-16 01:49:10 +01:00
break ;
2021-01-16 14:42:47 +01:00
Logger . Log ( $"[FFCmds] Extracted subtitle track {subTrack.Key} to {outPath} ({FormatUtils.Bytes(IOUtils.GetFilesize(outPath))})" , true , false , "ffmpeg" ) ;
2021-01-16 01:49:10 +01:00
}
2021-02-01 14:50:08 +01:00
if ( subtitleTracks . Count > 0 )
2021-01-16 14:42:47 +01:00
{
2021-02-01 14:50:08 +01:00
Logger . Log ( $"Extracted {subtitleTracks.Count} subtitle tracks from the input video." ) ;
2021-01-16 14:42:47 +01:00
Utils . ContainerSupportsSubs ( Utils . GetExt ( outMode ) , true ) ;
}
2021-01-16 02:30:46 +01:00
}
public static async Task < Dictionary < int , string > > GetSubtitleTracks ( string inputFile )
{
Dictionary < int , string > subDict = new Dictionary < int , string > ( ) ;
string args = $"-i {inputFile.Wrap()}" ;
2021-02-01 16:23:35 +01:00
string [ ] outputLines = ( await GetFfmpegOutputAsync ( args ) ) . SplitIntoLines ( ) ;
2021-01-16 02:30:46 +01:00
string [ ] filteredLines = outputLines . Where ( l = > l . Contains ( " Subtitle: " ) ) . ToArray ( ) ;
int idx = 0 ;
foreach ( string line in filteredLines )
{
string lang = "unknown" ;
bool hasLangInfo = line . Contains ( "(" ) & & line . Contains ( "): Subtitle: " ) ;
if ( hasLangInfo )
lang = line . Split ( '(' ) [ 1 ] . Split ( ')' ) [ 0 ] ;
subDict . Add ( idx , lang ) ;
idx + + ;
}
return subDict ;
2021-01-16 01:49:10 +01:00
}
2021-01-16 14:42:47 +01:00
public static async Task MergeAudioAndSubs ( string inputFile , string audioPath , string tempFolder , int looptimes = - 1 ) // https://superuser.com/a/277667
2020-11-23 16:51:05 +01:00
{
Logger . Log ( $"[FFCmds] Merging audio from {audioPath} into {inputFile}" , true ) ;
2021-01-16 14:42:47 +01:00
string containerExt = Path . GetExtension ( inputFile ) ;
string tempPath = Path . Combine ( tempFolder , $"vid{containerExt}" ) ; // inputFile + "-temp" + Path.GetExtension(inputFile);
string outPath = Path . Combine ( tempFolder , $"muxed{containerExt}" ) ; // inputFile + "-temp" + Path.GetExtension(inputFile);
File . Move ( inputFile , tempPath ) ;
string inName = Path . GetFileName ( tempPath ) ;
string audioName = Path . GetFileName ( audioPath ) ;
string outName = Path . GetFileName ( outPath ) ;
bool subs = Utils . ContainerSupportsSubs ( containerExt , false ) & & Config . GetBool ( "keepSubs" ) ;
string subInputArgs = "" ;
string subMapArgs = "" ;
string subMetaArgs = "" ;
string [ ] subTracks = subs ? IOUtils . GetFilesSorted ( tempFolder , false , "*.srt" ) : new string [ 0 ] ;
2021-02-01 14:50:08 +01:00
2021-01-16 14:42:47 +01:00
for ( int subTrack = 0 ; subTrack < subTracks . Length ; subTrack + + )
2020-11-23 16:51:05 +01:00
{
2021-01-16 14:42:47 +01:00
subInputArgs + = $" -i {Path.GetFileName(subTracks[subTrack])}" ;
subMapArgs + = $" -map {subTrack+2}" ;
subMetaArgs + = $" -metadata:s:s:{subTrack} language={Path.GetFileNameWithoutExtension(subTracks[subTrack]).Split('-').Last()}" ;
}
2021-01-15 22:43:13 +01:00
2021-01-16 14:42:47 +01:00
string subCodec = Utils . GetSubCodecForContainer ( containerExt ) ;
string args = $" -i {inName} -stream_loop {looptimes} -i {audioName.Wrap()}" +
$"{subInputArgs} -map 0:v -map 1:a {subMapArgs} -c:v copy -c:a copy -c:s {subCodec} {subMetaArgs} -shortest {outName}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , tempFolder , LogMode . Hidden ) ;
2021-01-15 22:43:13 +01:00
2021-02-01 16:23:35 +01:00
if ( ( File . Exists ( outPath ) & & IOUtils . GetFilesize ( outPath ) < 1024 ) | | lastOutputFfmpeg . Contains ( "Invalid data" ) | | lastOutputFfmpeg . Contains ( "Error initializing output stream" ) )
2021-01-16 14:42:47 +01:00
{
Logger . Log ( "Failed to merge audio losslessly! Trying to re-encode." , false , false , "ffmpeg" ) ;
args = $" -i {inName} -stream_loop {looptimes} -i {audioName.Wrap()}" +
$"{subInputArgs} -map 0:v -map 1:a {subMapArgs} -c:v copy {Utils.GetAudioFallbackArgs(Path.GetExtension(inputFile))} -c:s {subCodec} {subMetaArgs} -shortest {outName}" ;
2021-02-01 16:23:35 +01:00
await RunFfmpeg ( args , tempFolder , LogMode . Hidden ) ;
2021-01-16 14:42:47 +01:00
2021-02-01 16:23:35 +01:00
if ( ( File . Exists ( outPath ) & & IOUtils . GetFilesize ( outPath ) < 1024 ) | | lastOutputFfmpeg . Contains ( "Invalid data" ) | | lastOutputFfmpeg . Contains ( "Error initializing output stream" ) )
2021-01-15 22:43:13 +01:00
{
2021-01-16 14:42:47 +01:00
Logger . Log ( "Failed to merge audio, even with re-encoding. Output will not have audio." , false , false , "ffmpeg" ) ;
2021-01-15 22:43:13 +01:00
IOUtils . TryDeleteIfExists ( tempPath ) ;
return ;
}
string audioExt = Path . GetExtension ( audioPath ) . Remove ( "." ) . ToUpper ( ) ;
2021-01-16 14:42:47 +01:00
Logger . Log ( $"Source audio ({audioExt}) has been re-encoded to fit into the target container ({containerExt.Remove(" . ").ToUpper()}). This may decrease the quality slightly." , false , true , "ffmpeg" ) ;
}
if ( File . Exists ( outPath ) & & IOUtils . GetFilesize ( outPath ) > 512 )
{
File . Delete ( tempPath ) ;
File . Move ( outPath , inputFile ) ;
}
else
{
File . Move ( tempPath , inputFile ) ;
2020-11-23 16:51:05 +01:00
}
}
2021-01-30 13:09:59 +01:00
public static long GetDuration ( string inputFile )
{
Logger . Log ( "Reading Duration using ffprobe." , true , false , "ffprobe" ) ;
string args = $" -v panic -select_streams v:0 -show_entries format=duration -of csv=s=x:p=0 -sexagesimal {inputFile.Wrap()}" ;
2021-02-01 16:23:35 +01:00
string info = GetFfprobeOutput ( args ) ;
2021-01-30 13:09:59 +01:00
return FormatUtils . MsFromTimestamp ( info ) ;
return - 1 ;
}
2020-12-15 14:46:33 +01:00
public static float GetFramerate ( string inputFile )
2020-11-23 16:51:05 +01:00
{
2020-12-27 22:52:14 +01:00
Logger . Log ( "Reading FPS using ffmpeg." , true , false , "ffmpeg" ) ;
2020-11-23 16:51:05 +01:00
string args = $" -i {inputFile.Wrap()}" ;
2021-02-01 16:23:35 +01:00
string output = GetFfmpegOutput ( args ) ;
2020-11-23 18:08:17 +01:00
string [ ] entries = output . Split ( ',' ) ;
2020-12-15 14:46:33 +01:00
foreach ( string entry in entries )
2020-11-23 16:51:05 +01:00
{
2020-11-23 18:08:17 +01:00
if ( entry . Contains ( " fps" ) & & ! entry . Contains ( "Input " ) ) // Avoid reading FPS from the filename, in case filename contains "fps"
2020-11-23 16:51:05 +01:00
{
Logger . Log ( "[FFCmds] FPS Entry: " + entry , true ) ;
string num = entry . Replace ( " fps" , "" ) . Trim ( ) . Replace ( "," , "." ) ;
float value ;
float . TryParse ( num , NumberStyles . Any , CultureInfo . InvariantCulture , out value ) ;
return value ;
}
}
return 0f ;
}
2020-12-15 14:46:33 +01:00
public static Size GetSize ( string inputFile )
2020-11-23 16:51:05 +01:00
{
2021-01-08 20:16:40 +01:00
string args = $" -v panic -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 {inputFile.Wrap()}" ;
2021-02-01 16:23:35 +01:00
string output = GetFfprobeOutput ( args ) ;
2020-11-23 16:51:05 +01:00
if ( output . Length > 4 & & output . Contains ( "x" ) )
{
string [ ] numbers = output . Split ( 'x' ) ;
return new Size ( numbers [ 0 ] . GetInt ( ) , numbers [ 1 ] . GetInt ( ) ) ;
}
return new Size ( 0 , 0 ) ;
}
public static int GetFrameCount ( string inputFile )
{
int frames = 0 ;
2020-12-27 22:52:14 +01:00
Logger . Log ( "Reading frame count using ffprobe." , true , false , "ffmpeg" ) ;
2020-11-23 16:51:05 +01:00
frames = ReadFrameCountFfprobe ( inputFile , Config . GetBool ( "ffprobeCountFrames" ) ) ; // Try reading frame count with ffprobe
if ( frames > 0 )
return frames ;
2020-12-27 22:52:14 +01:00
Logger . Log ( $"Failed to get frame count using ffprobe (frames = {frames}). Reading frame count using ffmpeg." , true , false , "ffmpeg" ) ;
2020-11-23 16:51:05 +01:00
frames = ReadFrameCountFfmpeg ( inputFile ) ; // Try reading frame count with ffmpeg
if ( frames > 0 )
return frames ;
Logger . Log ( "Failed to get total frame count of video." ) ;
return 0 ;
}
2020-12-27 22:52:14 +01:00
public static async Task < int > GetFrameCountAsync ( string inputFile )
{
int frames = 0 ;
Logger . Log ( "Reading frame count using ffprobe." , true , false , "ffmpeg" ) ;
frames = await ReadFrameCountFfprobeAsync ( inputFile , Config . GetBool ( "ffprobeCountFrames" ) ) ; // Try reading frame count with ffprobe
if ( frames > 0 )
return frames ;
Logger . Log ( $"Failed to get frame count using ffprobe (frames = {frames}). Reading frame count using ffmpeg." , true , false , "ffmpeg" ) ;
frames = await ReadFrameCountFfmpegAsync ( inputFile ) ; // Try reading frame count with ffmpeg
if ( frames > 0 )
return frames ;
Logger . Log ( "Failed to get total frame count of video." ) ;
return 0 ;
}
2020-12-15 14:46:33 +01:00
static int ReadFrameCountFfprobe ( string inputFile , bool readFramesSlow )
2020-11-23 16:51:05 +01:00
{
string args = $" -v panic -select_streams v:0 -show_entries stream=nb_frames -of default=noprint_wrappers=1 {inputFile.Wrap()}" ;
if ( readFramesSlow )
{
Logger . Log ( "Counting total frames using FFprobe. This can take a moment..." ) ;
args = $" -v panic -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 {inputFile.Wrap()}" ;
}
2021-02-01 16:23:35 +01:00
string info = GetFfprobeOutput ( args ) ;
2020-11-23 16:51:05 +01:00
string [ ] entries = info . SplitIntoLines ( ) ;
try
{
if ( readFramesSlow )
return info . GetInt ( ) ;
foreach ( string entry in entries )
{
if ( entry . Contains ( "nb_frames=" ) )
return entry . GetInt ( ) ;
2020-12-27 22:52:14 +01:00
}
}
catch { }
return - 1 ;
}
static async Task < int > ReadFrameCountFfprobeAsync ( string inputFile , bool readFramesSlow )
{
string args = $" -v panic -select_streams v:0 -show_entries stream=nb_frames -of default=noprint_wrappers=1 {inputFile.Wrap()}" ;
if ( readFramesSlow )
{
Logger . Log ( "Counting total frames using FFprobe. This can take a moment..." ) ;
await Task . Delay ( 10 ) ;
args = $" -v panic -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 {inputFile.Wrap()}" ;
}
2021-02-01 16:23:35 +01:00
string info = GetFfprobeOutput ( args ) ;
2020-12-27 22:52:14 +01:00
string [ ] entries = info . SplitIntoLines ( ) ;
try
{
if ( readFramesSlow )
return info . GetInt ( ) ;
foreach ( string entry in entries )
{
if ( entry . Contains ( "nb_frames=" ) )
return entry . GetInt ( ) ;
2020-11-23 16:51:05 +01:00
}
}
catch { }
return - 1 ;
}
static int ReadFrameCountFfmpeg ( string inputFile )
{
string args = $" -loglevel panic -i {inputFile.Wrap()} -map 0:v:0 -c copy -f null - " ;
2021-02-01 16:23:35 +01:00
string info = GetFfmpegOutput ( args ) ;
2020-11-23 16:51:05 +01:00
string [ ] entries = info . SplitIntoLines ( ) ;
foreach ( string entry in entries )
{
if ( entry . Contains ( "frame=" ) )
return entry . Substring ( 0 , entry . IndexOf ( "fps" ) ) . GetInt ( ) ;
}
return - 1 ;
}
2020-12-27 22:52:14 +01:00
static async Task < int > ReadFrameCountFfmpegAsync ( string inputFile )
{
string args = $" -loglevel panic -i {inputFile.Wrap()} -map 0:v:0 -c copy -f null - " ;
2021-02-01 16:23:35 +01:00
string info = await GetFfmpegOutputAsync ( args , true ) ;
2020-12-27 22:52:14 +01:00
try
{
string [ ] lines = info . SplitIntoLines ( ) ;
string lastLine = lines . Last ( ) ;
return lastLine . Substring ( 0 , lastLine . IndexOf ( "fps" ) ) . GetInt ( ) ;
}
catch
{
return - 1 ;
}
}
2020-12-25 00:39:14 +01:00
public static string GetAudioCodec ( string path )
2020-11-23 16:51:05 +01:00
{
string args = $" -v panic -show_streams -select_streams a -show_entries stream=codec_name {path.Wrap()}" ;
2021-02-01 16:23:35 +01:00
string info = GetFfprobeOutput ( args ) ;
2020-11-23 16:51:05 +01:00
string [ ] entries = info . SplitIntoLines ( ) ;
foreach ( string entry in entries )
{
if ( entry . Contains ( "codec_name=" ) )
return entry . Split ( '=' ) [ 1 ] ;
}
return "" ;
}
2021-02-01 16:23:35 +01:00
public static void DeleteSource ( string path )
2020-11-23 16:51:05 +01:00
{
2020-11-30 02:14:04 +01:00
Logger . Log ( "[FFCmds] Deleting input file/dir: " + path , true ) ;
2020-11-23 16:51:05 +01:00
if ( IOUtils . IsPathDirectory ( path ) & & Directory . Exists ( path ) )
Directory . Delete ( path , true ) ;
if ( ! IOUtils . IsPathDirectory ( path ) & & File . Exists ( path ) )
File . Delete ( path ) ;
}
}
}