();
28 | }
29 |
30 | return _knownConfigurations[format]
31 | .GetPlaceHoldersToAdd(fileModels);
32 | }
33 |
34 |
35 | }
36 | }
--------------------------------------------------------------------------------
/Packager/Instructions.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IUMDPI/IUMediaHelperApps/32afb704dc9c7691ca0b0f1c3ff01b8bbd451f53/Packager/Instructions.docx
--------------------------------------------------------------------------------
/Packager/Models/EmailMessageModels/AbstractEmailMessage.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Linq;
3 |
4 | namespace Packager.Models.EmailMessageModels
5 | {
6 | public abstract class AbstractEmailMessage
7 | {
8 | private const string AttachmentFormat = "For more details, see the attached {0}: {1}
";
9 |
10 | protected AbstractEmailMessage(string[] toAddresses, string fromAddress, string[] attachments)
11 | {
12 | ToAddresses = toAddresses;
13 | From = fromAddress;
14 | Attachments = attachments;
15 | }
16 |
17 | public string[] ToAddresses { get; }
18 | public string From { get; }
19 | public abstract string Title { get; }
20 | public abstract string Body { get; }
21 | public string[] Attachments { get; }
22 |
23 | protected string GetAttachmentsText()
24 | {
25 | if (!Attachments.Any()) return "";
26 |
27 | return Attachments.Length == 1
28 | ? string.Format(AttachmentFormat, "log", Path.GetFileName(Attachments.Single()))
29 | : string.Format(AttachmentFormat, "logs", string.Join(", ", Attachments.Select(Path.GetFileName)));
30 | }
31 | }
32 | }
--------------------------------------------------------------------------------
/Packager/Models/EmbeddedMetadataModels/AbstractEmbeddedMetadata.cs:
--------------------------------------------------------------------------------
1 | using Packager.Utilities;
2 | using Packager.Utilities.ProcessRunners;
3 |
4 | namespace Packager.Models.EmbeddedMetadataModels
5 | {
6 | public abstract class AbstractEmbeddedMetadata
7 | {
8 | public abstract ArgumentBuilder AsArguments();
9 | }
10 | }
--------------------------------------------------------------------------------
/Packager/Models/EmbeddedMetadataModels/AbstractEmbeddedVideoMetadata.cs:
--------------------------------------------------------------------------------
1 | using Packager.Extensions;
2 | using Packager.Utilities.ProcessRunners;
3 |
4 | namespace Packager.Models.EmbeddedMetadataModels
5 | {
6 | public abstract class AbstractEmbeddedVideoMetadata : AbstractEmbeddedMetadata
7 | {
8 | public string Title { get; set; }
9 | public string Description { get; set; }
10 | public string MasteredDate { get; set; }
11 | public string Comment { get; set; }
12 |
13 | public override ArgumentBuilder AsArguments()
14 | {
15 | var arguments = new ArgumentBuilder
16 | {
17 | $"-metadata title={Title.NormalizeForCommandLine().ToQuoted()}",
18 | $"-metadata comment={Comment.NormalizeForCommandLine().ToQuoted()}",
19 | $"-metadata description={Description.NormalizeForCommandLine().ToQuoted()}"
20 | };
21 | return arguments;
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Packager/Models/EmbeddedMetadataModels/EmbeddedVideoMezzanineMetadata.cs:
--------------------------------------------------------------------------------
1 | using Packager.Extensions;
2 | using Packager.Utilities.ProcessRunners;
3 |
4 | namespace Packager.Models.EmbeddedMetadataModels
5 | {
6 | public class EmbeddedVideoMezzanineMetadata : AbstractEmbeddedVideoMetadata
7 | {
8 | public override ArgumentBuilder AsArguments()
9 | {
10 | var arguments = base.AsArguments();
11 | arguments.Add($"-metadata date={MasteredDate.NormalizeForCommandLine().ToQuoted()}");
12 | return arguments;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Models/EmbeddedMetadataModels/EmbeddedVideoPreservationMetadata.cs:
--------------------------------------------------------------------------------
1 | using Packager.Extensions;
2 | using Packager.Utilities.ProcessRunners;
3 |
4 | namespace Packager.Models.EmbeddedMetadataModels
5 | {
6 | public class EmbeddedVideoPreservationMetadata : AbstractEmbeddedVideoMetadata
7 | {
8 | public override ArgumentBuilder AsArguments()
9 | {
10 | var arguments = base.AsArguments();
11 | arguments.Add($"-metadata date_digitized={MasteredDate.NormalizeForCommandLine().ToQuoted()}");
12 | return arguments;
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AbstractPreservationFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public abstract class AbstractPreservationFile : AbstractFile
6 | {
7 |
8 | protected AbstractPreservationFile(AbstractFile original, string extension) :
9 | base(original, FileUsages.PreservationMaster, extension)
10 | {
11 | }
12 |
13 | public override bool ShouldNormalize => true;
14 |
15 | public override int Precedence => 0;
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AbstractPreservationIntermediateFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public abstract class AbstractPreservationIntermediateFile : AbstractFile
6 | {
7 | protected AbstractPreservationIntermediateFile(AbstractFile original, string extension) :
8 | base(original, FileUsages.PreservationIntermediateMaster, extension)
9 | {
10 | }
11 |
12 | public override bool ShouldNormalize => true;
13 | public override int Precedence => 2;
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AccessFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class AccessFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".mp4";
8 |
9 | public AccessFile(AbstractFile original) :
10 | base(original, FileUsages.AccessFile, ExtensionValue)
11 | {
12 | }
13 |
14 | public override int Precedence => 5;
15 | }
16 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AudioPreservationFile.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class AudioPreservationFile : AbstractPreservationFile
4 | {
5 | public AudioPreservationFile(AbstractFile original) : base(original, original.Extension)
6 | {
7 | }
8 |
9 | public override bool ShouldNormalize => Extension.Equals(".wav");
10 | }
11 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AudioPreservationIntermediateFile.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class AudioPreservationIntermediateFile : AbstractPreservationIntermediateFile
4 | {
5 | private const string ExtensionValue = ".wav";
6 |
7 | public AudioPreservationIntermediateFile(AbstractFile original) : base(original, ExtensionValue)
8 | {
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AudioPreservationIntermediateToneReferenceFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class AudioPreservationIntermediateToneReferenceFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".wav";
8 |
9 | public AudioPreservationIntermediateToneReferenceFile(AbstractFile original) :
10 | base(original, FileUsages.PreservationIntermediateToneReference, ExtensionValue)
11 | {
12 | }
13 |
14 | public override bool ShouldNormalize => true;
15 | public override int Precedence => 3;
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/AudioPreservationToneReferenceFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class AudioPreservationToneReferenceFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".wav";
8 |
9 | public AudioPreservationToneReferenceFile(AbstractFile original) :
10 | base(original, FileUsages.PreservationToneReference, ExtensionValue)
11 | {
12 | }
13 |
14 | public override bool ShouldNormalize => true;
15 |
16 | public override int Precedence => 1;
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Packager/Models/FileModels/CueFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class CueFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".cue";
8 |
9 | public CueFile(AbstractFile original) : base(original, ExtensionValue)
10 | {
11 | }
12 |
13 | public override int Precedence => FileUsage == FileUsages.PreservationMaster ? 1 : 3;
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/FilesArchiveFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class FilesArchiveFile: AbstractFile
6 | {
7 | private const string ExtensionValue = ".zip";
8 |
9 | public FilesArchiveFile(AbstractFile original): base(original, ExtensionValue)
10 | {
11 | }
12 |
13 | public override int Precedence => 7;
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/InfoFile.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class InfoFile : AbstractFile
4 | {
5 | private const string ExtensionValue = ".info";
6 |
7 | public InfoFile(AbstractFile original) : base(original, original.FileUsage, ExtensionValue)
8 | {
9 | }
10 |
11 | public override int Precedence => 26;
12 | }
13 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/MediaInfo.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class MediaInfo
4 | {
5 | public int AudioStreams { get; set; }
6 | public int VideoStreams { get; set; }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/Packager/Models/FileModels/MezzanineFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class MezzanineFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".mov";
8 |
9 | public MezzanineFile(AbstractFile original) :
10 | base(original, FileUsages.MezzanineFile, ExtensionValue)
11 | {
12 | }
13 |
14 | public override bool ShouldNormalize => true;
15 | public override int Precedence => 4;
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/PlaceHolderFile.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class PlaceHolderFile : UnknownFile
4 | {
5 | public PlaceHolderFile(string projectCode, string barcode, int sequenceIndicator, string extension)
6 | : base($"{projectCode}_{barcode}_{sequenceIndicator}_pres.{extension}")
7 | {
8 | IsPlaceHolder = true;
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/ProductionFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class ProductionFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".wav";
8 |
9 | public ProductionFile(AbstractFile original) :
10 | base(original, FileUsages.ProductionMaster, ExtensionValue)
11 | {
12 | }
13 |
14 | public override bool ShouldNormalize => true;
15 | public override int Precedence => 4;
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/QualityControlFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class QualityControlFile : AbstractFile
6 | {
7 | private const string ExtensionValue = ".qctools.xml.gz";
8 | private const string IntermediateExtensionValue = ".qctools.xml";
9 |
10 | public string IntermediateFileName { get; }
11 |
12 | public QualityControlFile(AbstractFile original) :
13 | base(original, new QualityControlFileUsage(original.FileUsage), ExtensionValue)
14 | {
15 | Filename = $"{original.Filename}{ExtensionValue}";
16 | IntermediateFileName = $"{original.Filename}{IntermediateExtensionValue}";
17 | }
18 |
19 | public override int Precedence => 7;
20 | }
21 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/TextFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Extensions;
2 | using Common.Models;
3 |
4 | namespace Packager.Models.FileModels
5 | {
6 | public class TextFile : AbstractFile
7 | {
8 | private const string ExtensionValue = ".txt";
9 |
10 | public TextFile(AbstractFile original) : base(original, ExtensionValue)
11 | {
12 | FileUsage= FileUsages.TextFile;
13 | SequenceIndicator = 1;
14 | }
15 |
16 | protected override string NormalizeFilename()
17 | {
18 | var parts = new[]
19 | {
20 | ProjectCode,
21 | BarCode
22 | };
23 |
24 | return string.Join("_", parts) + Extension;
25 | }
26 |
27 | public override bool IsImportable()
28 | {
29 | if (ProjectCode.IsNotSet())
30 | {
31 | return false;
32 | }
33 |
34 | if (BarCode.IsNotSet())
35 | {
36 | return false;
37 | }
38 |
39 | if (Extension.IsNotSet())
40 | {
41 | return false;
42 | }
43 |
44 | if (!FileUsages.IsImportable(FileUsage))
45 | {
46 | return false;
47 | }
48 |
49 | return true;
50 | }
51 |
52 | public override int Precedence => 9;
53 | }
54 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/TiffImageFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 |
3 | namespace Packager.Models.FileModels
4 | {
5 | public class TiffImageFile:AbstractFile
6 | {
7 | private const string ExtensionValue = ".tif";
8 |
9 | public TiffImageFile(AbstractFile original) : base(original, FileUsages.LabelImageFile, ExtensionValue)
10 | {
11 | }
12 |
13 | public override int Precedence => 6;
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Packager/Models/FileModels/UnknownFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using Common.Models;
4 | using Packager.Extensions;
5 |
6 | namespace Packager.Models.FileModels
7 | {
8 | public class UnknownFile : AbstractFile
9 | {
10 | public UnknownFile(string file)
11 | {
12 | var parts = GetPathParts(file);
13 |
14 | ProjectCode = parts.FromIndex(0, string.Empty).ToUpperInvariant();
15 | BarCode = parts.FromIndex(1, string.Empty).ToLowerInvariant();
16 | SequenceIndicator = GetSequenceIndicator(parts.FromIndex(2, string.Empty));
17 | Extension = Path.GetExtension(file);
18 | FileUsage = FileUsages.GetUsage(parts.FromIndex(3, string.Empty));
19 | OriginalFileName = Path.GetFileName(file);
20 | Filename = OriginalFileName;
21 | }
22 |
23 | private static string[] GetPathParts(string path)
24 | {
25 | return Path.GetFileNameWithoutExtension(path)
26 | .ToDefaultIfEmpty()
27 | .ToLowerInvariant()
28 | .Split(new[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
29 | }
30 |
31 | public override bool IsImportable()
32 | {
33 | return false;
34 | }
35 |
36 | public override int Precedence => 200;
37 | }
38 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/VideoPreservationFile.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class VideoPreservationFile : AbstractPreservationFile
4 | {
5 | private const string ExtensionValue = ".mkv";
6 |
7 | public VideoPreservationFile(AbstractFile original) : base(original, ExtensionValue)
8 | {
9 | }
10 |
11 | public override bool ShouldNormalize => true;
12 | }
13 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/VideoPreservationIntermediateFile.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.FileModels
2 | {
3 | public class VideoPreservationIntermediateFile : AbstractPreservationIntermediateFile
4 | {
5 | private const string ExtensionValue = ".mkv";
6 |
7 | public VideoPreservationIntermediateFile(AbstractFile original) : base(original, ExtensionValue)
8 | {
9 | }
10 |
11 | public override bool ShouldNormalize => true;
12 | }
13 | }
--------------------------------------------------------------------------------
/Packager/Models/FileModels/XmlFile.cs:
--------------------------------------------------------------------------------
1 | using Common.Models;
2 | using Packager.Extensions;
3 |
4 | namespace Packager.Models.FileModels
5 | {
6 | public class XmlFile : AbstractFile
7 | {
8 | public XmlFile(string projectCode, string barCode)
9 | {
10 | ProjectCode = projectCode;
11 | BarCode = barCode;
12 | Extension = ".xml";
13 | Filename = $"{ProjectCode}_{BarCode}{Extension}";
14 | FileUsage = FileUsages.None;
15 | }
16 |
17 | public override int Precedence => 100;
18 |
19 | public override bool IsImportable()
20 | {
21 | return ProjectCode.IsSet() && BarCode.IsSet();
22 | }
23 | }
24 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/AudioConfigurationData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using RestSharp.Extensions;
3 |
4 | namespace Packager.Models.OutputModels
5 | {
6 | [Serializable]
7 | public class AudioConfigurationData
8 | {
9 | public string Track { get; set; }
10 | public string SoundField { get; set; }
11 | public string Speed { get; set; }
12 | public string RecordingType { get; set; }
13 |
14 | public string TapeType { get; set; }
15 | public string TapeStockBrand { get; set; }
16 | public string NoiseReduction { get; set; }
17 | public string FormatDuration { get; set; }
18 |
19 | public bool ShouldSerializeTrack() => Track.HasValue();
20 | public bool ShouldSerializeSoundField() => SoundField.HasValue();
21 | public bool ShouldSerializeSpeed() => Speed.HasValue();
22 | public bool ShouldSerializeRecordingType() => RecordingType.HasValue();
23 | public bool ShouldSerializeTapeType() => TapeType.HasValue();
24 | public bool ShouldSerializeTapeStockBrand() => TapeStockBrand.HasValue();
25 | public bool ShouldSerializeNoiseReduction() => NoiseReduction.HasValue();
26 | public bool ShouldSerializeFormatDuration() => FormatDuration.HasValue();
27 | }
28 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/BakingData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 |
4 | namespace Packager.Models.OutputModels
5 | {
6 | [Serializable]
7 | public class BakingData
8 | {
9 | public string Date { get; set; }
10 |
11 | public bool ShouldSerializeDate()
12 | {
13 | return Date.IsSet();
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/Carrier/AbstractCarrierData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 |
4 | namespace Packager.Models.OutputModels.Carrier
5 | {
6 | [Serializable]
7 | [XmlInclude(typeof (VideoCarrier))]
8 | [XmlInclude(typeof (AudioCarrier))]
9 | public abstract class AbstractCarrierData
10 | {
11 | }
12 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/Carrier/RecordCarrier.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Models.OutputModels.Carrier
4 | {
5 | [Serializable]
6 | public class RecordCarrier:AudioCarrier
7 | {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/CleaningData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 |
4 | namespace Packager.Models.OutputModels
5 | {
6 | [Serializable]
7 | public class CleaningData
8 | {
9 | public string Date { get; set; }
10 | public string Comment { get; set; }
11 |
12 | public bool ShouldSerializeDate()
13 | {
14 | return Date.IsSet();
15 | }
16 |
17 | public bool ShouldSerializeComment()
18 | {
19 | return Comment.IsSet();
20 | }
21 | }
22 |
23 |
24 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/ExportableManifest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 | using Packager.Models.OutputModels.Carrier;
4 |
5 | namespace Packager.Models.OutputModels
6 | {
7 | [Serializable]
8 | [XmlRoot(ElementName = "IU")]
9 | public class ExportableManifest
10 | {
11 | public AbstractCarrierData Carrier { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/File.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 | using Common.Extensions;
4 |
5 | namespace Packager.Models.OutputModels
6 | {
7 | [Serializable]
8 | public class File
9 | {
10 | public File()
11 | {
12 | PlaceHolder = string.Empty; // ensures that placeholder node gets
13 | // serialized as
14 | }
15 |
16 | [XmlElement("FileName", Order = 1)]
17 | public string FileName { get; set; }
18 |
19 | [XmlElement("CheckSum", Order =2)]
20 | public string Checksum { get; set; }
21 |
22 | [XmlElement("PlaceHolder", Order = 3)]
23 | public string PlaceHolder {get;set; }
24 |
25 | // include Checksum node if it is set; otherwise, suppress it
26 | public bool ShouldSerializeChecksum() => Checksum.IsSet();
27 |
28 | // if checksum node is not set, include PlaceHolder node;
29 | // otherwise suppress PlaceHolder node
30 | public bool ShouldSerializePlaceHolder() => Checksum.IsNotSet();
31 | }
32 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/ImportableManifest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 | using Packager.Models.OutputModels.Carrier;
4 |
5 | namespace Packager.Models.OutputModels
6 | {
7 | [Serializable]
8 | [XmlRoot(ElementName = "IU")]
9 | public class ImportableManifest where T: AbstractCarrierData
10 | {
11 | public T Carrier { get; set; }
12 | }
13 |
14 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/Ingest/AbstractIngest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 |
4 | namespace Packager.Models.OutputModels.Ingest
5 | {
6 | [Serializable]
7 | [XmlInclude(typeof (VideoIngest))]
8 | [XmlInclude(typeof (AudioIngest))]
9 | public class AbstractIngest
10 | {
11 |
12 | }
13 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/Ingest/Device.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.OutputModels.Ingest
2 | {
3 | public class Device
4 | {
5 | public string Model { get; set; }
6 | public string SerialNumber { get; set; }
7 | public string Manufacturer { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/Ingest/VideoIngest.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 |
4 | namespace Packager.Models.OutputModels.Ingest
5 | {
6 | [Serializable]
7 | public class VideoIngest : AbstractIngest
8 | {
9 | [XmlElement(Order = 1)]
10 | public string FileName { get; set; }
11 |
12 | [XmlElement(Order = 2)]
13 | public string Date { get; set; }
14 |
15 | [XmlElement(Order = 3)]
16 | public string Comments { get; set; }
17 |
18 | [XmlElement(ElementName = "Created_by", Order = 4)]
19 | public string CreatedBy { get; set; }
20 |
21 | [XmlElement(Order = 5, ElementName = "Player")]
22 | public Device[] Players { get; set; }
23 |
24 | [XmlElement(Order = 6, ElementName = "TBC")]
25 | public Device[] TbcDevices { get; set; }
26 |
27 | [XmlElement(Order = 7, ElementName = "AD")]
28 | public Device[] AdDevices { get; set; }
29 |
30 | [XmlElement(Order = 8)]
31 | public Device Encoder { get; set; }
32 |
33 | [XmlElement(Order = 9, ElementName = "Extraction_workstation")]
34 | public Device ExtractionWorkstation { get; set; }
35 |
36 |
37 | }
38 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/PartsData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 |
4 | namespace Packager.Models.OutputModels
5 | {
6 | [Serializable]
7 | public class PartsData
8 | {
9 | public string DigitizingEntity { get; set; }
10 |
11 | [XmlElement("Part")]
12 | public SideData[] Sides { get; set; }
13 | }
14 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/PhysicalConditionData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 |
4 | namespace Packager.Models.OutputModels
5 | {
6 | [Serializable]
7 | public class PhysicalConditionData
8 | {
9 | public string Damage { get; set; }
10 | public string PreservationProblem { get; set; }
11 |
12 | public bool ShouldSerializePreservationProblem()
13 | {
14 | return PreservationProblem.IsSet();
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/PreviewData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 |
4 | namespace Packager.Models.OutputModels
5 | {
6 | [Serializable]
7 | public class PreviewData
8 | {
9 | public string Comments { get; set; }
10 |
11 | public bool ShouldSerializeComments()
12 | {
13 | return Comments.IsSet();
14 | }
15 | }
16 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/SideData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Xml.Serialization;
4 | using Packager.Extensions;
5 | using Packager.Models.OutputModels.Ingest;
6 |
7 | namespace Packager.Models.OutputModels
8 | {
9 | [Serializable]
10 | public class SideData
11 | {
12 | [XmlAttribute("Side")]
13 | public string Side { get; set; }
14 |
15 | [XmlElement("Ingest")]
16 | public List Ingest { get; set; }
17 |
18 | public List Files { get; set; }
19 | }
20 | }
--------------------------------------------------------------------------------
/Packager/Models/OutputModels/VideoConfigurationData.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Models.OutputModels
4 | {
5 | [Serializable]
6 | public class VideoConfigurationData
7 | {
8 | public string DigitalFileConfigurationVariant { get; set; }
9 | }
10 | }
--------------------------------------------------------------------------------
/Packager/Models/PlaceHolderConfigurations/IPlaceHolderConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Packager.Models.FileModels;
3 |
4 | namespace Packager.Models.PlaceHolderConfigurations
5 | {
6 | public interface IPlaceHolderConfiguration
7 | {
8 | List GetPlaceHoldersToAdd(List fileModels);
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/Packager/Models/PlaceHolderConfigurations/PresIntAudioPlaceHolderConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Common.Models;
3 | using Packager.Extensions;
4 | using Packager.Factories;
5 | using Packager.Models.FileModels;
6 |
7 | namespace Packager.Models.PlaceHolderConfigurations
8 | {
9 | public class PresIntAudioPlaceHolderConfiguration : AbstractPlaceHolderConfiguration
10 | {
11 | public PresIntAudioPlaceHolderConfiguration() : base(new List { FileUsages.PreservationMaster,
12 | FileUsages.PreservationIntermediateMaster,
13 | FileUsages.ProductionMaster,
14 | FileUsages.AccessFile})
15 | {
16 | }
17 |
18 | protected override List GetPlaceHolders(PlaceHolderFile template)
19 | {
20 | return new List
21 | {
22 | template.ConvertTo(),
23 | template.ConvertTo(),
24 | template.ConvertTo(),
25 | template.ConvertTo()
26 | };
27 | }
28 | }
29 | }
--------------------------------------------------------------------------------
/Packager/Models/PlaceHolderConfigurations/StandardAudioPlaceHolderConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Common.Models;
3 | using Packager.Extensions;
4 | using Packager.Models.FileModels;
5 |
6 | namespace Packager.Models.PlaceHolderConfigurations
7 | {
8 | public class StandardAudioPlaceHolderConfiguration : AbstractPlaceHolderConfiguration
9 | {
10 | public StandardAudioPlaceHolderConfiguration() : base(
11 | new List {
12 | FileUsages.PreservationMaster,
13 | FileUsages.ProductionMaster,
14 | FileUsages.AccessFile})
15 | {
16 | }
17 |
18 | protected override List GetPlaceHolders(PlaceHolderFile template)
19 | {
20 | return new List
21 | {
22 | template.ConvertTo(),
23 | template.ConvertTo(),
24 | template.ConvertTo()
25 | };
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/Packager/Models/PlaceHolderConfigurations/StandardVideoPlaceHolderConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Common.Models;
3 | using Packager.Extensions;
4 | using Packager.Models.FileModels;
5 |
6 | namespace Packager.Models.PlaceHolderConfigurations
7 | {
8 | public class StandardVideoPlaceHolderConfiguration : AbstractPlaceHolderConfiguration
9 | {
10 | public StandardVideoPlaceHolderConfiguration() : base(new List {
11 | FileUsages.PreservationMaster,
12 | FileUsages.MezzanineFile,
13 | FileUsages.AccessFile})
14 | {
15 | }
16 |
17 | protected override List GetPlaceHolders(PlaceHolderFile template)
18 | {
19 | return new List
20 | {
21 | template.ConvertTo(),
22 | template.ConvertTo(),
23 | template.ConvertTo()
24 | };
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Packager/Models/PodMetadataModels/Device.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Linq;
3 | using Packager.Extensions;
4 | using Packager.Factories;
5 |
6 | namespace Packager.Models.PodMetadataModels
7 | {
8 | public class Device : IImportable
9 | {
10 | public string DeviceType { get; set; }
11 | public string SerialNumber { get; set; }
12 | public string Manufacturer { get; set; }
13 | public string Model { get; set; }
14 |
15 | public void ImportFromXml(XElement element, IImportableFactory factory)
16 | {
17 | DeviceType = factory.ToStringValue(element,"device_type");
18 | SerialNumber = factory.ToStringValue(element,"serial_number");
19 | Manufacturer = factory.ToStringValue(element,"manufacturer");
20 | Model = factory.ToStringValue(element,"model");
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/Packager/Models/PodMetadataModels/DigitalVideoFile.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Packager.Validators.Attributes;
5 |
6 | namespace Packager.Models.PodMetadataModels
7 | {
8 | public class DigitalVideoFile : AbstractDigitalFile
9 | {
10 | private const string VideoCaptureDeviceType = "video capture";
11 | private const string TBCDeviceType = "tbc";
12 |
13 | [Required]
14 | public Device Encoder
15 | {
16 | get
17 | {
18 | return SignalChain?.
19 | FirstOrDefault(d => d.DeviceType.Equals(VideoCaptureDeviceType, StringComparison.InvariantCultureIgnoreCase));
20 | }
21 | }
22 |
23 | [HasMembers]
24 | public IEnumerable TBCDevices
25 | {
26 | get
27 | {
28 | return SignalChain?.
29 | Where(e => e.DeviceType.Equals(TBCDeviceType, StringComparison.InvariantCultureIgnoreCase)) ?? new List();
30 | }
31 | }
32 |
33 | }
34 | }
--------------------------------------------------------------------------------
/Packager/Models/PodMetadataModels/VideoPodMetadata.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Xml.Linq;
4 | using Packager.Factories;
5 |
6 | namespace Packager.Models.PodMetadataModels
7 | {
8 | public class VideoPodMetadata : AbstractPodMetadata
9 | {
10 | public string ImageFormat { get; set; }
11 |
12 | public string RecordingStandard { get; set; }
13 |
14 | public string FormatVersion { get; set; }
15 |
16 | public override void ImportFromXml(XElement element, IImportableFactory factory)
17 | {
18 | base.ImportFromXml(element, factory);
19 | ImageFormat = factory.ToStringValue(element, "data/image_format");
20 | RecordingStandard = factory.ToStringValue(element, "data/recording_standard");
21 | FormatVersion = factory.ToStringValue(element, "data/object/technical_metadata/format_version");
22 | }
23 |
24 | protected override List ImportFileProvenances(XElement element, string path,
25 | IImportableFactory factory)
26 | {
27 | return factory.ToObjectList(element, path)
28 | .Cast().ToList();
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Packager/Models/ProgramArgumentsModels/IProgramArguments.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.ProgramArgumentsModels
2 | {
3 | public interface IProgramArguments
4 | {
5 | bool Interactive { get; }
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/Packager/Models/ProgramArgumentsModels/ProgramArguments.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Linq;
3 |
4 | namespace Packager.Models.ProgramArgumentsModels
5 | {
6 | public class ProgramArguments : IProgramArguments
7 | {
8 | public ProgramArguments(string[] arguments)
9 | {
10 | Interactive = arguments.Any(a => a.Equals("-noninteractive", StringComparison.InvariantCultureIgnoreCase))==false;
11 | }
12 |
13 | public bool Interactive { get; }
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Models/ResultModels/DurationResult.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Models.ResultModels
4 | {
5 | public class DurationResult
6 | {
7 | public TimeSpan Duration { get; }
8 | public DateTime Timestamp { get; }
9 | public bool Succeeded { get; }
10 | public bool Failed { get; }
11 | public bool Skipped { get; }
12 | public string Issue { get; }
13 |
14 | public DurationResult(DateTime startTime, string baseIssue, params object[] args)
15 | : this(startTime, false, true, false, string.Format(baseIssue, args))
16 | {
17 |
18 | }
19 |
20 | private DurationResult(DateTime startTime, bool succeeded, bool failed, bool deferred, string issue)
21 | {
22 | Timestamp = startTime;
23 | Duration = DateTime.Now - startTime;
24 | Succeeded = succeeded;
25 | Failed = failed;
26 | Skipped = deferred;
27 | Issue = issue;
28 |
29 | }
30 |
31 | public static DurationResult Success(DateTime startTime) =>
32 | new DurationResult(startTime, true, false, false, "");
33 |
34 | public static DurationResult Deferred (DateTime startTime, string baseIssue, params object[] args) =>
35 | new DurationResult(startTime, false, false, true, string.Format(baseIssue, args));
36 | }
37 | }
--------------------------------------------------------------------------------
/Packager/Models/ResultModels/IProcessResult.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using Packager.Utilities;
3 | using Packager.Utilities.ProcessRunners;
4 |
5 | namespace Packager.Models.ResultModels
6 | {
7 | public interface IProcessResult
8 | {
9 | int ExitCode { get; set; }
10 |
11 | IOutputBuffer StandardOutput { get; }
12 |
13 | IOutputBuffer StandardError { get; }
14 |
15 | ProcessStartInfo StartInfo { get; set; }
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Models/ResultModels/ProcessResult.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using Packager.Utilities.ProcessRunners;
3 |
4 | namespace Packager.Models.ResultModels
5 | {
6 | public class ProcessResult : IProcessResult
7 | {
8 | public int ExitCode { get; set; }
9 | public IOutputBuffer StandardOutput { get; set; }
10 | public IOutputBuffer StandardError { get; set; }
11 | public ProcessStartInfo StartInfo { get; set; }
12 | }
13 | }
--------------------------------------------------------------------------------
/Packager/Models/SettingsModels/IProgramSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Forms.VisualStyles;
2 |
3 | namespace Packager.Models.SettingsModels
4 | {
5 | public interface IProgramSettings
6 | {
7 | string BwfMetaEditPath { get; }
8 | string FFMPEGPath { get; }
9 | string FFProbePath { get; }
10 | string InputDirectory { get; }
11 | string ProcessingDirectory { get; }
12 | string FFMPEGAudioProductionArguments { get; }
13 | string FFMPEGAudioAccessArguments { get; }
14 | string FFMPEGVideoMezzanineArguments { get; }
15 | string FFMPEGVideoAccessArguments { get; }
16 | string FFProbeVideoQualityControlArguments { get; }
17 | string ProjectCode { get; }
18 | string DropBoxDirectoryName { get; }
19 | string WebServiceUrl { get; }
20 | string ErrorDirectoryName { get; }
21 | string SuccessDirectoryName { get; }
22 | string LogDirectoryName { get; }
23 | string[] IssueNotifyEmailAddresses { get; }
24 | string[] SuccessNotifyEmailAddresses { get; }
25 | string[] DeferredNotifyEmailAddresses { get; }
26 | string SmtpServer { get; }
27 | string FromEmailAddress { get; }
28 | int DeleteSuccessfulObjectsAfterDays { get; }
29 | string UnitPrefix { get; }
30 | string PodAuthFilePath { get; }
31 | string DigitizingEntity { get; }
32 | string ImageDirectory { get; }
33 | }
34 | }
--------------------------------------------------------------------------------
/Packager/Models/SettingsModels/PodAuth.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Xml.Serialization;
3 | using Packager.Validators.Attributes;
4 |
5 | namespace Packager.Models.SettingsModels
6 | {
7 | [Serializable]
8 | [XmlRoot(ElementName = "Auth")]
9 | public class PodAuth
10 | {
11 | [XmlElement(ElementName = "username")]
12 | [Required]
13 | public string UserName { get; set; }
14 |
15 | [XmlElement(ElementName = "password")]
16 | [Required]
17 | public string Password { get; set; }
18 | }
19 | }
--------------------------------------------------------------------------------
/Packager/Models/UserInterfaceModels/SectionModel.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Models.UserInterfaceModels
2 | {
3 | public class SectionModel
4 | {
5 | public int StartOffset { get; set; }
6 | public int EndOffset { get; set; }
7 | public string Key { get; set; }
8 | public bool Completed { get; set; }
9 | public int Indent { get; set; }
10 | public string Title { get; set; }
11 | }
12 | }
--------------------------------------------------------------------------------
/Packager/NOTICE:
--------------------------------------------------------------------------------
1 | INDIANA UNIVERSITY MEDIA HELPER APPLICATIONS: PACKAGER
2 |
3 | Automates the process of creating derivatives and embedding metadata
4 | in digital media objects.
5 |
6 | Copyright (C) 2014-2017, The Trustees of Indiana University.
7 |
--------------------------------------------------------------------------------
/Packager/Observers/GeneralNLogObserver.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using NLog;
4 | using Packager.Extensions;
5 | using Packager.Models.SettingsModels;
6 |
7 | namespace Packager.Observers
8 | {
9 | public class GeneralNLogObserver : AbstractNLogObserver
10 | {
11 | private const string ThisLoggerName = "GeneralFileLogger";
12 |
13 | private static readonly Logger Logger = LogManager.GetLogger(ThisLoggerName);
14 |
15 | public GeneralNLogObserver(IProgramSettings settings):base(ThisLoggerName, settings)
16 | {
17 | }
18 |
19 | protected override void Log(IEnumerable events)
20 | {
21 | foreach (var logEvent in events.Where(e => e.Message.IsSet()))
22 | {
23 | Logger.Log(logEvent);
24 | }
25 | }
26 |
27 | protected override void LogEvent(LogEventInfo eventInfo)
28 | {
29 | Logger.Log(eventInfo);
30 | }
31 |
32 | public override int UniqueIdentifier => 1;
33 | }
34 | }
--------------------------------------------------------------------------------
/Packager/Observers/IObserver.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Observers
4 | {
5 | public interface IObserver
6 | {
7 | void Log(string baseMessage, params object[] elements);
8 | void LogProcessingError(Exception issue, string barcode);
9 | void LogEngineError(Exception issue);
10 | void BeginSection(string sectionKey, string baseMessage, params object[] elements);
11 | void EndSection(string sectionKey, string newTitle = "", bool collapse = false);
12 | int UniqueIdentifier { get; }
13 | }
14 | }
--------------------------------------------------------------------------------
/Packager/Observers/IObserverCollection.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 |
4 | namespace Packager.Observers
5 | {
6 | public interface IObserverCollection : ICollection
7 | {
8 | void Log(string baseMessage, params object[] elements);
9 | void LogProcessingIssue(Exception issue, string barcode);
10 | string BeginProcessingSection(string barcode, string baseMessage, params object[] elements);
11 | string BeginSection(string baseMessage, params object[] elements);
12 | void EndSection(string sectionKey, string newTitle = "", bool collapse = false);
13 | void LogEngineIssue(Exception exception);
14 | }
15 | }
--------------------------------------------------------------------------------
/Packager/Observers/LayoutRenderers/BarcodeLayoutRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using NLog;
3 | using NLog.LayoutRenderers;
4 |
5 | namespace Packager.Observers.LayoutRenderers
6 | {
7 | [LayoutRenderer("ProcessingDirectoryName")]
8 | public class BarcodeLayoutRenderer:LayoutRenderer
9 | {
10 | protected override void Append(StringBuilder builder, LogEventInfo logEvent)
11 | {
12 | if (logEvent.Properties.ContainsKey("Barcode"))
13 | {
14 | builder.Append(logEvent.Properties["Barcode"]);
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Packager/Observers/LayoutRenderers/LoggingDirectoryLayoutRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using NLog;
3 | using NLog.LayoutRenderers;
4 |
5 | namespace Packager.Observers.LayoutRenderers
6 | {
7 | [LayoutRenderer("LogDirectoryName")]
8 | public class LoggingDirectoryLayoutRenderer:LayoutRenderer
9 | {
10 | protected override void Append(StringBuilder builder, LogEventInfo logEvent)
11 | {
12 | if (logEvent.Properties.ContainsKey("LogDirectoryName"))
13 | {
14 | builder.Append(logEvent.Properties["LogDirectoryName"]);
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Packager/Observers/LayoutRenderers/ProcessingDirectoryNameLayoutRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using NLog;
3 | using NLog.LayoutRenderers;
4 |
5 | namespace Packager.Observers.LayoutRenderers
6 | {
7 | [LayoutRenderer("ProcessingDirectoryName")]
8 | public class ProcessingDirectoryNameLayoutRenderer : LayoutRenderer
9 | {
10 | protected override void Append(StringBuilder builder, LogEventInfo logEvent)
11 | {
12 | if (logEvent.Properties.ContainsKey("ProcessingDirectoryName"))
13 | {
14 | builder.Append(logEvent.Properties["ProcessingDirectoryName"]);
15 | }
16 | }
17 | }
18 | }
--------------------------------------------------------------------------------
/Packager/Observers/LayoutRenderers/ProjectCodeLayoutRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using NLog;
3 | using NLog.LayoutRenderers;
4 |
5 | namespace Packager.Observers.LayoutRenderers
6 | {
7 | [LayoutRenderer("ProcessingDirectoryName")]
8 | public class ProjectCodeLayoutRenderer:LayoutRenderer
9 | {
10 | protected override void Append(StringBuilder builder, LogEventInfo logEvent)
11 | {
12 | if (logEvent.Properties.ContainsKey("ProjectCode"))
13 | {
14 | builder.Append(logEvent.Properties["ProjectCode"]);
15 | }
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Packager/Observers/ObjectNLogObserver.cs:
--------------------------------------------------------------------------------
1 | using NLog;
2 | using Packager.Extensions;
3 | using Packager.Models.SettingsModels;
4 |
5 | namespace Packager.Observers
6 | {
7 | public class ObjectNLogObserver : AbstractNLogObserver
8 | {
9 | private const string ThisLoggerName = "ObjectFileLogger";
10 |
11 | public string CurrentBarcode { private get; set; }
12 |
13 | private static readonly Logger Logger = LogManager.GetLogger(ThisLoggerName);
14 |
15 | public ObjectNLogObserver(IProgramSettings settings) : base(ThisLoggerName, settings)
16 | {
17 |
18 | }
19 |
20 | public void ClearBarcode()
21 | {
22 | CurrentBarcode = string.Empty;
23 | }
24 |
25 | protected override LogEventInfo GetLogEvent(string message)
26 | {
27 | var logEvent = base.GetLogEvent(message);
28 | logEvent.Properties["Barcode"] = CurrentBarcode;
29 | return logEvent;
30 | }
31 |
32 | protected override void LogEvent(LogEventInfo eventInfo)
33 | {
34 | if (CurrentBarcode.IsNotSet())
35 | {
36 | return;
37 | }
38 |
39 | Logger.Log(eventInfo);
40 | }
41 |
42 | public override int UniqueIdentifier => 2;
43 | }
44 | }
--------------------------------------------------------------------------------
/Packager/Observers/ObserverCollectionEqualityComparer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Packager.Observers
4 | {
5 | internal class ObserverCollectionEqualityComparer : IEqualityComparer
6 | {
7 | public bool Equals(IObserver x, IObserver y)
8 | {
9 | return x.GetType() == y.GetType();
10 | }
11 |
12 | public int GetHashCode(IObserver obj)
13 | {
14 | return obj.UniqueIdentifier;
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Processors/IProcessor.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.FileModels;
5 | using Packager.Models.ResultModels;
6 | using Packager.Validators;
7 |
8 | namespace Packager.Processors
9 | {
10 | public interface IProcessor
11 | {
12 | Task ProcessObject(IGrouping fileModels, CancellationToken cancellationToken);
13 | }
14 | }
--------------------------------------------------------------------------------
/Packager/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Packager.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Packager/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Packager/Providers/IDirectoryProvider.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Threading.Tasks;
5 |
6 | namespace Packager.Providers
7 | {
8 | public interface IDirectoryProvider
9 | {
10 | IEnumerable EnumerateFiles(string path);
11 | DirectoryInfo CreateDirectory(string path);
12 | Task MoveDirectoryAsync(string sourcePath, string destPath);
13 | void MoveDirectory(string sourcePath, string destPath);
14 | bool DirectoryExists(string value);
15 |
16 | Task DeleteDirectoryAsync(string path);
17 |
18 | IEnumerable> GetFolderNamesAndCreationDates(string parent);
19 | }
20 | }
--------------------------------------------------------------------------------
/Packager/Providers/IFileProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.IO;
3 | using System.Threading;
4 | using System.Threading.Tasks;
5 |
6 | namespace Packager.Providers
7 | {
8 | public interface IFileProvider
9 | {
10 | Task CopyFileAsync(string sourceFileName, string destFileName, CancellationToken cancellationToken);
11 | Task MoveFileAsync(string sourceFileName, string destFileName, CancellationToken cancellationToken);
12 | bool FileExists(string path);
13 | bool FileDoesNotExist(string path);
14 | FileInfo GetFileInfo(string path);
15 | void AppendText(string path, string text);
16 | string ReadAllText(string path);
17 | Task ArchiveFile(string filePath, string archivePath, CancellationToken cancellationToken);
18 | T Deserialize(string filePath);
19 | }
20 | }
--------------------------------------------------------------------------------
/Packager/Providers/IMediaInfoProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using Packager.Models.FileModels;
4 |
5 | namespace Packager.Providers
6 | {
7 | public interface IMediaInfoProvider
8 | {
9 | Task GetMediaInfo(AbstractFile target, CancellationToken cancellationToken);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Packager/Providers/IPodMetadataProvider.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.FileModels;
5 | using Packager.Models.PodMetadataModels;
6 |
7 | namespace Packager.Providers
8 | {
9 | public interface IPodMetadataProvider
10 | {
11 | Task GetObjectMetadata(string barcode, CancellationToken cancellationToken) where T : AbstractPodMetadata, new();
12 | T AdjustMediaFormat(T podMetadata, List models) where T: AbstractPodMetadata;
13 | T AdjustDigitalProvenanceData(T podMetadata, List models) where T : AbstractPodMetadata;
14 | void Validate(T podMetadata, List models) where T : AbstractPodMetadata;
15 | void Log(T podMetadata) where T : AbstractPodMetadata;
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Providers/ISystemInfoProvider.cs:
--------------------------------------------------------------------------------
1 | using Packager.Engine;
2 |
3 | namespace Packager.Providers
4 | {
5 | public interface ISystemInfoProvider
6 | {
7 | string MachineName { get; }
8 | string CurrentSystemLogPath { get; }
9 | void ExitApplication(EngineExitCodes exitCode);
10 | }
11 | }
--------------------------------------------------------------------------------
/Packager/UserInterface/CancelPanel.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/Packager/UserInterface/CancelPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Packager.UserInterface
17 | {
18 | ///
19 | /// Interaction logic for CancelPanel.xaml
20 | ///
21 | public partial class CancelPanel : UserControl
22 | {
23 | public CancelPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Packager/UserInterface/IViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.UserInterface
2 | {
3 | public interface IViewModel
4 | {
5 | void Initialize(OutputWindow outputWindow, string projectCode);
6 | bool Processing { get; set; }
7 | string ProcessingMessage { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/Packager/UserInterface/LineGenerators/BarcodeSectionLineGenerator.cs:
--------------------------------------------------------------------------------
1 | using Common.UserInterface.LineGenerators;
2 | using Common.UserInterface.ViewModels;
3 | using ICSharpCode.AvalonEdit.Rendering;
4 |
5 | namespace Packager.UserInterface.LineGenerators
6 | {
7 | public class BarcodeElementGenerator:AbstractBarcodeElementGenerator
8 | {
9 | public BarcodeElementGenerator(ILogPanelViewModel viewModel)
10 | {
11 | ViewModel = viewModel;
12 | }
13 |
14 | public override VisualLineElement ConstructElement(int offset)
15 | {
16 | int matchOffset;
17 | var match = GetMatch(offset, out matchOffset);
18 | return match.Success
19 | ? new BarCodeLinkText(match.Value, CurrentContext.VisualLine, ViewModel)
20 | : null;
21 | }
22 |
23 | private ILogPanelViewModel ViewModel { get; }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Packager/Utilities/Bext/BextFields.cs:
--------------------------------------------------------------------------------
1 | using Packager.Attributes;
2 |
3 | namespace Packager.Utilities.Bext
4 | {
5 | public enum BextFields
6 | {
7 | [FFMPEGArgument("description")] Description,
8 | [FFMPEGArgument("originator")] Originator,
9 | [FFMPEGArgument("originator_reference")] OriginatorReference,
10 | [FFMPEGArgument("origination_date")] OriginationDate,
11 | [FFMPEGArgument("origination_time")] OriginationTime,
12 | [FFMPEGArgument("time_reference")] TimeReference,
13 | [FFMPEGArgument("coding_history")] History,
14 | [FFMPEGArgument("umid")] UMID,
15 | IARL,
16 | IART,
17 | ICMS,
18 | ICMT,
19 | ICOP,
20 | ICRD,
21 | IENG,
22 | IGNR,
23 | IKEY,
24 | IMED,
25 | INAM,
26 | IPRD,
27 | ISBJ,
28 | ISFT,
29 | ISRC,
30 | ISRF,
31 | ITCH
32 | }
33 | }
--------------------------------------------------------------------------------
/Packager/Utilities/Bext/IBextProcessor.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.FileModels;
5 |
6 | namespace Packager.Utilities.Bext
7 | {
8 | public interface IBextProcessor
9 | {
10 | Task ClearMetadataFields(List instances, List fields, CancellationToken cancellationToken);
11 | }
12 | }
--------------------------------------------------------------------------------
/Packager/Utilities/Email/IEmailSender.cs:
--------------------------------------------------------------------------------
1 | using Packager.Models.EmailMessageModels;
2 |
3 | namespace Packager.Utilities.Email
4 | {
5 | public interface IEmailSender
6 | {
7 | void Send(AbstractEmailMessage message);
8 | }
9 | }
--------------------------------------------------------------------------------
/Packager/Utilities/FileSystem/ISuccessFolderCleaner.cs:
--------------------------------------------------------------------------------
1 | using System.Threading.Tasks;
2 |
3 | namespace Packager.Utilities.FileSystem
4 | {
5 | public interface ISuccessFolderCleaner
6 | {
7 | bool Enabled { get; }
8 | string ConfiguredInterval { get; }
9 | Task DoCleaning();
10 | }
11 | }
--------------------------------------------------------------------------------
/Packager/Utilities/Hashing/IHasher.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using Packager.Models.FileModels;
4 |
5 | namespace Packager.Utilities.Hashing
6 | {
7 | public interface IHasher
8 | {
9 | Task Hash(AbstractFile model, CancellationToken cancellationToken);
10 | Task Hash(string path, CancellationToken cancellationToken);
11 | }
12 | }
--------------------------------------------------------------------------------
/Packager/Utilities/Images/ILabelImageImporter.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.FileModels;
5 | using Packager.Models.PodMetadataModels;
6 |
7 | namespace Packager.Utilities.Images
8 | {
9 | public interface ILabelImageImporter
10 | {
11 | Task> ImportMediaImages(string barcode, CancellationToken cancellationToken);
12 | bool LabelImagesPresent(AbstractPodMetadata metadata);
13 | }
14 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/ArgumentBuilder.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using Packager.Extensions;
5 |
6 | namespace Packager.Utilities.ProcessRunners
7 | {
8 | public class ArgumentBuilder : List
9 | {
10 | public ArgumentBuilder()
11 | {
12 | }
13 |
14 | public ArgumentBuilder(string arguments)
15 | {
16 | AddRange(arguments.Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries));
17 | }
18 |
19 | public ArgumentBuilder AddArguments(string arguments)
20 | {
21 | AddRange(arguments.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
22 | return this;
23 | }
24 |
25 | public ArgumentBuilder AddArguments(IEnumerable arguments)
26 | {
27 | AddRange(arguments.Select(a=>a.ToDefaultIfEmpty().Trim()).Where(a=>a.IsSet()));
28 | return this;
29 | }
30 |
31 | public ArgumentBuilder Clone()
32 | {
33 | return new ArgumentBuilder()
34 | .AddArguments(this);
35 | }
36 |
37 | public override string ToString()
38 | {
39 | return string.Join(" ", this);
40 | }
41 | }
42 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/FileOutputBuffer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Text;
3 | using Packager.Providers;
4 |
5 | namespace Packager.Utilities.ProcessRunners
6 | {
7 | public class FileOutputBuffer : IOutputBuffer, IDisposable
8 | {
9 | private readonly string _path;
10 | private readonly IFileProvider _fileProvider;
11 |
12 | private readonly StringBuilder _buffer = new StringBuilder();
13 |
14 | public FileOutputBuffer(string path, IFileProvider fileProvider)
15 | {
16 | _path = path;
17 | _fileProvider = fileProvider;
18 | }
19 |
20 | public void AppendLine(string value)
21 | {
22 | _buffer.AppendLine(value);
23 | if (_buffer.Length < 50000)
24 | {
25 | return;
26 | }
27 |
28 | Flush();
29 | }
30 |
31 | public string GetContent()
32 | {
33 | return _fileProvider.ReadAllText(_path);
34 | }
35 |
36 | private void Flush()
37 | {
38 | _fileProvider.AppendText(_path, _buffer.ToString());
39 | _buffer.Clear();
40 | }
41 |
42 | public void Dispose()
43 | {
44 | Flush();
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/IBwfMetaEditRunner.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.FileModels;
5 | using Packager.Models.ResultModels;
6 | using Packager.Utilities.Bext;
7 |
8 | namespace Packager.Utilities.ProcessRunners
9 | {
10 | public interface IBwfMetaEditRunner
11 | {
12 | string BwfMetaEditPath { get; }
13 | Task ClearMetadata(AbstractFile model, IEnumerable fields, CancellationToken cancellationToken);
14 | Task GetVersion();
15 | }
16 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/IFFMpegRunner.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.FileModels;
5 |
6 | namespace Packager.Utilities.ProcessRunners
7 | {
8 | public interface IFFMPEGRunner
9 | {
10 | string FFMPEGPath { get; set; }
11 |
12 | Task GetFFMPEGVersion();
13 |
14 | Task Normalize(AbstractFile original, ArgumentBuilder arguments, CancellationToken cancellationToken);
15 |
16 | Task Verify(List originals, CancellationToken cancellationToken);
17 |
18 | Task CreateProdOrMezzDerivative(AbstractFile original, AbstractFile target, ArgumentBuilder arguments, IEnumerable notes, CancellationToken cancellationToken);
19 |
20 | Task CreateAccessDerivative(AbstractFile original, ArgumentBuilder arguments, IEnumerable notes, CancellationToken cancellationToken);
21 | }
22 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/IFFProbeRunner.cs:
--------------------------------------------------------------------------------
1 | using System.Threading;
2 | using System.Threading.Tasks;
3 | using Packager.Models.FileModels;
4 |
5 | namespace Packager.Utilities.ProcessRunners
6 | {
7 | public interface IFFProbeRunner
8 | {
9 | string FFProbePath { get; }
10 | string VideoQualityControlArguments { get; }
11 | Task GenerateQualityControlFile(AbstractFile target, CancellationToken cancellationToken);
12 |
13 | Task GetVersion();
14 |
15 | Task GetMediaInfo(AbstractFile target, CancellationToken cancellation);
16 | }
17 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/IOutputBuffer.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Utilities.ProcessRunners
2 | {
3 | public interface IOutputBuffer
4 | {
5 | void AppendLine(string value);
6 | string GetContent();
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/IProcessRunner.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Threading;
3 | using System.Threading.Tasks;
4 | using Packager.Models.ResultModels;
5 |
6 | namespace Packager.Utilities.ProcessRunners
7 | {
8 | public interface IProcessRunner
9 | {
10 | Task Run(
11 | ProcessStartInfo startInfo,
12 | CancellationToken cancellationToken,
13 | IOutputBuffer outputBuffer = null,
14 | IOutputBuffer errorBuffer = null);
15 | }
16 | }
--------------------------------------------------------------------------------
/Packager/Utilities/ProcessRunners/StringOutputBuffer.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 |
3 | namespace Packager.Utilities.ProcessRunners
4 | {
5 | public class StringOutputBuffer : IOutputBuffer
6 | {
7 | private readonly StringBuilder _buffer = new StringBuilder();
8 |
9 | public void AppendLine(string value)
10 | {
11 | _buffer.AppendLine(value);
12 | }
13 |
14 | public string GetContent()
15 | {
16 | return _buffer.ToString();
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Packager/Utilities/Reporting/IReportWriter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using Packager.Models.ResultModels;
4 | using Packager.Validators;
5 |
6 | namespace Packager.Utilities.Reporting
7 | {
8 | public interface IReportWriter
9 | {
10 | void WriteResultsReport(Dictionary results, DateTime startTime);
11 | void WriteResultsReport(Exception e);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Packager/Utilities/Xml/IXmlExporter.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Utilities.Xml
2 | {
3 | public interface IXmlExporter
4 | {
5 | void ExportToFile(object o, string path);
6 | T ImportFromFile(string path) where T: class;
7 | }
8 | }
--------------------------------------------------------------------------------
/Packager/Utilities/Xml/XmlExporter.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Text;
3 | using System.Xml;
4 | using System.Xml.Serialization;
5 |
6 | namespace Packager.Utilities.Xml
7 | {
8 | public class XmlExporter : IXmlExporter
9 | {
10 | public void ExportToFile(object o, string path)
11 | {
12 | var settings = new XmlWriterSettings
13 | {
14 | Indent = true,
15 | Encoding = Encoding.UTF8
16 | };
17 | var xmlSerializer = new XmlSerializer(o.GetType());
18 |
19 | using (Stream stream = new FileStream(path, FileMode.Create))
20 | using (var xmlWriter = XmlWriter.Create(stream, settings))
21 | {
22 | xmlSerializer.Serialize(xmlWriter, o);
23 | }
24 | }
25 |
26 | public T ImportFromFile(string path) where T:class
27 | {
28 | var xmlSerializer = new XmlSerializer(typeof(T));
29 | using (var stream = new FileStream(path, FileMode.Open))
30 | {
31 | return xmlSerializer.Deserialize(stream) as T;
32 | }
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/HasMembersAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Validators.Attributes
2 | {
3 | public class HasMembersAttribute : PropertyValidationAttribute
4 | {
5 | }
6 | }
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/PropertyValidationAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Validators.Attributes
4 | {
5 | public abstract class PropertyValidationAttribute:Attribute
6 | {
7 |
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/RequiredAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Validators.Attributes
2 | {
3 | public class RequiredAttribute:PropertyValidationAttribute
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/ValidateFileAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Validators.Attributes
2 | {
3 | public class ValidateFileAttribute:PropertyValidationAttribute
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/ValidateFolderAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Validators.Attributes
2 | {
3 | public class ValidateFolderAttribute:PropertyValidationAttribute
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/ValidateObjectAttribute.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Validators.Attributes
4 | {
5 | internal class ValidateObjectAttribute : Attribute
6 | {
7 | }
8 | }
--------------------------------------------------------------------------------
/Packager/Validators/Attributes/ValidateUriAttribute.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Validators.Attributes
2 | {
3 | public class ValidateUriAttribute:PropertyValidationAttribute
4 | {
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Packager/Validators/DirectoryExistsValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 | using Packager.Providers;
4 | using Packager.Validators.Attributes;
5 |
6 | namespace Packager.Validators
7 | {
8 | public class DirectoryExistsValidator : IValidator
9 | {
10 | public DirectoryExistsValidator(IDirectoryProvider directoryProvider)
11 | {
12 | DirectoryProvider = directoryProvider;
13 | }
14 |
15 | private IDirectoryProvider DirectoryProvider { get; set; }
16 |
17 | public ValidationResult Validate(object value, string friendlyName)
18 | {
19 | return DirectoryProvider.DirectoryExists(value.ToDefaultIfEmpty())
20 | ? ValidationResult.Success
21 | : new ValidationResult("Invalid path specified for {0}: {1}", friendlyName, value.ToDefaultIfEmpty("[not set]"));
22 | }
23 |
24 | public Type Supports => typeof (ValidateFolderAttribute);
25 | }
26 | }
--------------------------------------------------------------------------------
/Packager/Validators/FileExistsValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 | using Packager.Providers;
4 | using Packager.Validators.Attributes;
5 |
6 | namespace Packager.Validators
7 | {
8 | public class FileExistsValidator : IValidator
9 | {
10 | public FileExistsValidator(IFileProvider fileProvider)
11 | {
12 | FileProvider = fileProvider;
13 | }
14 |
15 | private IFileProvider FileProvider { get; set; }
16 |
17 | public ValidationResult Validate(object value, string friendlyName)
18 | {
19 | return FileProvider.FileExists(value.ToDefaultIfEmpty())
20 | ? ValidationResult.Success
21 | : new ValidationResult("Invalid path specified for {0}: {1}", friendlyName, value.ToDefaultIfEmpty("[not set]"));
22 | }
23 |
24 | public Type Supports => typeof (ValidateFileAttribute);
25 | }
26 | }
--------------------------------------------------------------------------------
/Packager/Validators/IValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Packager.Validators
4 | {
5 | public interface IValidator
6 | {
7 | Type Supports { get; }
8 | ValidationResult Validate(object value, string friendlyName);
9 | }
10 | }
--------------------------------------------------------------------------------
/Packager/Validators/IValidatorCollection.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 |
3 | namespace Packager.Validators
4 | {
5 | public interface IValidatorCollection : ICollection
6 | {
7 | ValidationResults Validate(object instance);
8 | }
9 | }
--------------------------------------------------------------------------------
/Packager/Validators/UriValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 | using Packager.Validators.Attributes;
4 |
5 | namespace Packager.Validators
6 | {
7 | public class UriValidator : IValidator
8 | {
9 | public ValidationResult Validate(object value, string friendlyName)
10 | {
11 | return Uri.IsWellFormedUriString(value.ToDefaultIfEmpty(), UriKind.Absolute)
12 | ? ValidationResult.Success
13 | : new ValidationResult("Invalid uri specified for {0}: {1}", friendlyName, value.ToDefaultIfEmpty("[not set]"));
14 | }
15 |
16 | public Type Supports => typeof (ValidateUriAttribute);
17 | }
18 | }
--------------------------------------------------------------------------------
/Packager/Validators/ValidationResult.cs:
--------------------------------------------------------------------------------
1 | namespace Packager.Validators
2 | {
3 | public class ValidationResult
4 | {
5 | public ValidationResult(string baseIssue, params object[] args)
6 | : this(false, string.Format(baseIssue, args))
7 | {
8 |
9 | }
10 |
11 | protected ValidationResult(bool success, string issue)
12 | {
13 | Issue = issue;
14 | Result = success;
15 | }
16 |
17 | public static ValidationResult Success => new ValidationResult(true, "");
18 |
19 | public bool Result { get; set; }
20 | public string Issue { get; set; }
21 |
22 | }
23 | }
--------------------------------------------------------------------------------
/Packager/Validators/ValidationResults.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using System.Text;
4 | using Packager.Extensions;
5 |
6 | namespace Packager.Validators
7 | {
8 | public class ValidationResults : List
9 | {
10 | public bool Succeeded
11 | {
12 | get { return TrueForAll(r => r.Result); }
13 | }
14 |
15 | public IEnumerable Issues
16 | {
17 | get { return this
18 | .Where(v => v.Result == false)
19 | .Where(v => v.Issue.IsSet())
20 | .Select(v => v.Issue)
21 | .ToList(); }
22 | }
23 |
24 | public void Add(string issue, params object[] args)
25 | {
26 | Add(new ValidationResult(issue, args));
27 | }
28 |
29 | public string GetIssues(string baseMessage)
30 | {
31 | var builder = new StringBuilder();
32 | builder.AppendLine(baseMessage);
33 | foreach (var issue in Issues)
34 | {
35 | builder.AppendFormat(" {0}/n", issue);
36 | }
37 |
38 | return builder.ToString();
39 | }
40 | }
41 | }
--------------------------------------------------------------------------------
/Packager/Validators/ValueRequiredValidator.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Packager.Extensions;
3 | using Packager.Validators.Attributes;
4 |
5 | namespace Packager.Validators
6 | {
7 | public class ValueRequiredValidator : IValidator
8 | {
9 | public ValidationResult Validate(object value, string friendlyName)
10 | {
11 | return value.ToDefaultIfEmpty().IsSet()
12 | ? ValidationResult.Success
13 | : new ValidationResult("Value not set for {0}", friendlyName);
14 | }
15 |
16 | public Type Supports => typeof (RequiredAttribute);
17 | }
18 | }
--------------------------------------------------------------------------------
/Packager/Verifiers/IBwfMetaEditResultsVerifier.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using Packager.Observers;
3 |
4 | namespace Packager.Verifiers
5 | {
6 | public interface IBwfMetaEditResultsVerifier
7 | {
8 | bool Verify(string output, IEnumerable targetPaths);
9 | bool Verify(string output, string targetPath);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/Packager/copy to input.bat:
--------------------------------------------------------------------------------
1 | FOR %%A IN (%*) DO (copy %%A c:\work\mdpi)
2 |
--------------------------------------------------------------------------------
/Packager/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # IUMediaHelperApps
2 | This is the repository for the MDPI utilities that are required to run on the desktop of media engineers and QC operators.
3 |
4 | The two core utilities in this repository are the [IU Media Helper Recorder](Recorder/README.md) and the [IU Media Helper Packager](Packager/readme.md):
5 |
6 | * the [IU Media Helper Recorder](Recorder/README.md) provides a graphical user shell for FFMPEG, allowing video engineers better control over the video capture and processing pipeline.
7 | * the [IU Media Helper Packager](Packager/readme.md) is a post-processor that normalizes and embeds metadata into files generated by the audio and video engineers.
8 |
9 | For more details about each of these applications, please see the readme files in their repective repository folders.
10 |
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/Interop/RegistryAccess.cs:
--------------------------------------------------------------------------------
1 | using Microsoft.Win32;
2 |
3 | // Adapted from https://github.com/aelij/RawInputProcessor
4 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
5 | namespace Recorder.BarcodeScanner.Interop
6 | {
7 | internal static class RegistryAccess
8 | {
9 | private const string Prefix = @"\\?\";
10 |
11 | internal static RegistryKey GetDeviceKey(string device)
12 | {
13 | if (device == null || !device.StartsWith(Prefix)) return null;
14 | var array = device.Substring(Prefix.Length).Split('#');
15 | return array.Length < 3
16 | ? null
17 | : Registry.LocalMachine.OpenSubKey($@"System\CurrentControlSet\Enum\{array[0]}\{array[1]}\{array[2]}");
18 | }
19 |
20 | internal static string GetClassType(string classGuid)
21 | {
22 | var registryKey =
23 | Registry.LocalMachine.OpenSubKey("SYSTEM\\CurrentControlSet\\Control\\Class\\" + classGuid);
24 | if (registryKey == null)
25 | {
26 | return string.Empty;
27 | }
28 | return (string) registryKey.GetValue("Class");
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/KeyPressState.cs:
--------------------------------------------------------------------------------
1 | namespace Recorder.BarcodeScanner
2 | {
3 | // Adapted from https://github.com/aelij/RawInputProcessor
4 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
5 | public enum KeyPressState
6 | {
7 | Up,
8 | Down
9 | }
10 | }
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/RawDeviceType.cs:
--------------------------------------------------------------------------------
1 |
2 | // Adapted from https://github.com/aelij/RawInputProcessor
3 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
4 | namespace Recorder.BarcodeScanner
5 | {
6 | public enum RawDeviceType
7 | {
8 | Mouse,
9 | Keyboard,
10 | Hid
11 | }
12 | }
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/RawInput.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // Adapted from https://github.com/aelij/RawInputProcessor
4 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
5 | namespace Recorder.BarcodeScanner
6 | {
7 | public abstract class RawInput : IDisposable
8 | {
9 | private readonly RawKeyboard _keyboardDriver;
10 |
11 | public event EventHandler KeyPressed
12 | {
13 | add { KeyboardDriver.KeyPressed += value; }
14 | remove { KeyboardDriver.KeyPressed -= value; }
15 | }
16 |
17 | public int NumberOfKeyboards
18 | {
19 | get { return KeyboardDriver.NumberOfKeyboards; }
20 | }
21 |
22 | protected RawKeyboard KeyboardDriver
23 | {
24 | get { return _keyboardDriver; }
25 | }
26 |
27 | protected RawInput(IntPtr handle, RawInputCaptureMode captureMode)
28 | {
29 | _keyboardDriver = new RawKeyboard(handle, captureMode == RawInputCaptureMode.Foreground);
30 | }
31 |
32 | public abstract void AddMessageFilter();
33 | public abstract void RemoveMessageFilter();
34 |
35 | public void Dispose()
36 | {
37 | KeyboardDriver.Dispose();
38 | }
39 | }
40 | }
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/RawInputCaptureMode.cs:
--------------------------------------------------------------------------------
1 |
2 | // Adapted from https://github.com/aelij/RawInputProcessor
3 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
4 | namespace Recorder.BarcodeScanner
5 | {
6 | public enum RawInputCaptureMode
7 | {
8 | Foreground,
9 | ForegroundAndBackground,
10 | }
11 | }
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/RawInputEventArgs.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Input;
3 |
4 | // Adapted from https://github.com/aelij/RawInputProcessor
5 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
6 | namespace Recorder.BarcodeScanner
7 | {
8 | public sealed class RawInputEventArgs : EventArgs
9 | {
10 | public RawKeyboardDevice Device { get; private set; }
11 | public KeyPressState KeyPressState { get; private set; }
12 | public uint Message { get; private set; }
13 | public Key Key { get; private set; }
14 | public int VirtualKey { get; private set; }
15 | public bool Handled { get; set; }
16 |
17 | internal RawInputEventArgs(RawKeyboardDevice device, KeyPressState keyPressState, uint message, Key key,
18 | int virtualKey)
19 | {
20 | Device = device;
21 | KeyPressState = keyPressState;
22 | Message = message;
23 | Key = key;
24 | VirtualKey = virtualKey;
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/Recorder/BarcodeScanner/RawKeyboardDevice.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | // Adapted from https://github.com/aelij/RawInputProcessor
4 | // and http://www.codeproject.com/Articles/17123/Using-Raw-Input-from-C-to-handle-multiple-keyboard
5 | namespace Recorder.BarcodeScanner
6 | {
7 | public sealed class RawKeyboardDevice
8 | {
9 | public string Name { get; private set; }
10 | public RawDeviceType Type { get; private set; }
11 | public IntPtr Handle { get; private set; }
12 | public string Description { get; private set; }
13 |
14 | internal RawKeyboardDevice(string name, RawDeviceType type, IntPtr handle, string description)
15 | {
16 | Handle = handle;
17 | Type = type;
18 | Name = name;
19 | Description = description;
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return string.Format("Device\n Name: {0}\n Type: {1}\n Handle: {2}\n Name: {3}\n",
25 | Name,
26 | Type,
27 | Handle.ToInt64().ToString("X"),
28 | Description);
29 | }
30 | }
31 | }
--------------------------------------------------------------------------------
/Recorder/Controls/ActionButton.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for ActionButton.xaml
20 | ///
21 | public partial class ActionButton : UserControl
22 | {
23 | public ActionButton()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/ActionPanel.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Recorder/Controls/ActionPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for ActionPanel.xaml
20 | ///
21 | public partial class ActionPanel : UserControl
22 | {
23 | public ActionPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/AudioMeter.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Recorder/Controls/AudioMeter.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for AudioMeter.xaml
20 | ///
21 | public partial class AudioMeter : UserControl
22 | {
23 | public AudioMeter()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/BarcodePanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for BarcodePanel.xaml
20 | ///
21 | public partial class BarcodePanel : UserControl
22 | {
23 | public BarcodePanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/FinishPanel.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
16 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Recorder/Controls/FinishPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for FinishPanel.xaml
20 | ///
21 | public partial class FinishPanel : UserControl
22 | {
23 | public FinishPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/FrameStats.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for FrameStats.xaml
20 | ///
21 | public partial class FrameStats : UserControl
22 | {
23 | public FrameStats()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/NavigationPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for NavigationPanel.xaml
20 | ///
21 | public partial class NavigationPanel : UserControl
22 | {
23 | public NavigationPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/OutputPanel.xaml:
--------------------------------------------------------------------------------
1 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/Recorder/Controls/OutputPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for OutputPanel.xaml
20 | ///
21 | public partial class OutputPanel : UserControl
22 | {
23 | public OutputPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/RecordPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for RecordPanel.xaml
20 | ///
21 | public partial class RecordPanel : UserControl
22 | {
23 | public RecordPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Controls/YesNoQuestionPanel.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using System.Windows.Data;
9 | using System.Windows.Documents;
10 | using System.Windows.Input;
11 | using System.Windows.Media;
12 | using System.Windows.Media.Imaging;
13 | using System.Windows.Navigation;
14 | using System.Windows.Shapes;
15 |
16 | namespace Recorder.Controls
17 | {
18 | ///
19 | /// Interaction logic for YesNoQuestionPanel.xaml
20 | ///
21 | public partial class YesNoQuestionPanel : UserControl
22 | {
23 | public YesNoQuestionPanel()
24 | {
25 | InitializeComponent();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Recorder/Converters/BooleanToCollapsedConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace Recorder.Converters
7 | {
8 | internal class BooleanToCollapsedConverter : IValueConverter
9 | {
10 | #region IValueConverter Members
11 |
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | //reverse conversion (false=>Visible, true=>collapsed) on any given parameter
15 | var input = (null == parameter) ? (bool) value : !((bool) value);
16 | return (input) ? Visibility.Visible : Visibility.Collapsed;
17 | }
18 |
19 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
20 | {
21 | throw new NotImplementedException();
22 | }
23 |
24 | #endregion
25 | }
26 |
27 | }
--------------------------------------------------------------------------------
/Recorder/Converters/EmptyToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace Recorder.Converters
7 | {
8 | public class NullOrEmptyToVisibilityConverter : IValueConverter
9 | {
10 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
11 | {
12 | return string.IsNullOrWhiteSpace(value?.ToString()) ? Visibility.Collapsed : Visibility.Visible;
13 | }
14 |
15 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
16 | {
17 | throw new NotImplementedException();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Recorder/Converters/TimespanToStringConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Text;
6 | using System.Threading.Tasks;
7 | using System.Windows.Data;
8 |
9 | namespace Recorder.Converters
10 | {
11 | public class TimespanToStringConverter:IValueConverter
12 | {
13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14 | {
15 | if (!(value is TimeSpan))
16 | {
17 | return string.Empty;
18 | }
19 |
20 | var timespan = (TimeSpan) value;
21 | return $@"{timespan:hh\:mm\:ss\.ff}";
22 | }
23 |
24 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
25 | {
26 | throw new NotImplementedException();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/Recorder/Dialogs/UserControls.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Media;
4 | using Recorder.ViewModels;
5 |
6 | namespace Recorder.Dialogs
7 | {
8 | ///
9 | /// Interaction logic for MainWindow.xaml
10 | ///
11 | public partial class UserControls : Window
12 | {
13 | public UserControls()
14 | {
15 | InitializeComponent();
16 | }
17 |
18 | protected override void OnSourceInitialized(EventArgs e)
19 | {
20 | base.OnSourceInitialized(e);
21 |
22 | var handleInitialized = DataContext as IWindowHandleInitialized;
23 | handleInitialized?.WindowHandleInitialized(this);
24 |
25 | }
26 |
27 | private void OnWindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
28 | {
29 | var onClosing = DataContext as IClosing;
30 | if (onClosing == null)
31 | {
32 | return;
33 | }
34 |
35 | e.Cancel = onClosing.CancelWindowClose();
36 | }
37 | }
38 | }
--------------------------------------------------------------------------------
/Recorder/Enums/FileUses.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Threading.Tasks;
6 |
7 | namespace Recorder.Enums
8 | {
9 | public class FileUses
10 | {
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/Recorder/Exceptions/AbstractHandledException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Recorder.Exceptions
4 | {
5 | public class AbstractHandledException : Exception
6 | {
7 | public AbstractHandledException()
8 | {
9 | }
10 |
11 | public AbstractHandledException(string message) : base(message)
12 | {
13 | }
14 |
15 | public AbstractHandledException(string message, Exception innerException) : base(message, innerException)
16 | {
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Recorder/Exceptions/CombiningException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Recorder.Exceptions
4 | {
5 | public class CombiningException : AbstractHandledException
6 | {
7 | public CombiningException()
8 | {
9 | }
10 |
11 | public CombiningException(string message) : base(message)
12 | {
13 | }
14 |
15 | public CombiningException(string message, Exception innerException) : base(message, innerException)
16 | {
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Recorder/Exceptions/ConfigurationException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Recorder.Exceptions
4 | {
5 | public class ConfigurationException : AbstractHandledException
6 | {
7 | public ConfigurationException()
8 | {
9 | }
10 |
11 | public ConfigurationException(string message) : base(message)
12 | {
13 | }
14 |
15 | public ConfigurationException(string message, Exception innerException) : base(message, innerException)
16 | {
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Recorder/Exceptions/RecordingException.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace Recorder.Exceptions
4 | {
5 | public class RecordingException : AbstractHandledException
6 | {
7 | public RecordingException()
8 | {
9 | }
10 |
11 | public RecordingException(string message) : base(message)
12 | {
13 | }
14 |
15 | public RecordingException(string message, Exception innerException) : base(message, innerException)
16 | {
17 | }
18 | }
19 | }
--------------------------------------------------------------------------------
/Recorder/Extensions/UserInterfaceExtensions.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Media;
3 |
4 | namespace Recorder.Extensions
5 | {
6 | public static class DependencyObjectExtensions
7 | {
8 | public static T FindDescendant(this DependencyObject target) where T : DependencyObject
9 | {
10 | if (target == null) return default(T);
11 | var numberChildren = VisualTreeHelper.GetChildrenCount(target);
12 | if (numberChildren == 0) return default(T);
13 |
14 | for (var i = 0; i < numberChildren; i++)
15 | {
16 | var child = VisualTreeHelper.GetChild(target, i);
17 | var instance = child as T;
18 | if (instance != null)
19 | {
20 | return instance;
21 | }
22 | }
23 |
24 | for (var i = 0; i < numberChildren; i++)
25 | {
26 | var child = VisualTreeHelper.GetChild(target, i);
27 | var potentialMatch = FindDescendant(child);
28 | if (potentialMatch.Equals(default(T)) == false)
29 | {
30 | return potentialMatch;
31 | }
32 | }
33 |
34 | return default(T);
35 | }
36 | }
37 | }
--------------------------------------------------------------------------------
/Recorder/Handlers/AbstractProcessOutputHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 |
3 | namespace Recorder.Handlers
4 | {
5 | public abstract class AbstractProcessOutputHandler
6 | {
7 | public abstract void OnDataReceived(object sender, DataReceivedEventArgs args);
8 |
9 | public abstract void Reset();
10 | }
11 | }
--------------------------------------------------------------------------------
/Recorder/Handlers/CurrentFrameHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Text.RegularExpressions;
3 | using Recorder.ViewModels;
4 |
5 | namespace Recorder.Handlers
6 | {
7 | public class CurrentFrameHandler : AbstractProcessOutputHandler
8 | {
9 | private readonly Regex _currentFrameExpression = new Regex(@"frame=(.*\d+) fps");
10 | private readonly FrameStatsViewModel _viewModel;
11 |
12 | public CurrentFrameHandler(FrameStatsViewModel viewModel)
13 | {
14 | _viewModel = viewModel;
15 | }
16 |
17 | public override void OnDataReceived(object sender, DataReceivedEventArgs args)
18 | {
19 | if (string.IsNullOrWhiteSpace(args.Data))
20 | {
21 | return;
22 | }
23 |
24 | var match = _currentFrameExpression.Match(args.Data);
25 | if (match.Success == false)
26 | {
27 | return;
28 | }
29 |
30 | if (match.Groups.Count < 2)
31 | {
32 | return;
33 | }
34 |
35 | _viewModel.CurrentFrame = match.Groups[1].Value.Trim();
36 | }
37 |
38 | public override void Reset()
39 | {
40 | _viewModel.CurrentFrame = "0";
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/Recorder/Handlers/DroppedFramesHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Text.RegularExpressions;
3 | using Recorder.ViewModels;
4 |
5 | namespace Recorder.Handlers
6 | {
7 | public class DroppedFramesHandler:AbstractProcessOutputHandler
8 |
9 | {
10 | private readonly FrameStatsViewModel _viewModel;
11 | private readonly Regex _currentFrameExpression = new Regex(@"drop=(\d+)");
12 |
13 | public DroppedFramesHandler(FrameStatsViewModel viewModel)
14 | {
15 | _viewModel = viewModel;
16 | }
17 |
18 | public override void OnDataReceived(object sender, DataReceivedEventArgs args)
19 | {
20 | if (string.IsNullOrWhiteSpace(args.Data))
21 | {
22 | return;
23 | }
24 |
25 | var match = _currentFrameExpression.Match(args.Data);
26 | if (match.Success == false)
27 | {
28 | return;
29 | }
30 |
31 | if (match.Groups.Count < 2)
32 | {
33 | return;
34 | }
35 |
36 | _viewModel.DroppedFrames = match.Groups[1].Value.Trim();
37 | }
38 |
39 | public override void Reset()
40 | {
41 | _viewModel.DroppedFrames = "0";
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/Recorder/Handlers/DuplicateFrameHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Text.RegularExpressions;
3 | using Recorder.ViewModels;
4 |
5 | namespace Recorder.Handlers
6 | {
7 | public class DuplicateFrameHandler:AbstractProcessOutputHandler
8 | {
9 | private readonly FrameStatsViewModel _viewModel;
10 | private readonly Regex _currentFrameExpression = new Regex(@"dup=(\d+)");
11 |
12 | public DuplicateFrameHandler(FrameStatsViewModel viewModel)
13 | {
14 | _viewModel = viewModel;
15 | }
16 |
17 | public override void OnDataReceived(object sender, DataReceivedEventArgs args)
18 | {
19 | if (string.IsNullOrWhiteSpace(args.Data))
20 | {
21 | return;
22 | }
23 |
24 | var match = _currentFrameExpression.Match(args.Data);
25 | if (match.Success == false)
26 | {
27 | return;
28 | }
29 |
30 | if (match.Groups.Count < 2)
31 | {
32 | return;
33 | }
34 |
35 | _viewModel.DuplicateFrames = match.Groups[1].Value.Trim();
36 | }
37 |
38 | public override void Reset()
39 | {
40 | _viewModel.DuplicateFrames = "0";
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/Recorder/Handlers/OutputLogHandler.cs:
--------------------------------------------------------------------------------
1 | using System.Diagnostics;
2 | using System.Text;
3 | using Recorder.ViewModels;
4 |
5 | namespace Recorder.Handlers
6 | {
7 | public class OutputLogHandler: AbstractProcessOutputHandler
8 | {
9 | public OutputLogHandler(OutputWindowViewModel viewModel)
10 | {
11 | ViewModel = viewModel;
12 | }
13 |
14 | private OutputWindowViewModel ViewModel { get; }
15 |
16 | public override void OnDataReceived(object sender, DataReceivedEventArgs args)
17 | {
18 | if (string.IsNullOrWhiteSpace(args.Data))
19 | {
20 | return;
21 | }
22 |
23 | AppendLine(args.Data);
24 | }
25 |
26 | private void AppendLine(string text)
27 | {
28 | var builder = new StringBuilder(ViewModel.Text);
29 | builder.AppendLine(text);
30 | ViewModel.Text = builder.ToString();
31 | }
32 |
33 | public override void Reset()
34 | {
35 | if (ViewModel.Clear == false)
36 | {
37 | AppendLine("");
38 | AppendLine("------------------------------------------------------------------------");
39 | return;
40 | }
41 |
42 | ViewModel.Text = string.Empty;
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Recorder/Handlers/TimestampReceivedHandler.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Diagnostics;
3 | using System.Text.RegularExpressions;
4 | using Recorder.Utilities;
5 |
6 | namespace Recorder.Handlers
7 | {
8 | public class TimestampReceivedHandler:AbstractProcessOutputHandler
9 | {
10 | private RecordingEngine Recorder { get; }
11 | private readonly Regex _timestampExpression = new Regex(@"time=(\d{2}:\d{2}:\d{2}\.\d{2})");
12 |
13 | public TimestampReceivedHandler(RecordingEngine recorder)
14 | {
15 | Recorder = recorder;
16 | }
17 |
18 | public override void Reset()
19 | {
20 | Recorder.OnTimestampUpdated(new TimeSpan());
21 | }
22 |
23 | public override void OnDataReceived(object sender, DataReceivedEventArgs args)
24 | {
25 | if (string.IsNullOrWhiteSpace(args.Data))
26 | {
27 | return;
28 | }
29 |
30 | var match = _timestampExpression.Match(args.Data);
31 | if (match.Success == false)
32 | {
33 | return;
34 | }
35 |
36 | TimeSpan timeSpan;
37 | if (!TimeSpan.TryParse(match.Groups[1].ToString(), out timeSpan))
38 | {
39 | return;
40 | }
41 |
42 | Recorder.OnTimestampUpdated(timeSpan);
43 | }
44 | }
45 | }
--------------------------------------------------------------------------------
/Recorder/Models/AudioChannelsAndStreams.cs:
--------------------------------------------------------------------------------
1 | namespace Recorder.Models
2 | {
3 | public class AudioChannelsAndStreams
4 | {
5 | public string DisplayName { get; set; }
6 | public int Channels { get; set; }
7 | public int Streams { get; set; }
8 | public int Id { get; set; }
9 |
10 | public bool Is4Channels => Channels == 4;
11 |
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Recorder/NOTICE:
--------------------------------------------------------------------------------
1 | INDIANA UNIVERSITY MEDIA HELPER APPLICATIONS: RECORDER
2 |
3 | Provides a graphical user interface to help engineers use
4 | FFMPEG to digitize content from video media sources.
5 |
6 | Copyright (C) 2014-2017, The Trustees of Indiana University.
7 |
--------------------------------------------------------------------------------
/Recorder/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace Recorder.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Recorder/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Recorder/ReleaseNotes.txt:
--------------------------------------------------------------------------------
1 | 1.0.0.0 10/15/2015 initial release
2 | 1.1.0.0 10/15/2015 fixed issue displaying timestamps
3 | 1.2.0.0 10/22/2015 combiner should now write logs
4 | 1.3.0.0 11/03/2015 added audio meter
5 | added dropped, duplicate frames display
6 | 1.4.0.0 11/10/2015 changing how audio meter is configured
7 | adding configuration logging at startup
8 | removing unused dependencies
9 | 1.8.0.0 05/26/2016 Should now record 4 channels properly
10 | 1.9.0.0 05/27/2016 Should only keep first four channels of 8 channel input
11 | 2.0.0.0 06/20/2016 improvements to 4 channel recording
12 | 2.1.0.0 03/08/2017 add support for 2 channel, 2 mono streams recording
13 | 2.2.0.0 11/05/2018 add support for 1 channel mono stream recording
--------------------------------------------------------------------------------
/Recorder/Scripts/Internal/betacam_fix_internal.bat:
--------------------------------------------------------------------------------
1 | %1 -y -loglevel error -i %2 -f lavfi -i anullsrc=r=48000:cl=mono -f lavfi -i anullsrc=r=48000:cl=mono -codec:a pcm_s24le -codec:v copy -filter_complex "[0:a]pan=mono|c0=c0[a0];[0:a]pan=mono|c0=c1[a1]" -map 0:v -map "[a0]" -map "[a1]" -map 1:0 -map 2:0 -shortest %3
2 |
3 |
--------------------------------------------------------------------------------
/Recorder/Scripts/Internal/umatic_fix_internal.bat:
--------------------------------------------------------------------------------
1 | %1 -y -loglevel error -i %2 -y -codec:a pcm_s24le -codec:v copy -filter_complex "[0:a]pan=mono|c0=c0[a0];[0:a]pan=mono|c0=c1[a1]" -map 0:v -map "[a0]" -map "[a1]" %3
--------------------------------------------------------------------------------
/Recorder/Scripts/extract audio channels.bat:
--------------------------------------------------------------------------------
1 | c:\dependencies\ffmpeg\ffmpeg -i %1 -map 0:0 %~n1_0.wav
2 | c:\dependencies\ffmpeg\ffmpeg -i %1 -map 0:1 %~n1_1.wav
3 | c:\dependencies\ffmpeg\ffmpeg -i %1 -map 0:2 %~n1_2.wav
4 | c:\dependencies\ffmpeg\ffmpeg -i %1 -map 0:3 %~n1_3.wav
5 |
6 | pause
--------------------------------------------------------------------------------
/Recorder/Scripts/extract stereo to mono.bat:
--------------------------------------------------------------------------------
1 | c:\dependencies\ffmpeg\ffmpeg.exe -i %1 -y -map_channel 0.1.0 %~n1_left.wav -map_channel 0.1.1 %~n1_right.wav
2 | pause
--------------------------------------------------------------------------------
/Recorder/Scripts/umatic_fix.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 |
3 | echo.
4 | echo ***********************************************************
5 | echo * *
6 | echo * Umatic Fix *
7 | echo * *
8 | echo * Converts a video file (.mkv) with one stereo audio *
9 | echo * stream to one with 2 mono audio streams containing *
10 | echo * the content of the original's stereo channels. *
11 | echo * *
12 | echo ***********************************************************
13 | echo.
14 |
15 | set baseScriptPath=%~dp0
16 | set commonCodePath="%baseScriptPath%\Shared\common.bat"
17 | set internalFixCode="%baseScriptPath%\Internal\umatic_fix_internal.bat"
18 | set outputPath="%~p1%~n1_umatic_fix\%~n1%~x1"
19 |
20 | call %commonCodePath% %1 %internalFixCode% %outputPath%
21 |
22 | :Err
23 | echo.
24 |
25 | pause
26 |
27 | exit /B
--------------------------------------------------------------------------------
/Recorder/Utilities/ICanLogConfiguration.cs:
--------------------------------------------------------------------------------
1 | using Recorder.ViewModels;
2 |
3 | namespace Recorder.Utilities
4 | {
5 | public interface ICanLogConfiguration
6 | {
7 | void LogConfiguration(OutputWindowViewModel outputModel);
8 | }
9 | }
--------------------------------------------------------------------------------
/Recorder/ViewModels/AskExitViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Runtime.CompilerServices;
3 | using System.Windows;
4 | using System.Windows.Input;
5 | using Common.UserInterface.Commands;
6 | using JetBrains.Annotations;
7 |
8 | namespace Recorder.ViewModels
9 | {
10 | public class AskExitViewModel : AbstractNotifyModel, IClosing
11 | {
12 |
13 | private bool _exitNow;
14 |
15 | public AskExitViewModel()
16 | {
17 | YesText = "Yes";
18 | NoText = "No";
19 | Question = "Stop recording and exit?";
20 | YesCommand = new RelayCommand(
21 | param => DoExit());
22 | NoCommand = new RelayCommand(
23 | param => ShowPanel = false);
24 |
25 | }
26 |
27 |
28 | public bool CancelWindowClose()
29 | {
30 | FlashPanel = false;
31 |
32 | if (_exitNow)
33 | {
34 | return false;
35 | }
36 |
37 | ShowPanel = true;
38 | FlashPanel = true;
39 |
40 | return true;
41 | }
42 |
43 | private void DoExit()
44 | {
45 | _exitNow = true;
46 | Application.Current.MainWindow.Close();
47 | }
48 | }
49 | }
--------------------------------------------------------------------------------
/Recorder/ViewModels/IClosing.cs:
--------------------------------------------------------------------------------
1 | namespace Recorder.ViewModels
2 | {
3 | public interface IClosing
4 | {
5 | bool CancelWindowClose();
6 | }
7 | }
--------------------------------------------------------------------------------
/Recorder/ViewModels/IWindowHandleInitialized.cs:
--------------------------------------------------------------------------------
1 | using System.Windows.Media;
2 |
3 | namespace Recorder.ViewModels
4 | {
5 | public interface IWindowHandleInitialized
6 | {
7 | void WindowHandleInitialized(Visual client);
8 | }
9 | }
--------------------------------------------------------------------------------
/Recorder/ViewModels/IssueNotifyModel.cs:
--------------------------------------------------------------------------------
1 | using Common.UserInterface.Commands;
2 |
3 | namespace Recorder.ViewModels
4 | {
5 | public class IssueNotifyModel : AbstractNotifyModel
6 | {
7 | public IssueNotifyModel()
8 | {
9 | YesText = "Ok";
10 | YesCommand = new RelayCommand(param =>
11 | {
12 | ShowPanel = false;
13 | Question = string.Empty;
14 | });
15 | }
16 |
17 |
18 | public void Notify(string message)
19 | {
20 | FlashPanel = false;
21 | Question = message;
22 | ShowPanel = true;
23 | FlashPanel = true;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/Recorder/ViewModels/VolumeMeterViewModel.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using System.Configuration;
3 | using System.Runtime.CompilerServices;
4 | using System.Windows;
5 | using JetBrains.Annotations;
6 |
7 | namespace Recorder.ViewModels
8 | {
9 | public class VolumeMeterViewModel : INotifyPropertyChanged
10 | {
11 | private float _inputLevel;
12 | private Visibility _volumeMeterVisibility;
13 |
14 | public VolumeMeterViewModel()
15 | {
16 | VolumeMeterVisibility = Visibility.Collapsed;
17 | }
18 |
19 | public Visibility VolumeMeterVisibility
20 | {
21 | get { return _volumeMeterVisibility; }
22 | set { _volumeMeterVisibility = value; OnPropertyChanged(); }
23 | }
24 |
25 | public float InputLevel
26 | {
27 | get { return _inputLevel; }
28 | set
29 | {
30 | _inputLevel = value;
31 | OnPropertyChanged();
32 | }
33 | }
34 |
35 | public event PropertyChangedEventHandler PropertyChanged;
36 |
37 | [NotifyPropertyChangedInvocator]
38 | protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
39 | {
40 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
41 | }
42 | }
43 | }
--------------------------------------------------------------------------------
/Recorder/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Reporter/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | c:\work\logs
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Reporter/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Reporter/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Configuration;
3 | using System.Windows;
4 | using Common.UserInterface.ViewModels;
5 | using Reporter.Models;
6 | using Reporter.Utilities;
7 |
8 | namespace Reporter
9 | {
10 | ///
11 | /// Interaction logic for App.xaml
12 | ///
13 | public partial class App : Application
14 | {
15 | private void InitializeApplication(object sender, StartupEventArgs e)
16 | {
17 | var logPanelViewModel = new LogPanelViewModel();
18 | var settings = new ProgramSettings(ConfigurationManager.AppSettings);
19 | var reportReaders = new List()
20 | {
21 | new FileReportRenderer(settings, logPanelViewModel),
22 | new TaskSchedulerRenderer(logPanelViewModel)
23 | };
24 |
25 |
26 | var viewModel = new ViewModel(settings, reportReaders, logPanelViewModel);
27 | var reportWindow = new ReporterWindow
28 | {
29 | DataContext = viewModel
30 | };
31 |
32 | reportWindow.Show();
33 | }
34 |
35 | private void ApplicationExitHandler(object sender, ExitEventArgs e)
36 | {
37 |
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/Reporter/Converters/DisabledIfEmptyConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Globalization;
4 | using System.Linq;
5 | using System.Windows.Data;
6 | using Reporter.Models;
7 |
8 | namespace Reporter.Converters
9 | {
10 | class DisabledIfEmptyConverter:IValueConverter
11 | {
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
13 | {
14 | var list = value as BindingList;
15 | if (list == null)
16 | {
17 | return false;
18 | }
19 |
20 | return list.Any();
21 | }
22 |
23 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
24 | {
25 | throw new NotImplementedException();
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Reporter/LineGenerators/OpenObjectLogfileGenerator.cs:
--------------------------------------------------------------------------------
1 | using System.Dynamic;
2 | using Common.UserInterface.LineGenerators;
3 | using ICSharpCode.AvalonEdit.Rendering;
4 | using Reporter.Models;
5 |
6 | namespace Reporter.LineGenerators
7 | {
8 | public class OpenObjectLogfileGenerator:AbstractBarcodeElementGenerator
9 | {
10 | private ProgramSettings ProgramSettings { get; }
11 |
12 | public OpenObjectLogfileGenerator(ProgramSettings programSettings)
13 | {
14 | ProgramSettings = programSettings;
15 | }
16 |
17 | public override VisualLineElement ConstructElement(int offset)
18 | {
19 | int matchOffset;
20 | var match = GetMatch(offset, out matchOffset);
21 | return match.Success
22 | ? new OpenObjectLogFileLinkText(ProgramSettings.ReportFolder, match.Value, CurrentContext.VisualLine)
23 | : null;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Reporter/Models/AbstractReportEntry.cs:
--------------------------------------------------------------------------------
1 | namespace Reporter.Models
2 | {
3 | public abstract class AbstractReportEntry
4 | {
5 | public string DisplayName { get; set; }
6 | public long Timestamp { get; set; }
7 | }
8 | }
--------------------------------------------------------------------------------
/Reporter/Models/FileReportEntry.cs:
--------------------------------------------------------------------------------
1 | namespace Reporter.Models
2 | {
3 | public class FileReportEntry:AbstractReportEntry
4 | {
5 | public string Filename { get; set; }
6 | }
7 | }
--------------------------------------------------------------------------------
/Reporter/Models/ProgramSettings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Specialized;
2 | using Common.Extensions;
3 |
4 | namespace Reporter.Models
5 | {
6 | public class ProgramSettings
7 | {
8 | public ProgramSettings(NameValueCollection settings)
9 | {
10 | ProjectCode = GetStringValue(settings, "ProjectCode");
11 | }
12 |
13 | public string ProjectCode { get; }
14 |
15 | public string ReportFolder {
16 | get { return Properties.Settings.Default.ReportFolder; }
17 | set
18 | {
19 | Properties.Settings.Default.ReportFolder = value;
20 | Properties.Settings.Default.Save();
21 | }
22 | }
23 |
24 | // todo: move to common
25 | private static string GetStringValue(NameValueCollection settings, string name)
26 | {
27 | return settings[name].ToDefaultIfEmpty().ToUpperInvariant();
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/Reporter/Models/TaskSchedulerEntry.cs:
--------------------------------------------------------------------------------
1 | namespace Reporter.Models
2 | {
3 | public class TaskSchedulerEntry:AbstractReportEntry
4 | {
5 | public string Contents { get; set; }
6 | public string TaskName { get; set; }
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/Reporter/NOTICE:
--------------------------------------------------------------------------------
1 | INDIANA UNIVERSITY MEDIA HELPER APPLICATIONS: REPORTER
2 |
3 | Provides quick summaries of Packager logs.
4 |
5 | Copyright (C) 2014-2017, The Trustees of Indiana University.
6 |
--------------------------------------------------------------------------------
/Reporter/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | c:\work\logs
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Reporter/ReleaseNotes.txt:
--------------------------------------------------------------------------------
1 | 1.0.0.0 2/13/2017 initial release
2 | 1.1.0.0 3/20/2017 add functionality to display task-scheduler
3 | logs in instances where scheduled task did
4 | not run; fix issue opening logs in notepad.exe
5 | 1.2.0.0 1/17/2018 add support for deferred reports
6 |
--------------------------------------------------------------------------------
/Reporter/ReporterWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 |
3 | namespace Reporter
4 | {
5 | ///
6 | /// Interaction logic for MainWindow.xaml
7 | ///
8 | public partial class ReporterWindow : Window
9 | {
10 | public ReporterWindow()
11 | {
12 | InitializeComponent();
13 | }
14 |
15 | private async void OnLoadedHandler(object sender, RoutedEventArgs e)
16 | {
17 | var viewModel = DataContext as ViewModel;
18 | if (viewModel == null)
19 | {
20 | return;
21 | }
22 |
23 | await viewModel.Initialize(ReportText);
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Reporter/Utilities/IReportRenderer.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Threading.Tasks;
3 | using Common.Models;
4 | using Common.UserInterface.ViewModels;
5 | using Reporter.Models;
6 |
7 | namespace Reporter.Utilities
8 | {
9 | public interface IReportRenderer
10 | {
11 | Task> GetReports();
12 | Task Render(AbstractReportEntry reportEntry);
13 | bool CanRender(AbstractReportEntry report);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/Reporter/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Scheduler/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/Scheduler/NOTICE:
--------------------------------------------------------------------------------
1 | INDIANA UNIVERSITY MEDIA HELPER APPLICATIONS: SCHEDULER
2 |
3 | Command-line utility to configure Windows scheduled tasks.
4 |
5 | Copyright (C) 2014-2017, The Trustees of Indiana University.
6 |
--------------------------------------------------------------------------------
/Scheduler/OpenTaskScheduler.bat:
--------------------------------------------------------------------------------
1 | start taskschd.msc
--------------------------------------------------------------------------------
/Scheduler/Schedule.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | :: use schedule.exe
3 | scheduler.exe -days=monday,tuesday,wednesday,thursday,friday -start=19:00
4 |
5 | :: To use windows command, comment out following line
6 | :: schtasks /create /tn "Media Packager" /tr "%CD%\Packager.exe" /sc weekly /d MON,WED,THU,FRI /st 19:00
--------------------------------------------------------------------------------
/Scheduler/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/SetLogonAsBatchRight/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/SetLogonAsBatchRight/NOTICE:
--------------------------------------------------------------------------------
1 | INDIANA UNIVERSITY MEDIA HELPER APPLICATIONS: SET LOGON AS BATCH RIGHT
2 |
3 | Command-line utility to grant user logon-as-batch privileges.
4 |
5 | Copyright (C) 2014-2017, The Trustees of Indiana University.
6 |
--------------------------------------------------------------------------------
/WaveInfo/AbstractChunk.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 | using System.Text;
3 | using WaveInfo.Extensions;
4 |
5 | namespace WaveInfo
6 | {
7 | public abstract class AbstractChunk
8 | {
9 | public string Id { get; set; }
10 | public uint Size { get; set; }
11 | public uint ReportedSize { get; set; }
12 | public long Offset { get; set; }
13 |
14 | public virtual void ReadChunk(BinaryReader reader)
15 | {
16 | SetOffset(reader);
17 | SetSize(reader);
18 | }
19 |
20 | private void SetSize(BinaryReader reader)
21 | {
22 | ReportedSize = reader.ReadUInt32();
23 | Size = ReportedSize.Normalize();
24 | }
25 |
26 | private void SetOffset(BinaryReader reader)
27 | {
28 | Offset = reader.BaseStream.Position - 4;
29 | }
30 |
31 |
32 | public virtual string GetReport()
33 | {
34 | var builder = new StringBuilder();
35 |
36 | builder.AppendLine();
37 | builder.AppendLine($"{Id} chunk");
38 | builder.AppendLine(new string('-', 75));
39 | builder.AppendLine(this.ToColumns("Size"));
40 | builder.AppendLine(this.ToColumns("ReportedSize"));
41 | builder.AppendLine(this.ToColumns("Offset"));
42 |
43 | return builder.ToString();
44 | }
45 |
46 |
47 | }
48 | }
--------------------------------------------------------------------------------
/WaveInfo/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/WaveInfo/DataChunk.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace WaveInfo
4 | {
5 | public class DataChunk:AbstractChunk
6 | {
7 | public string Md5Hash { get; set; }
8 | }
9 | }
--------------------------------------------------------------------------------
/WaveInfo/Ds64Chunk.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace WaveInfo
4 | {
5 | public class Ds64Chunk : AbstractChunk
6 | {
7 | public ulong RiffSize { get; set; }
8 | public ulong DataSize { get; set; }
9 | public ulong SampleCount { get; set; }
10 | public uint TableLength { get; set; }
11 |
12 |
13 | public override void ReadChunk(BinaryReader reader)
14 | {
15 | base.ReadChunk(reader);
16 |
17 | RiffSize = reader.ReadUInt64();
18 | DataSize = reader.ReadUInt64();
19 | SampleCount = reader.ReadUInt64();
20 | TableLength = reader.ReadUInt32();
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/WaveInfo/Extensions/Uint64Extensions.cs:
--------------------------------------------------------------------------------
1 | namespace WaveInfo.Extensions
2 | {
3 | public static class SizeExtensions
4 | {
5 | public static uint Normalize(this uint value)
6 | {
7 | if (value%2 == 0)
8 | {
9 | return value;
10 | }
11 |
12 | return value + 1;
13 | }
14 |
15 |
16 | public static ulong Normalize(this ulong value)
17 | {
18 | if (value%2 == 0)
19 | {
20 | return value;
21 | }
22 |
23 | return value + 1;
24 | }
25 | }
26 | }
--------------------------------------------------------------------------------
/WaveInfo/FactChunk.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace WaveInfo
4 | {
5 | public class FactChunk:AbstractChunk
6 | {
7 | public uint Samples; //Number of audio frames;
8 | public override void ReadChunk(BinaryReader reader)
9 | {
10 | base.ReadChunk(reader);
11 |
12 | Samples = reader.ReadUInt32();
13 | }
14 | }
15 | }
--------------------------------------------------------------------------------
/WaveInfo/FormatChunk.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace WaveInfo
4 | {
5 | public class FormatChunk : AbstractChunk
6 | {
7 | public uint AvgBytesPerSec;
8 | public ushort BitsPerSample;
9 | public ushort BlockAlign;
10 | public ushort Channels;
11 | public ushort FormatTag;
12 | public uint SamplesPerSec;
13 | public ushort ExtensionSize;
14 | public ushort ValidBitsPerSample;
15 | public uint ChannelMask;
16 | public byte[] SubFormat;
17 | public override void ReadChunk(BinaryReader reader)
18 | {
19 | base.ReadChunk(reader);
20 |
21 | FormatTag = reader.ReadUInt16();
22 | Channels = reader.ReadUInt16();
23 | SamplesPerSec = reader.ReadUInt32();
24 | AvgBytesPerSec = reader.ReadUInt32();
25 | BlockAlign = reader.ReadUInt16();
26 | BitsPerSample = reader.ReadUInt16();
27 |
28 | if (Size == 16)
29 | {
30 | return;
31 | }
32 |
33 | ExtensionSize = reader.ReadUInt16();
34 | if (ExtensionSize == 0)
35 | {
36 | return;
37 | }
38 |
39 | ValidBitsPerSample = reader.ReadUInt16();
40 | ChannelMask = reader.ReadUInt32();
41 | SubFormat = reader.ReadBytes(16);
42 | }
43 | }
44 | }
--------------------------------------------------------------------------------
/WaveInfo/InfoChunk.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Text;
4 | using WaveInfo.Extensions;
5 |
6 | namespace WaveInfo
7 | {
8 | public class InfoChunk : AbstractChunk
9 | {
10 | public string Text { get; set; }
11 |
12 | public override void ReadChunk(BinaryReader reader)
13 | {
14 | base.ReadChunk(reader);
15 |
16 | Text = new string(reader.ReadChars(Convert.ToInt32(Size))).AppendEnd();
17 | }
18 |
19 | public override string GetReport()
20 | {
21 | var builder = new StringBuilder(base.GetReport());
22 | builder.AppendLine(this.ToColumns("Text"));
23 |
24 | return builder.ToString();
25 | }
26 | }
27 | }
--------------------------------------------------------------------------------
/WaveInfo/ListChunk.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.IO;
4 | using System.Linq;
5 | using System.Runtime.InteropServices;
6 | using System.Text;
7 | using System.Threading.Tasks;
8 |
9 | namespace WaveInfo
10 | {
11 | public class ListChunk:AbstractChunk
12 | {
13 | public string ListType;
14 | public override void ReadChunk(BinaryReader reader)
15 | {
16 | base.ReadChunk(reader);
17 |
18 | ListType = new string(reader.ReadChars(4));
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/WaveInfo/NOTICE:
--------------------------------------------------------------------------------
1 | INDIANA UNIVERSITY MEDIA HELPER APPLICATIONS: WAVEINFO
2 |
3 | Command-line utility to display embedded metadata properties in .WAV files.
4 |
5 | Copyright (C) 2014-2017, The Trustees of Indiana University.
6 |
--------------------------------------------------------------------------------
/WaveInfo/OtherChunk.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 |
4 | namespace WaveInfo
5 | {
6 | public class OtherChunk : AbstractChunk
7 | {
8 | public byte[] Data { get; set; }
9 | public override void ReadChunk(BinaryReader reader)
10 | {
11 | base.ReadChunk(reader);
12 |
13 | reader.BaseStream.Seek(Size, SeekOrigin.Current);
14 | //Data = reader.ReadBytes(Convert.ToInt32(Size));
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/WaveInfo/RiffChunk.cs:
--------------------------------------------------------------------------------
1 | using System.IO;
2 |
3 | namespace WaveInfo
4 | {
5 | public class RiffChunk : AbstractChunk
6 | {
7 | public uint FileLength; //In bytes, measured from offset 8
8 | public string RiffType; //WAVE, usually
9 |
10 | public override void ReadChunk(BinaryReader reader)
11 | {
12 | base.ReadChunk(reader);
13 |
14 | RiffType = new string(reader.ReadChars(4));
15 | }
16 | }
17 | }
--------------------------------------------------------------------------------
/WaveInfo/WaveFile.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 |
4 | namespace WaveInfo
5 | {
6 | public class WaveFile
7 | {
8 | public string FileName { get; set; }
9 | public long FileSize { get; set; }
10 |
11 | public List Chunks { get; set; }
12 |
13 | public T GetChunk() where T : AbstractChunk
14 | {
15 | if (Chunks == null || !Chunks.Any())
16 | {
17 | return null;
18 | }
19 |
20 | return Chunks.FirstOrDefault(c => c.GetType() == typeof (T)) as T;
21 | }
22 | }
23 | }
--------------------------------------------------------------------------------
/deploy.bat:
--------------------------------------------------------------------------------
1 | rmdir %2 /s /q
2 | mkdir %2
3 | copy %1\*.exe %2
4 | copy %1\*.config %2
5 | copy %1\*.dll %2
6 | copy %1\*.doc %2
7 | copy %1\*.docx %2
8 | copy %1\*.txt %2
9 | copy %1\*.bat %2
10 | del %2\*.vshost.exe
11 | del %2\*.vshost.exe.config
12 | ren %2\*.exe.config *.config.dev
13 |
--------------------------------------------------------------------------------
/example barcodes.txt:
--------------------------------------------------------------------------------
1 | 8 mm Video 40000000300063 https://pod.mdpi.iu.edu/responses/objects/40000000300063/metadata/digital_provenance
2 | Umatic 40000002133314 https://pod.mdpi.iu.edu/responses/objects/40000002133314/metadata/digital_provenance
3 | Betamax 40000002441915 https://pod.mdpi.iu.edu/responses/objects/40000002441915/metadata/digital_provenance
4 | Cylinder 40000001327644 https://pod.mdpi.iu.edu/responses/objects/40000001327644/metadata/digital_provenance
5 | Lacquer Disc 40000001312158 https://pod.mdpi.iu.edu/responses/objects/40000001312158/metadata/digital_provenance
6 | Open Reel Audio Tape 40000001211368 https://pod.mdpi.iu.edu/responses/objects/40000001211368/metadata/digital_provenance
7 | Open Reel Audio Tape 45000000243771 https://pod.mdpi.iu.edu/responses/objects/45000000243771/metadata/digital_provenance
8 | Open Reel Audio Tape (stereo) 40000000089633 https://pod.mdpi.iu.edu/responses/objects/40000000089633/metadata/digital_provenance
9 |
--------------------------------------------------------------------------------
/reference/IU_PID_1.0_technical_only.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IUMDPI/IUMediaHelperApps/32afb704dc9c7691ca0b0f1c3ff01b8bbd451f53/reference/IU_PID_1.0_technical_only.docx
--------------------------------------------------------------------------------
/reference/InputTemplate.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IUMDPI/IUMediaHelperApps/32afb704dc9c7691ca0b0f1c3ff01b8bbd451f53/reference/InputTemplate.xlsx
--------------------------------------------------------------------------------
/reference/ReferenceInformation.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IUMDPI/IUMediaHelperApps/32afb704dc9c7691ca0b0f1c3ff01b8bbd451f53/reference/ReferenceInformation.txt
--------------------------------------------------------------------------------
/reference/mdpi_embeddedMD_audio_20150519.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/IUMDPI/IUMediaHelperApps/32afb704dc9c7691ca0b0f1c3ff01b8bbd451f53/reference/mdpi_embeddedMD_audio_20150519.docx
--------------------------------------------------------------------------------