Files
flowframes/Code/Media/GetVideoInfoCached.cs

85 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Flowframes.Data;
using Flowframes.IO;
using Flowframes.OS;
namespace Flowframes.Media
{
class GetVideoInfoCached
{
enum InfoType { Ffmpeg, Ffprobe };
static Dictionary<PseudoUniqueFile, string> ffmpegCache = new Dictionary<PseudoUniqueFile, string>();
static Dictionary<PseudoUniqueFile, string> ffprobeCache = new Dictionary<PseudoUniqueFile, string>();
public static async Task<string> GetFfmpegInfoAsync(string path, string lineFilter = "")
{
return await GetInfoAsync(path, InfoType.Ffmpeg, lineFilter);
}
public static async Task<string> GetFfprobeInfoAsync(string path, string lineFilter = "")
{
return await GetInfoAsync(path, InfoType.Ffprobe, lineFilter);
}
static async Task<string> GetInfoAsync(string path, InfoType type, string lineFilter)
{
Logger.Log($"Get{type}InfoAsync({path})", true);
Dictionary<PseudoUniqueFile, string> cacheDict = new Dictionary<PseudoUniqueFile, string>(type == InfoType.Ffmpeg ? ffmpegCache : ffprobeCache);
long filesize = IOUtils.GetFilesize(path);
PseudoUniqueFile hash = new PseudoUniqueFile(path, filesize);
if (filesize > 0 && CacheContains(hash, ref cacheDict))
{
Logger.Log($"Returning cached {type} info.", true);
return GetFromCache(hash, ref cacheDict);
}
Process process = OSUtils.NewProcess(true);
string avPath = Path.Combine(Paths.GetPkgPath(), Paths.audioVideoDir);
if(type == InfoType.Ffmpeg)
process.StartInfo.Arguments = $"/C cd /D {avPath.Wrap()} & ffmpeg.exe -hide_banner -y -stats -i {path.Wrap()}";
if (type == InfoType.Ffprobe)
process.StartInfo.Arguments = $"/C cd /D {avPath.Wrap()} & ffprobe -v quiet -show_format -show_streams {path.Wrap()}";
string output = await OSUtils.GetOutputAsync(process);
if (type == InfoType.Ffmpeg)
ffmpegCache.Add(hash, output);
if (type == InfoType.Ffprobe)
ffprobeCache.Add(hash, output);
if (!string.IsNullOrWhiteSpace(lineFilter.Trim()))
output = string.Join("\n", output.SplitIntoLines().Where(x => x.Contains(lineFilter)).ToArray());
return output;
}
private static bool CacheContains(PseudoUniqueFile hash, ref Dictionary<PseudoUniqueFile, string> cacheDict)
{
foreach (KeyValuePair<PseudoUniqueFile, string> entry in cacheDict)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return true;
return false;
}
private static string GetFromCache(PseudoUniqueFile hash, ref Dictionary<PseudoUniqueFile, string> cacheDict)
{
foreach (KeyValuePair<PseudoUniqueFile, string> entry in cacheDict)
if (entry.Key.path == hash.path && entry.Key.filesize == hash.filesize)
return entry.Value;
return "";
}
}
}