static void ProcessFolder(string folder) { // output each trigger and which footage files that contain it // output lists of footage folders in chronological order // output list of everything in chronological order var triggers = new List <Trigger>(); var footageList = new Dictionary <string, IList <Footage> >(); foreach (var d in Directory.EnumerateDirectories(folder)) { Console.WriteLine(d); if (d.Contains("iPhone")) { // load triggers foreach (var f in (new DirectoryInfo(d)).EnumerateFiles()) { if (f.Extension.ToUpper() == ".JPG") { var pu = new RandomWayfarer.Pictures.PictureUtils(); var pic = pu.GetJpegPicture(f.FullName); if (pic != null) { triggers.Add(new Trigger { CreateDate = pic.DateTime, FileName = f.FullName }); } else { Console.WriteLine($"Invalid {f.FullName}"); } } else if (f.Extension.ToUpper() == ".MOV") { var v = GetInfo(f.FullName); var s = v.streams.Where(vv => vv.codec_type == "video").First(); var cd = s.Tags["creation_time"]; triggers.Add(new Trigger { FileName = f.FullName, CreateDate = Convert.ToDateTime(cd) }); } } } else { var footage = new List <Footage>(); var ff = Path.GetFullPath(d); var footageSourceName = ff.Split('\\').Reverse().First(); footageList.Add(footageSourceName, footage); // load footage files foreach (var f in (new DirectoryInfo(d)).EnumerateFiles()) { var v = GetInfo(f.FullName); var s = v.streams?.Where(vv => vv.codec_type == "video").FirstOrDefault(); if (s != null) { var cd = s.Tags["creation_time"]; footage.Add(new Footage { FileName = f.FullName, CreateDate = Convert.ToDateTime(cd).AddHours(5), // TODO TZ : I punted on timezone Duration = s.duration }); } else { Console.WriteLine($"INVALID : {f.FullName}"); } } } } foreach (var trig in triggers) { foreach (var foot in footageList) { foreach (var x in foot.Value) { trig.CheckAddFootage(foot.Key, x); } } } var sb = new StringBuilder(); foreach (var f in footageList.First().Value.OrderBy(ff => ff.CreateDate)) { sb.AppendLine($"{f.FileName} : {f.CreateDate} + {f.Duration} = {f.EndDate}"); } foreach (var trig in triggers) { sb.AppendLine($"{trig.FileName} : {trig.CreateDate}"); if (trig.Footage.Count > 0) { foreach (var f in trig.Footage.First().Value.OrderBy(ff => ff.CreateDate)) { sb.AppendLine($"{f.FileName} : {f.CreateDate} + {f.Duration} = {f.EndDate}"); } } } var footageListFileName = Path.Combine(folder, $"footage{DateTime.Now.Ticks}.txt"); File.WriteAllText(footageListFileName, sb.ToString()); }
static void ProcessFolder(string folder) { // output each trigger and which footage files that contain it // output lists of footage folders in chronological order // output list of everything in chronological order var triggers = new List <Trigger>(); var footageList = new Dictionary <string, IList <Footage> >(); var clipList = new List <Clip>(); var combineComps = new List <string>(); foreach (var d in Directory.EnumerateDirectories(folder)) { Console.WriteLine(d); if (d.Contains("iPhone") || d.Contains("Android")) { // load triggers foreach (var f in (new DirectoryInfo(d)).EnumerateFiles()) { if (f.Extension.ToUpper() == ".JPG") { var pu = new RandomWayfarer.Pictures.PictureUtils(); var pic = pu.GetJpegPicture(f.FullName); if (pic != null) { triggers.Add(new Trigger { CreateDate = pic.DateTime, FileName = f.FullName }); } else { Console.WriteLine($"Invalid {f.FullName}"); } } else if (f.Extension.ToUpper() == ".MOV") { var v = GetInfo(f.FullName); var s = v.streams.Where(vv => vv.codec_type == "video").First(); var cd = s.Tags["creation_time"]; triggers.Add(new Trigger { FileName = f.FullName, CreateDate = Convert.ToDateTime(cd) }); } } } else { var footage = new List <Footage>(); var ff = Path.GetFullPath(d); var footageSourceName = ff.Split('\\').Reverse().First(); footageList.Add(footageSourceName, footage); // load footage files foreach (var ext in new string[] { "*.mp4", "*.avi", "*.mov" }) { foreach (var f in (new DirectoryInfo(d)).EnumerateFiles(ext))//.mp4 { var foot = Footage.Factory(f); if (foot != null) { footage.Add(foot); } else { Console.WriteLine($"INVALID : {f.FullName}"); } } } } } //each camera for a single trigger makes a "clip." clips can be made of multiple vids foreach (var trig in triggers) { trig.ParamStart = trig.CreateDate - new TimeSpan(0, 0, before); trig.ParamEnd = trig.CreateDate + new TimeSpan(0, 0, after); foreach (var camera in footageList) { var clip = new Clip { InitTrigger = trig, CameraName = camera.Key, OutputName = "output", StartTime = trig.ParamStart, EndTime = trig.ParamEnd, NecessaryFiles = new List <Footage>() }; foreach (var vid in camera.Value) { if (vid.Contains(clip.StartTime) || vid.Contains(clip.EndTime)) { clip.NecessaryFiles.Add(vid); } else if (clip.Contains(vid.CreateDate)) { clip.NecessaryFiles.Add(vid); } } if (clip.NecessaryFiles.Count > 0) { clipList.Add(clip); } } } //makes each clip from source footage, 2 files if necessary, might work with 3+, does it need to? var clipNum = 0; foreach (var clip in clipList) { string endOutput = ""; clipNum++; clip.SplitParameters = new SplitParameters( clip.NecessaryFiles.FirstOrDefault().FileName, ((clip.InitTrigger.CreateDate - clip.NecessaryFiles.FirstOrDefault().CreateDate) - tsBefore), tsBefore + tsAfter, $"( {clipNum.ToString()} )" + clip.InitTrigger.OutputPrefix + clip.CameraName ); if (clip.NecessaryFiles.Count == 1) { endOutput = Split(clip.SplitParameters); } else if (clip.NecessaryFiles.Count == 0) { //delete clip } else { int fileNum = 0; foreach (var vid in clip.NecessaryFiles) { fileNum++; vid.SplitParameters = new SplitParameters( vid.FileName, ((clip.InitTrigger.CreateDate - vid.CreateDate) - tsBefore), tsBefore + tsAfter, $"( {fileNum.ToString()} )" + vid.OutputPrefix ); if (vid.Contains(clip.InitTrigger.ParamStart)) { vid.SplitParameters.Duration = vid.EndDate - clip.InitTrigger.ParamStart; } if (vid.Contains(clip.InitTrigger.ParamEnd)) { if (vid.Contains(clip.InitTrigger.ParamStart)) /*error I don't think this should happen */ Console {