/// <summary> /// Pass the 'inStream' through exiftool and write the output to the 'outStream'. /// </summary> private void ReadTemporaryFile(Stream file) { // get a buffer byte[] buffer = BufferCache.Get(); // read from the stream int count = file.Read(buffer, 0, Global.BufferSizeLocal); // write the buffer to the output stream Output.Write(buffer, 0, count); // is this the final buffer? if (count < Global.BufferSizeLocal) { // yes, dispose of the file stream file.Dispose(); // reset the buffer BufferCache.Set(buffer); Success = true; // run callback OnComplete.Run(); // should the file be removed? if (_removeTempFile) { ManagerResources.RemoveFile(Path); } } else { // no, reset the buffer BufferCache.Set(buffer); // add a task to clear the metadata ManagerUpdate.Control.AddSingle(ReadTemporaryFile, file); } }
/// <summary> /// Run the medadata removal process. /// </summary> public void Run() { bool found = false; if (_coordinator.Buffer != null) { while (_coordinator.BufferIndex < _coordinator.BufferCount) { if (_coordinator.ReadySearch.Next(_coordinator.Buffer[_coordinator.BufferIndex])) { ++_coordinator.BufferIndex; found = true; break; } ++_coordinator.BufferIndex; } if (_coordinator.BufferIndex == _coordinator.BufferCount) { _coordinator.Buffer = null; } } if (!found) { // read the {ready} flag from the exiftool var buffer = BufferCache.Get(); var process = _coordinator.Process.TakeItem(); int count = process.StandardOutput.BaseStream.Read(buffer, 0, Global.BufferSizeLocal); // while there are bytes in the process standard output while (count > 0) { int index = 0; while (index < count) { // check the buffer for the {ready} flag if (_coordinator.ReadySearch.Next(buffer[index])) { ++index; // are there bytes in the buffer? if (index == count) { // no, persist the buffer BufferCache.Set(buffer); } else { // yes, remember the buffer and position _coordinator.Buffer = buffer; _coordinator.BufferIndex = index; _coordinator.BufferCount = count; } found = true; break; } ++index; } if (found) { break; } count = process.StandardOutput.BaseStream.Read(buffer, 0, Global.BufferSizeLocal); } _coordinator.Process.Release(); } // should the file be read? if (Output == null) { // no, run callback OnComplete.Run(); // should the file be removed? if (_removeTempFile) { ManagerResources.RemoveFile(Path); } return; } FileStream fileStream; try { fileStream = new FileStream(Path, FileMode.Open, FileAccess.Read, FileShare.Read); } catch (IOException ex) { // if the file is still being used if (ex.HResult == -2147024864) { // try twice more ManagerUpdate.Iterant.AddSingle(TryReadTemporaryFile, 0); return; } throw; } // get a stream to the clean file ManagerUpdate.Control.AddSingle(ReadTemporaryFile, fileStream); }
/// <summary> /// Run the medadata removal process. /// </summary> public void Run() { var stream = new ByteBuffer(new MemoryStream()); bool found = false; if (_coordinator.Buffer != null) { while (_coordinator.BufferIndex < _coordinator.BufferCount) { var bit = _coordinator.Buffer[_coordinator.BufferIndex]; stream.Write(bit); ++_coordinator.BufferIndex; if (_coordinator.ReadySearch.Next(bit)) { found = true; break; } } if (_coordinator.BufferIndex == _coordinator.BufferCount) { _coordinator.Buffer = null; } } if (!found) { // read the {ready} flag from the exiftool var buffer = BufferCache.Get(); var process = _coordinator.Process.TakeItem(); int count = process.StandardOutput.BaseStream.Read(buffer, 0, Global.BufferSizeLocal); // while there are bytes in the process standard output while (count > 0) { int index = 0; while (index < count) { // check the buffer for the {ready} flag var bit = buffer[index]; stream.Write(bit); ++index; if (_coordinator.ReadySearch.Next(bit)) { // the flag has been found - are there bytes in the buffer? if (index == count) { BufferCache.Set(buffer); } else { // yes, remember the buffer _coordinator.Buffer = buffer; _coordinator.BufferIndex = index; _coordinator.BufferCount = count; } found = true; break; } } if (found) { break; } count = process.StandardOutput.BaseStream.Read(buffer, 0, Global.BufferSizeLocal); } _coordinator.Process.Release(); } // should the file be removed? if (_removeTempFile) { ManagerResources.RemoveFile(Path); } // reset the stream position stream.Position = 0; // create the metadata dictionary for the callback Metadata = new Dictionary <MetaKey, string>(); // while there are more bytes to read while (stream.Position < stream.WriteEnd) { string key; try { // read the key of the key value pair key = stream.ReadString(Chars.Colon); } catch { // ignore and break break; } // trim the key key = key.TrimSpace(); // no, read the value of the key-value pair var value = stream.ReadString(Chars.NewLine).TrimSpace(); if (string.IsNullOrEmpty(key) || string.IsNullOrEmpty(value)) { Log.Debug("Missing metadata '" + key + "' : '" + value + "'."); continue; } // parse the key and assign key-value pair MetaKey metaKey; if (MetaKeys.Map.TryGetValue(key, out metaKey)) { // determine how to parse the metadata value switch (metaKey) { case MetaKey.FileSize: { // determine the scale of the file size var splitFileSize = value.Split(value.IndexOf(Chars.Space)); switch (splitFileSize.ArgB) { case "bytes": Metadata[metaKey] = splitFileSize.ArgA; break; case "MB": Metadata[metaKey] = ((int)(splitFileSize.ArgA.ToDouble() * Global.Megabyte)).ToString(); break; case "kB": Metadata[metaKey] = ((int)(splitFileSize.ArgA.ToDouble() * Global.Kilobyte)).ToString(); break; case "GB": Metadata[metaKey] = ((int)(splitFileSize.ArgA.ToDouble() * Global.Gigabyte)).ToString(); break; default: Log.Error("Unknown file size scale of media '" + value + "'."); break; } } break; case MetaKey.Duration: { // check for (approx) suffix int index = value.IndexOf(Chars.Space); if (index != -1) { value = value.Substring(0, index); } var splitDuration = value.Split(Chars.Colon); // determine the type of duration if (splitDuration.Length == 1) { Metadata[metaKey] = ((int)(splitDuration[0].ToDouble() * 1000)).ToString(); } else { // parse each component int time = splitDuration[0].ToInt32() * 60 * 60 * 1000; time += splitDuration[1].ToInt32() * 60 * 1000; time += splitDuration[2].ToInt32() * 1000; // assign the time value Metadata[metaKey] = time.ToString(); } } break; case MetaKey.Bitrate: { // determine the scale of the file size var splitBitrate = value.Split(value.IndexOf(Chars.Space)); switch (splitBitrate.ArgB) { case "bps": Metadata[metaKey] = splitBitrate.ArgA; break; case "kbps": Metadata[metaKey] = ((int)(splitBitrate.ArgA.ToDouble() * Global.Kilobyte)).ToString(); break; case "Mbps": Metadata[metaKey] = ((int)(splitBitrate.ArgA.ToDouble() * Global.Megabyte)).ToString(); break; default: Log.Warning("Unknown bitrate scale of media '" + value + "'."); break; } } break; default: // assign the mime type directly Metadata[metaKey] = value; break; } } else { Log.Warning("Unrecognized metadata key '" + key + " : " + value + "'."); } } // dispose of the byte stream stream.Close(); // run callback OnComplete.Run(); }