public frmTool(Tool tool, bool autoCloseOnSuccess) { InitializeComponent(); this.Icon = Program.Icon; this._tool = tool; this._tool.Started += this.ToolStarted; this._tool.StdOutReceived += this.ToolStdOutReceived; this._tool.StdErrReceived += this.ToolStdErrReceived; this._tool.Completed += this.ToolCompleted; this.rtbOutput.WordWrap = this.chkWordWrap.Checked = MediaData.Properties.Settings.Default.ToolWordWrap; this.RunState = RunStates.WarmUp; this._autoCloseOnSuccess = autoCloseOnSuccess; }
protected Exception RunTool(MediaInfo newInfo, Tool tool, ShowProcessingOutput spo, string tempFilename, IWin32Window parentWindow, string finalFilename) { Exception result = null; try { bool gui; switch (spo.Shown) { case ShowProcessingOutput.When.Always: gui = true; break; case ShowProcessingOutput.When.BiggerThan: gui = (Convert.ToUInt64((new FileInfo(this.FullFilename)).Length) >= spo.BiggerThanThisBytes) ? true : false; break; case ShowProcessingOutput.When.Never: default: gui = false; break; } if (gui) { result = tool.RunGUI(parentWindow, spo.AutocloseOnSuccess).Error; } else { result = tool.Run().Error; } if (result == null) { MediaInfo updatedInfo = this.GetInfo(tempFilename); if (!updatedInfo.CheckUpdatedInfo(this.Info, newInfo)) { result = new UnableToSetNewMetadataException(); } else { if (MediaData.Properties.Settings.Default.DeleteToTrash) { MyIO.DeleteToTrash(this.FullFilename); } else { File.Delete(this.FullFilename); } File.Move(tempFilename, finalFilename); this._info = updatedInfo; } } } catch (Exception x) { result = x; } return result; }
protected Exception RunTool(MediaInfo newInfo, Tool tool, ShowProcessingOutput spo, string tempFilename, IWin32Window parentWindow) { return this.RunTool(newInfo, tool, spo, tempFilename, parentWindow, this.FullFilename); }
protected override MediaInfo GetInfo(string fullFilename) { VideoInfo result = new VideoInfo(); Tool tool = new Tool(Tool.Which.FFprobe, new string[] { "-hide_banner", "-print_format xml=fully_qualified=1", "-show_format", "-show_streams", "-show_error", Tool.Escape(fullFilename) }, new int[] { 0 }); Tool.Result toolResult = tool.Run(); if (toolResult.Error != null) { throw toolResult.Error; } FFprobe.ffprobeType ffp; using (MemoryStream ms = new MemoryStream()) { byte[] bytes = System.Text.Encoding.UTF8.GetBytes(toolResult.StdOut); ms.Write(bytes, 0, bytes.Length); ms.Position = 0L; using (XmlReader xr = XmlReader.Create(ms)) { ffp = (MediaData.FFprobe.ffprobeType)FFmpegVideoProcessor.FFProbeDeserializer.Deserialize(xr); } } if (ffp.error != null) { throw new Exception(ffp.error.@string); } if (ffp.format.tag != null) { foreach (FFprobe.tagType tag in ffp.format.tag) { switch (tag.key) { case "creation_time": DateTime? dt = FFmpegVideoProcessor.ParseCreationTimeTag(tag.value); if (!dt.HasValue) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, tag.key, tag.value)); } result.AddAlternativeMetadataTimestamp(string.Format(i18n.GlobalTag_X, tag.key), dt.Value); break; case "location": case "location-eng": Position position = FFmpegVideoProcessor.ParseLocationTag(tag.value); if (position == null) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, tag.key, tag.value)); } if (result.Position == null || (result.Position.Lat == 0M && result.Position.Lng == 0M)) { result.Position = position; } else if (position.Lat != 0M && position.Lng != 0M && (position.Lat != result.Position.Lat || position.Lng != result.Position.Lng)) { throw new Exception(i18n.Multiple_GPS_positions_found); } break; } } } if (ffp.streams != null) { foreach (FFprobe.streamType stream in ffp.streams) { switch (stream.codec_type) { case "audio": result.AudioTracks++; break; case "video": result.VideoTracks++; break; default: throw new Exception(string.Format(i18n.Unsupported_stream_type_X, stream.codec_type)); } if (stream.tag != null) { foreach (FFprobe.tagType tag in stream.tag) { switch (tag.key) { case "creation_time": DateTime? dt = FFmpegVideoProcessor.ParseCreationTimeTag(tag.value); if (!dt.HasValue) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, tag.key, tag.value)); } result.AddAlternativeMetadataTimestamp(string.Format(i18n.StreamTag_X, tag.key), dt.Value); break; case "location": case "location-eng": Position position = FFmpegVideoProcessor.ParseLocationTag(tag.value); if (position == null) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, tag.key, tag.value)); } if (result.Position == null || (result.Position.Lat == 0 && result.Position.Lng == 0)) { result.Position = position; } else if (position.Lat != 0 && position.Lng != 0 && (position.Lat != result.Position.Lat || position.Lng != result.Position.Lng)) { throw new Exception(i18n.Multiple_GPS_positions_found); } break; } } } } } if (result.VideoTracks == 0 && result.AudioTracks == 0) { throw new Exception(i18n.No_video_audio); } return result; }
public void ToolStdOutReceived(object sender, Tool.OutputReceivedEventArgs e) { this.AddLogLine(e.Text); }
public void ToolCompleted(object sender, Tool.Result e) { if (e.Error == null) { this.RunState = RunStates.Succeeded; if (this._autoCloseOnSuccess && string.IsNullOrEmpty(e.StdErr)) { this.DialogResult = DialogResult.OK; } } else { this.AddLogLine(""); this.AddLogLine(e.Error.Message, true, true); if (e.Cancelled) { this.RunState = RunStates.Cancelled; } else { this.RunState = RunStates.Failed; } } }
protected override MediaInfo GetInfo(string fullFilename) { ExivInfo result = new ExivInfo(); Tool tool = new Tool(Tool.Which.Exiv2, new string[] { "-Pkv", Tool.Escape(fullFilename) }, new int[] { 0, 253 }); Tool.Result toolOutput = tool.Run(); decimal? lat = null; int? latSign = null; decimal? lng = null; int? lngSign = null; decimal? alt = null; int? altSign = null; DateTime dt; DateTime? gpsDate = null; TimeSpan? gpsTime = null; foreach (string line in toolOutput.StdOut.Replace("\r\n", "\n").Replace('\r', '\n').Split('\n')) { string[] chunks = line.Split(new char[] { ' ' }, 2); if (chunks.Length == 2) { chunks[1] = chunks[1].Trim(); if (chunks[1].Length > 0) { switch (chunks[0]) { case "Exif.Image.DateTime": case "Exif.Photo.DateTimeOriginal": case "Exif.Photo.DateTimeDigitized": case "Xmp.xmp.CreateDate": case "Xmp.xmp.MetadataDate": case "Xmp.xmp.ModifyDate": if (chunks[0].StartsWith("Xmp.xmp.")) { result.HasXmp = true; } if (DateTime.TryParseExact(chunks[1], @"yyyy\:MM\:dd HH\:mm\:ss", NumberFormatInfo.InvariantInfo, DateTimeStyles.AssumeLocal, out dt)) { result.AddAlternativeMetadataTimestamp(string.Format(i18n.Tag_X, chunks[0]), TimeZoneHandler.ToShootZone(ExivImageProcessor.EXIF_IMAGEPHOTOXMP_TAGS_TIMEZONE, dt)); } else if (DateTime.TryParseExact(chunks[1], @"yyyy-MM-dd\THH\:mm\:sszzz", NumberFormatInfo.InvariantInfo, DateTimeStyles.AssumeLocal, out dt)) { result.AddAlternativeMetadataTimestamp(string.Format(i18n.Tag_X, chunks[0]), TimeZoneHandler.ToShootZone(TimeZoneHandler.Zone.Utc, dt.ToUniversalTime())); } else { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; case "Exif.GPSInfo.GPSDateStamp": result.HasGpsTimestamp = true; if (!DateTime.TryParseExact(chunks[1], @"yyyy\:MM\:dd", NumberFormatInfo.InvariantInfo, DateTimeStyles.AssumeLocal, out dt)) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } gpsDate = new DateTime?(dt); break; case "Exif.GPSInfo.GPSTimeStamp": result.HasGpsTimestamp = true; decimal dH, dM, dS; if (!ExivImageProcessor.GpsTripleToDecimal(chunks[1], out dH, out dM, out dS)) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } gpsTime = new TimeSpan(Convert.ToInt32(Math.Round(dH)), Convert.ToInt32(Math.Round(dM)), Convert.ToInt32(Math.Round(dS))); break; case "Exif.GPSInfo.GPSLatitudeRef": if (latSign.HasValue) { throw new Exception(string.Format(i18n.Multiple_tags_found, chunks[0])); } switch (chunks[1]) { case "N": latSign = +1; break; case "S": latSign = -1; break; default: throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; case "Exif.GPSInfo.GPSLatitude": if (lat.HasValue) { throw new Exception(string.Format(i18n.Multiple_tags_found, chunks[0])); } lat = ExivImageProcessor.gpsLLToDecimal(chunks[1]); if (!lat.HasValue) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; case "Exif.GPSInfo.GPSLongitudeRef": if (lngSign.HasValue) { throw new Exception(string.Format(i18n.Multiple_tags_found, chunks[0])); } switch (chunks[1]) { case "E": lngSign = +1; break; case "W": lngSign = -1; break; default: throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; case "Exif.GPSInfo.GPSLongitude": if (lng.HasValue) { throw new Exception(string.Format(i18n.Multiple_tags_found, chunks[0])); } lng = ExivImageProcessor.gpsLLToDecimal(chunks[1]); if (!lng.HasValue) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; case "Exif.GPSInfo.GPSAltitudeRef": if (altSign.HasValue) { throw new Exception(string.Format(i18n.Multiple_tags_found, chunks[0])); } switch (chunks[1]) { case "0": altSign = +1; break; case "1": altSign = -1; break; default: throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; case "Exif.GPSInfo.GPSAltitude": if (alt.HasValue) { throw new Exception(string.Format(i18n.Multiple_tags_found, chunks[0])); } alt = ExivImageProcessor.gpsAltToDecimal(chunks[1]); if (!alt.HasValue) { throw new Exception(string.Format(i18n.Invalid_tag_X_value_V, chunks[0], chunks[1])); } break; } } } } if (gpsDate.HasValue || gpsTime.HasValue) { if (!gpsTime.HasValue) { throw new Exception(i18n.GPS_date_without_time); } if (!gpsDate.HasValue) { throw new Exception(i18n.GPS_time_without_date); } result.AddAlternativeMetadataTimestamp(i18n.GPS_tag, TimeZoneHandler.ToShootZone(ExivImageProcessor.EXIF_GPS_TAGS_TIMEZONE, gpsDate.Value.Add(gpsTime.Value))); } if (lat.HasValue || latSign.HasValue || lng.HasValue || lngSign.HasValue || alt.HasValue || altSign.HasValue) { if (!lat.HasValue) { throw new Exception(i18n.Missing_latitude); } if (!latSign.HasValue) { throw new Exception(i18n.Missing_latituderef); } if (!lng.HasValue) { throw new Exception(i18n.Missing_longitude); } if (!lngSign.HasValue) { throw new Exception(i18n.Missing_longituderef); } result.Position = new Position(lat.Value * Convert.ToDecimal(latSign.Value), lng.Value * Convert.ToDecimal(lngSign.Value), (alt.HasValue && altSign.HasValue) ? alt.Value * Convert.ToDecimal(altSign.Value) : (decimal?)null); } return result; }