Advertisement
Selzier

ExifToolWrapper

Dec 9th, 2020
1,317
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.07 KB | None | 0 0
  1. using UnityEngine;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Reflection;
  7. using System.Threading;
  8. using System.Diagnostics;
  9. using System.Linq;
  10.  
  11. public struct ExifTagItem {
  12.     public string group;
  13.     public string name;
  14.     public string value;
  15. }
  16.  
  17. public class ExifToolWrapper : List<ExifTagItem> {
  18.  
  19.     public List<float> smokeTimes = new List<float>();
  20.     public List<string> songArtists = new List<string>();
  21.     public List<string> songNames = new List<string>();
  22.     public List<float> songTimes = new List<float>();
  23.     public bool isMetadataLoaded;
  24.  
  25.     #region public methods
  26.     string toolPath;
  27.     public bool CheckToolExists() {
  28.         //string toolPath = GetAppPath();        
  29.         string toolPath = Application.streamingAssetsPath;
  30.         UnityEngine.Debug.Log(toolPath);
  31.         //toolPath += "-ver";
  32.  
  33.         string output = "";
  34.         if (!File.Exists(toolPath + "/exiftool.exe")) {
  35.             return false;
  36.         }
  37.         else {
  38.             try {
  39.                 output = Open(toolPath);
  40.             }
  41.             catch (Exception) {
  42.             }
  43.         }
  44.         // check the output
  45.         if (output.Length < 4)
  46.             return false;
  47.  
  48.         // (could check version number here if you care)
  49.         return true;
  50.     }
  51.  
  52.     public void Run(string filename, bool removeWhitespaceInTagNames = false) {
  53.         // exiftool command
  54.         toolPath = Application.streamingAssetsPath;
  55.         toolPath += "/exiftool.exe ";
  56.         if (removeWhitespaceInTagNames)
  57.             toolPath += "-s ";
  58.         //toolPath += "-fast -G -t -m -q -q ";        
  59.         toolPath += "\"" + filename + "\"";
  60.  
  61.         // Get all Marker Start Times and save to Array
  62.         string cmdMarkersStartTime = toolPath + " -TracksMarkersStartTime";
  63.         string output = Open(cmdMarkersStartTime);
  64.         // Remove first 34 characters (up to ":")
  65.         string data = output.Remove(0, 34);
  66.         float[] markerTimes = Array.ConvertAll(data.Split(','), float.Parse);
  67.  
  68.         foreach (float i in markerTimes) {
  69.             UnityEngine.Debug.Log(i);
  70.         }
  71.  
  72.         // Get all Marker comments and save to Array
  73.         string cmdMarkersComment = toolPath + " -TracksMarkersComment";
  74.         output = Open(cmdMarkersComment);
  75.         data = output.Remove(0, 34);
  76.         string[] markerComments = data.Split(',');
  77.         for (int i = 0; i < markerComments.Length; i++) {
  78.             markerComments[i] = markerComments[i].Trim();            
  79.         }
  80.         foreach (string i in markerComments) {
  81.             UnityEngine.Debug.Log(i);
  82.         }
  83.  
  84.         // Get all Marker comments and save to Array
  85.         string cmdMarkersName = toolPath + " -TracksMarkersName";
  86.         output = Open(cmdMarkersName);
  87.         data = output.Remove(0, 34);
  88.         string[] markerNames = data.Split(',');
  89.         //smokeTimes = new List<float>();
  90.         //songArtists = new List<string>();
  91.         //songNames = new List<string>();
  92.         //songTimes = new List<float>();
  93.         for (int i = 0; i < markerNames.Length; i++) {
  94.             markerNames[i] = markerNames[i].Trim();
  95.             if (markerNames[i] == "Smoke") {
  96.                 smokeTimes.Add(markerTimes[i] / 44100);
  97.             }
  98.             else {
  99.                 songTimes.Add(markerTimes[i] / 44100);
  100.                 //songNames.Add(markerComments[i]);
  101.                 songArtists.Add(markerNames[i]);
  102.             }
  103.         }
  104.         for (int i = 0; i < songTimes.Count; i++) {
  105.             songNames.Add(markerComments[i]);
  106.         }
  107.         foreach (float i in smokeTimes) {
  108.             UnityEngine.Debug.Log("Smoke times: " + i);
  109.         }
  110.  
  111.         UnityEngine.Debug.Log("Time: " + songTimes[3] + "; Artist: " + songArtists[3] + "; Song: " + songNames[3]);
  112.  
  113.  
  114.         isMetadataLoaded = true;
  115.  
  116.         /*
  117.         // parse the output into tags
  118.         this.Clear();
  119.         while (output.Length > 0) {
  120.             int epos = output.IndexOf('\r');
  121.  
  122.             if (epos < 0)
  123.                 epos = output.Length;
  124.             string tmp = output.Substring(0, epos);
  125.             int tpos1 = tmp.IndexOf('\t');
  126.             int tpos2 = tmp.IndexOf('\t', tpos1 + 1);
  127.  
  128.             if (tpos1 > 0 && tpos2 > 0) {
  129.                 string taggroup = tmp.Substring(0, tpos1);
  130.                 ++tpos1;
  131.                 string tagname = tmp.Substring(tpos1, tpos2 - tpos1);
  132.                 ++tpos2;
  133.                 string tagvalue = tmp.Substring(tpos2, tmp.Length - tpos2);
  134.  
  135.                 // special processing for tags with binary data
  136.                 tpos1 = tagvalue.IndexOf(", use -b option to extract");
  137.                 if (tpos1 >= 0)
  138.                     tagvalue.Remove(tpos1, 26);
  139.  
  140.                 ExifTagItem itm;
  141.                 itm.name = tagname;
  142.                 itm.value = tagvalue;
  143.                 itm.group = taggroup;
  144.                 this.Add(itm);
  145.             }
  146.  
  147.             // is \r followed by \n ?
  148.             if (epos < output.Length)
  149.                 epos += (output[epos + 1] == '\n') ? 2 : 1;
  150.             output = output.Substring(epos, output.Length - epos);        
  151.         }*/
  152.     }
  153.  
  154.     public bool HasExifData() {
  155.         return (this.Count > 0);
  156.     }
  157.  
  158.     public ExifTagItem Find(string tagname) {
  159.         var q_items = from tagItem in this
  160.                         where tagItem.name == tagname
  161.                         select tagItem;
  162.         return q_items.First();
  163.     }
  164.  
  165.     /// <summary>
  166.     /// This method saves EXIF data to an external file (<file>.exif). Only tags with group EXIF are saved.
  167.     /// </summary>
  168.     /// <param name="source_image">Source Image file path</param>
  169.     /// <param name="destination_exif_file">Destination .exif file path</param>
  170.     /// <returns>True if no error</returns>
  171.     public bool SaveExifData(string source_image, string destination_exif_file) {
  172.         // exiftool command
  173.         string toolPath = GetAppPath();
  174.         toolPath += "/exiftool.exe ";
  175.         toolPath += "-fast -m -q -q -tagsfromfile ";
  176.         toolPath += "\"" + source_image + "\" -exif ";
  177.         toolPath += "\"" + destination_exif_file + "\"";
  178.  
  179.         string output = Open(toolPath);
  180.  
  181.         if (output.Contains("Error"))
  182.             return false;
  183.  
  184.         return true;
  185.     }
  186.  
  187.     /// <summary>
  188.     /// This method writes EXIF data to the given destination image file (must exist beforehand).
  189.     /// </summary>
  190.     /// <param name="source_exif_file">Source .exif file</param>
  191.     /// <param name="destination_image">Destination image path (file must exist)</param>
  192.     /// <returns></returns>
  193.     public bool WriteExifData(string source_exif_file, string destination_image) {
  194.         // exiftool command
  195.         string toolPath = GetAppPath();
  196.         toolPath += "/exiftool.exe ";
  197.         toolPath += "-fast -m -q -q -TagsFromFile ";
  198.         toolPath += "\"" + source_exif_file + "\"";
  199.         toolPath += " -all:all ";
  200.         toolPath += "\"" + destination_image + "\"";
  201.  
  202.         string output = Open(toolPath);
  203.  
  204.         if (output.Contains("Error"))
  205.             return false;
  206.  
  207.         return true;
  208.     }
  209.     #endregion
  210.     #region Private methods
  211.     /// <summary>
  212.     /// Gets the path from where the executable is being run
  213.     /// </summary>
  214.     /// <returns>Path</returns>
  215.     private string GetAppPath() {
  216.         string AppPath;
  217.         AppPath = Assembly.GetExecutingAssembly().Location;
  218.         AppPath = Path.GetDirectoryName(AppPath);
  219.  
  220.         return AppPath;
  221.     }
  222.  
  223.     private string stdOut = null;
  224.     private string stdErr = null;
  225.     private ProcessStartInfo psi = null;
  226.     private Process activeProcess = null;
  227.  
  228.     private void Thread_ReadStandardError() {
  229.         if (activeProcess != null) {
  230.             stdErr = activeProcess.StandardError.ReadToEnd();
  231.         }
  232.     }
  233.  
  234.     private void Thread_ReadStandardOut() {
  235.         if (activeProcess != null) {
  236.             stdOut = activeProcess.StandardOutput.ReadToEnd();
  237.         }
  238.     }
  239.  
  240.     private string Open(string cmd) {
  241.         string program = "\"%COMSPEC%\"";
  242.         string args = "/c [command]";
  243.         this.psi = new ProcessStartInfo(
  244.             Environment.ExpandEnvironmentVariables(program),
  245.             args.Replace("[command]", cmd)
  246.         );
  247.         this.psi.CreateNoWindow = true;
  248.         this.psi.UseShellExecute = false;
  249.         this.psi.RedirectStandardOutput = true;
  250.         this.psi.RedirectStandardError = true;
  251.  
  252.         Thread thread_ReadStandardError = new Thread(new ThreadStart(Thread_ReadStandardError));
  253.         Thread thread_ReadStandardOut = new Thread(new ThreadStart(Thread_ReadStandardOut));
  254.  
  255.         activeProcess = Process.Start(psi);
  256.         if (psi.RedirectStandardError) {
  257.             thread_ReadStandardError.Start();
  258.         }
  259.         if (psi.RedirectStandardOutput) {
  260.             thread_ReadStandardOut.Start();
  261.         }
  262.         activeProcess.WaitForExit();
  263.  
  264.         thread_ReadStandardError.Join();
  265.         thread_ReadStandardOut.Join();
  266.  
  267.         string output = stdOut + stdErr;
  268.  
  269.         return output;
  270.     }
  271.  
  272.     #endregion
  273. }
  274.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement