Advertisement
mnerec

DeleteWMPTagsFromMP4.cs

Aug 31st, 2014
929
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 9.17 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.IO;
  6. using System.Diagnostics;
  7. using System.Threading;
  8. using System.Text.RegularExpressions;
  9.  
  10. class Script
  11. {
  12.     const string usage = "Usage: cscscript DeleteWMPTagsFromMP4.cs INFILE [/COMMIT]\n" +
  13.                          "Removes meta and Xtra tags if present.\n";
  14.  
  15.     static bool commitFlag = false;
  16.  
  17.     static public void Main(string[] args)
  18.     {
  19.         if (args.Length == 0 ||
  20.             (args.Length == 1 && (args[0] == "?" || args[0] == "/?" || args[0] == "-?" || args[0].ToLower() == "-help" || args[0].ToLower() == "help")))
  21.         {
  22.             Console.WriteLine(usage);
  23.             return;
  24.         }
  25.  
  26.         string[] files;
  27.         if (args[0].Contains('*'))
  28.         {
  29.             string dir = Path.GetDirectoryName(args[0]);
  30.             if (dir == "") dir = ".\\";
  31.             string fname = Path.GetFileName(args[0]);
  32.             files = Directory.GetFiles(dir, fname, SearchOption.AllDirectories);
  33.         }
  34.         else
  35.             files = new string[1] { args[0] };
  36.  
  37.         if (args.Length > 1)
  38.             commitFlag = args[1].Equals("/COMMIT", StringComparison.CurrentCultureIgnoreCase);
  39.  
  40.         Console.WriteLine("Inputfile:  " + args[0]);
  41.         Console.WriteLine("CommitFlag: " + (commitFlag ? "COMMIT" : "no-commit"));
  42.         Console.WriteLine("");
  43.  
  44.         foreach (string filename in files)
  45.         {
  46.             if (!File.Exists(filename))
  47.             {
  48.                 Console.WriteLine(" Cannot locate file " + filename);
  49.                 continue;
  50.             }
  51.  
  52.             ParseFile(filename);
  53.         }
  54.     }
  55.  
  56.     static public void ParseFile(string filename)
  57.     {
  58.         int original_filelength = 0;
  59.         int moov_pos = 0, moov_size = 0;
  60.         int udta_pos = 0, udta_size = 0;
  61.         int meta_pos = 0, meta_size = 0;
  62.         int xtra_pos = 0, xtra_size = 0;
  63.  
  64. //        Console.WriteLine(string.Format("Parsing [ {0} ]... ", filename));
  65.  
  66.         using (BinaryReader br = new BinaryReader(File.Open(filename, FileMode.Open, FileAccess.Read)))
  67.         {
  68.             original_filelength = (int)br.BaseStream.Length;
  69.  
  70.             // check filetype
  71.             br.BaseStream.Seek(4, SeekOrigin.Begin);
  72.             if ("ftypisom" != ASCIIEncoding.ASCII.GetString(br.ReadBytes(8)))
  73.             {
  74.                 //Console.WriteLine( " [UNKNOWN FILETYPE]");
  75.                 Console.WriteLine(string.Format("[UNKNOWN] [ {0} ]", filename));
  76.                 return;
  77.             }
  78.  
  79.             if (locateTag(br, 0, "moov", ref moov_pos, ref moov_size))
  80.             {
  81.                 if (locateTag(br, moov_pos + 8, "udta", ref udta_pos, ref udta_size))
  82.                 {
  83.                     locateTag(br, udta_pos + 8, "meta", ref meta_pos, ref meta_size);
  84.                     locateTag(br, udta_pos + 8, "Xtra", ref xtra_pos, ref xtra_size);
  85.                 }
  86.             }
  87.  
  88.             // if file clean, exit
  89.             if ((meta_pos == 0) && (xtra_pos == 0))
  90.             {
  91.                 //Console.WriteLine(" [CLEAN]");
  92.                 Console.WriteLine( string.Format( "[CLEAN]   [ {0} ]", filename ) );
  93.                 return;
  94.             }
  95.  
  96.             //Console.WriteLine( "[DIRTY!]" );
  97.             Console.WriteLine( string.Format( "[DIRTY]   [ {0} ]", filename ) );
  98.             Console.WriteLine( string.Format( " Tags @ 0x{0:x8}-0x{1:x8}, 0x{2:x8}-0x{3:x8}, 0x{4:x8}-0x{5:x8}",
  99.                                         udta_pos, udta_pos + udta_size,
  100.                                         meta_pos, meta_pos + meta_size,
  101.                                         xtra_pos, xtra_pos + xtra_size
  102.                                         ) );
  103.  
  104.             if ( !commitFlag )
  105.                 return;
  106.  
  107.             Console.WriteLine(string.Format(" Fixing file... ", filename));
  108.  
  109.             try
  110.             {
  111.                 byte[] udta_buffer;
  112.  
  113.                 // read udat into memory
  114.                 br.BaseStream.Seek( udta_pos, SeekOrigin.Begin );
  115.                 udta_buffer = br.ReadBytes( (int)udta_size );
  116.  
  117.                 if ( BA_FindTag( ref udta_buffer, "meta", ref meta_pos, ref meta_size ) )
  118.                     CleanUDTA( ref udta_buffer, meta_pos, meta_size );
  119.                 if ( BA_FindTag( ref udta_buffer, "Xtra", ref xtra_pos, ref xtra_size ) )
  120.                     CleanUDTA( ref udta_buffer, xtra_pos, xtra_size );
  121.                 UpdateUDTASize( ref udta_buffer );
  122.  
  123.                 using ( BinaryWriter bw = new BinaryWriter( File.Open( filename + "$TMP", FileMode.Create, FileAccess.Write ) ) )
  124.                 {
  125.                     // copy from 0 to UDTA begin
  126.                     br.BaseStream.Seek( 0, SeekOrigin.Begin );
  127.                     BufferedBinaryCopy( br, bw, udta_pos );
  128.  
  129.                     // write new UDTA
  130.                     if (udta_buffer.Length > 8)
  131.                         bw.Write( udta_buffer );
  132.  
  133.                     // copy from after old UDTA to EOF
  134.                     br.BaseStream.Seek( udta_size, SeekOrigin.Current );
  135.                     BufferedBinaryCopy( br, bw, original_filelength - ( udta_pos + udta_size ) );
  136.                 }
  137.  
  138.                 Console.WriteLine( " FIXED!" );
  139.             }
  140.             catch
  141.             {
  142.                 Console.WriteLine( " --FAILED--" );
  143.             }
  144.         }
  145.         File.Replace(filename + "$TMP", filename, filename + ".bak");
  146.     }
  147.  
  148.     static public bool BufferedBinaryCopy(BinaryReader source, BinaryWriter destination, int length)
  149.     {
  150.         const int IOBUFFER_SIZE = 32*1024*1024;
  151.         byte[] buffer;
  152.  
  153.         int bytes_left = length;
  154.         int bytes_to_read = 0;
  155.  
  156.         while (bytes_left > 0)
  157.         {
  158.             bytes_to_read = Math.Min(IOBUFFER_SIZE, bytes_left);
  159.             buffer = source.ReadBytes(bytes_to_read);
  160.             bytes_left -= buffer.Length;
  161.  
  162.             destination.Write(buffer);
  163.         }
  164.         return true;
  165.     }
  166.  
  167.     static public bool locateTag(BinaryReader br, int offset, string tag, ref int pos, ref int size)
  168.     {
  169.         Byte[] tagdata;
  170.         try
  171.         {
  172.             br.BaseStream.Seek(offset, SeekOrigin.Begin);
  173.  
  174.             while (br.BaseStream.Position < br.BaseStream.Length - 8)
  175.             {
  176.                 tagdata = br.ReadBytes(4);
  177.                 Array.Reverse(tagdata);
  178.                 int tagsize = (int)BitConverter.ToUInt32(tagdata, 0);
  179.                 if (tagsize == 1)
  180.                 {
  181.                     byte[] exdata = br.ReadBytes(4);
  182.                     Array.Reverse(exdata);
  183.                     tagsize = (tagsize << 32) + (int)BitConverter.ToUInt32(exdata, 0);
  184.                 }
  185.  
  186.                 tagdata = br.ReadBytes(4);
  187.                 string tagname = ASCIIEncoding.ASCII.GetString(tagdata);
  188.  
  189.                 if (tagname == tag)
  190.                 {
  191.                     pos = (int)br.BaseStream.Position - 8;
  192.                     size = tagsize;
  193.                     return true;
  194.                 }
  195.                 if (tagsize == 0)
  196.                     return false;
  197.                 br.BaseStream.Seek(tagsize-8, SeekOrigin.Current);
  198.             }
  199.        
  200.         } catch {
  201.         }
  202.         return false;
  203.     }
  204.  
  205.     static public void CleanUDTA(ref byte[] buffer, int pos, int size)
  206.     {
  207.         List<byte> lb = buffer.ToList();
  208.         lb.RemoveRange(pos, size);
  209.         buffer = lb.ToArray();
  210.     }
  211.  
  212.     static public void UpdateUDTASize(ref byte[] buffer)
  213.     {
  214.         int buffer_length = buffer.Length;
  215.         byte[] tagsize = BitConverter.GetBytes(buffer_length);
  216.         Array.Reverse(tagsize);
  217.  
  218.         List<byte> lb = buffer.ToList();
  219.         lb.RemoveRange(0, 4);
  220.         lb.InsertRange(0, tagsize);
  221.         buffer = lb.ToArray();
  222.     }
  223.  
  224.     static public bool RewriteFile(ref BinaryReader input, long udta_pos, long udta_size, long meta_pos, long meta_size, long xtra_pos, long xtra_size)
  225.     {
  226.         string tempname = string.Format(@"{0}.txt", Guid.NewGuid());
  227.         using (BinaryWriter b = new BinaryWriter(File.Open("tempname", FileMode.Create, FileAccess.Read)))
  228.         {
  229.  
  230.  
  231.  
  232.         }
  233.         return true;
  234.     }
  235.  
  236.     static public bool BA_FindTag(ref byte[] bb, string tag, ref int tag_pos, ref int tag_size)
  237.     {
  238.         byte[] pattern = Encoding.UTF8.GetBytes(tag);
  239.         int byte_index = BA_IndexOf(bb, pattern);
  240.         if (byte_index >= 0)
  241.         {
  242.             tag_pos = byte_index-4;
  243.             tag_size = (bb[byte_index - 4] << 24) | (bb[byte_index - 3] << 16) | (bb[byte_index - 2] << 8) | bb[byte_index - 1];
  244.             return true;
  245.         }
  246.  
  247.         return false;
  248.     }
  249.  
  250.     static public int BA_IndexOf(byte[] data, byte[] pattern)
  251.     {
  252.         if (pattern.Length > data.Length)
  253.             return -1;
  254.  
  255.         for (int i = 0; i < data.Length - pattern.Length; i++)
  256.         {
  257.             bool found = true;
  258.             for (int j = 0; j < pattern.Length; j++)
  259.             {
  260.                 if (data[i + j] != pattern[j])
  261.                 {
  262.                     found = false;
  263.                     break;
  264.                 }
  265.             }
  266.             if (found)
  267.             {
  268.                 return i;
  269.             }
  270.         }
  271.         return -1;
  272.     }
  273. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement