/// <summary>
        /// Handles the click event for the View File button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event</param>
        private void ViewFile_Click(object sender, RoutedEventArgs e)
        {
            State previous = this.currentState;

            this.WaitMessageText = Strings.WaitForViewFile;
            this.CurrentState    = State.Wait;

            try
            {
                string filePath = this.OpenFileForInspection();

                if (!string.IsNullOrEmpty(filePath))
                {
                    this.eventFile = this.client.OpenEventFile(filePath);
                    this.fileData  = new FileData(this.eventFile);
                    this.ViewFileDataGrid.DataContext = this.fileData;

                    // show the data
                    this.CurrentState = State.ViewFile;
                }
                else
                {
                    // user canceled the OpenFileDialog, return to previous state
                    this.CurrentState = previous;
                }
            }
            catch (Exception ex)
            {
                this.ErrorMessageText = string.Format(Strings.ErrorLoadFileFailed, ex.Message);
                this.CurrentState     = State.Error;
            }
        }
        /// <summary>
        /// Handles the click event for the Exit button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event</param>
        private void Exit_Click(object sender, RoutedEventArgs e)
        {
            if (this.eventFile != null)
            {
                this.eventFile.Dispose();
                this.eventFile = null;
            }

            this.Close();
        }
        /// <summary>
        /// Handles the click event for the Exit button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event</param>
        private void CloseFile_Click(object sender, RoutedEventArgs e)
        {
            if (this.eventFile != null)
            {
                this.eventFile.Dispose();
                this.eventFile = null;
            }

            this.fileData     = null;
            this.CurrentState = State.Welcome;
        }
Exemple #4
0
        private static Guid GetFileId(string targetAlias, KStudioClipSource clipSource)
        {
            Debug.Assert(clipSource != null);

            Guid value = clipSource.Id;

            if (value == Guid.Empty)
            {
                KStudioEventFile file = clipSource as KStudioEventFile;
                if (file == null)
                {
                    throw new ArgumentOutOfRangeException("clipSource", "not a KStudioEventFile");
                }
                else
                {
                    // File did not have a real identifier (legacy file), so create one that is "reasonable"

                    string fileNameUpper = file.FilePath.ToUpperInvariant();
                    int    fullPathHash  = fileNameUpper.GetHashCode();
                    fileNameUpper = Path.GetFileName(fileNameUpper.Reverse());
                    int fileNameHash = fileNameUpper.GetHashCode();

                    if (targetAlias == null)
                    {
                        value = new Guid((UInt32)fullPathHash,
                                         (UInt16)fileNameHash,
                                         (UInt16)(((UInt32)fileNameHash) >> 16),
                                         0, 0, 0, 0, 0, 0, 0, 0);
                    }
                    else
                    {
                        string targetAliasUpper = targetAlias.ToUpperInvariant();
                        UInt32 targetAliasHash1 = (UInt32)targetAliasUpper.GetHashCode();
                        targetAliasUpper = targetAliasUpper.Reverse();
                        UInt32 targetAliasHash2 = (UInt32)targetAliasUpper.GetHashCode();

                        value = new Guid((UInt32)fullPathHash,
                                         (UInt16)fileNameHash,
                                         (UInt16)(((UInt32)fileNameHash) >> 16),
                                         (byte)targetAliasHash1,
                                         (byte)(targetAliasHash1 >> 8),
                                         (byte)(targetAliasHash1 >> 16),
                                         (byte)(targetAliasHash1 >> 24),
                                         (byte)targetAliasHash2,
                                         (byte)(targetAliasHash2 >> 8),
                                         (byte)(targetAliasHash2 >> 16),
                                         (byte)(targetAliasHash2 >> 24));
                    }
                }
            }

            return(value);
        }
Exemple #5
0
        public void SaveStreamSelection()
        {
            Debug.Assert(this.clipSource != null);

            if (this.fileSettingsService != null)
            {
                XElement streamsElement = null;

                if (this.targetAlias == null)
                {
                    streamsElement = this.fileSettingsService.GetSettings(this.clipSource, "streams");
                }
                else
                {
                    streamsElement = this.fileSettingsService.GetSettings(targetAlias, this.clipSource, "streams");
                }

                if (streamsElement != null)
                {
                    streamsElement.RemoveNodes();

                    KStudioEventFile eventFile = this.clipSource as KStudioEventFile;
                    if (eventFile != null)
                    {
                        foreach (KStudioEventStream s in eventFile.EventStreams)
                        {
                            EventStreamState ess = s.UserState as EventStreamState;
                            if (ess != null)
                            {
                                if (ess.SelectedLivePlaybackStream != null)
                                {
                                    XElement streamElement = new XElement("stream");
                                    streamElement.SetAttributeValue("dataTypeId", s.DataTypeId);
                                    streamElement.SetAttributeValue("fileSemanticId", s.SemanticId);
                                    streamElement.SetAttributeValue("liveSemanticId", ess.SelectedLivePlaybackStream.SemanticId);

                                    EventStreamState ess2 = ess.SelectedLivePlaybackStream.UserState as EventStreamState;
                                    if (ess2 != null)
                                    {
                                        if (ess2.IsSelectedForTargetPlayback)
                                        {
                                            streamElement.SetAttributeValue("selected", true.ToString());
                                        }
                                    }

                                    streamsElement.Add(streamElement);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemple #6
0
        public KinectFile(string filePath)
        {
            if (string.IsNullOrEmpty(filePath))
            {
                return;
            }

            var client = KStudio.CreateClient();

            _currentKinectFile = client.OpenEventFile(filePath);

            _streams = new List <KinectStream>();
            LoadStreams(_currentKinectFile.EventStreams);
        }
Exemple #7
0
        public TimelineMarkersCollection(string targetAlias, KStudioEventFile file)
            : base(targetAlias, file)
        {
            DebugHelper.AssertUIThread();

            if (file != null)
            {
                foreach (KStudioMarker marker in file.Markers)
                {
                    TimelineMarker markerProxy = new TimelineMarker(this, marker.RelativeTime, marker);

                    this.Points.Add(markerProxy);
                }
            }
        }
Exemple #8
0
        /// <summary>
        /// Verifies that the streams selected for playback exist in the file and are capable of being played on the service
        /// </summary>
        /// <param name="client">KStudioClient which is connected to the Kinect service</param>
        /// <param name="filePath">Path to file that will be played back</param>
        /// <param name="playbackStreams">Collection of streams which have been selected for playback</param>
        private static void VerifyStreamsForPlayback(KStudioClient client, string filePath, IEnumerable <Guid> playbackStreams)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            if (!client.IsServiceConnected)
            {
                throw new InvalidOperationException(Strings.ErrorNotConnected);
            }

            if (string.IsNullOrEmpty(filePath))
            {
                throw new ArgumentNullException("filePath");
            }

            if (playbackStreams == null)
            {
                throw new ArgumentNullException("playbackStreams");
            }

            // verify stream exists in the file
            using (KStudioEventFile file = client.OpenEventFile(filePath))
            {
                HashSet <Guid> fileStreams = new HashSet <Guid>();
                foreach (KStudioEventStream stream in file.EventStreams)
                {
                    fileStreams.Add(stream.DataTypeId);
                }

                if (!fileStreams.IsSupersetOf(playbackStreams))
                {
                    Guid invalidStream = playbackStreams.First(x => !fileStreams.Contains(x));
                    throw new InvalidOperationException(string.Format(Strings.ErrorPlaybackStreamNotInFile, StreamSupport.ConvertStreamGuidToString(invalidStream)));
                }
            }

            // verify stream is supported for playback by the Kinect sensor
            foreach (Guid stream in playbackStreams)
            {
                KStudioEventStream eventStream = client.GetEventStream(stream, KStudioEventStreamSemanticIds.KinectDefaultSensorConsumer);
                if (!eventStream.IsPlaybackable)
                {
                    throw new InvalidOperationException(string.Format(Strings.ErrorPlaybackStreamNotSupported, StreamSupport.ConvertStreamGuidToString(stream)));
                }
            }
        }
Exemple #9
0
        /// <summary>
        /// Initializes a new instance of the FileData class and sets all properties to the values found within the KStudioEventFile object
        /// </summary>
        /// <param name="eventFile">A KStudioEventFile that is currently opened for read access</param>
        public FileData(KStudioEventFile eventFile)
        {
            if (eventFile == null)
            {
                throw new ArgumentNullException("eventFile");
            }

            this.FileName = eventFile.FilePath;
            this.PublicMetadata = eventFile.GetMetadata(KStudioMetadataType.Public);
            this.PersonalMetadata = eventFile.GetMetadata(KStudioMetadataType.PersonallyIdentifiableInformation);
            this.Streams = new ObservableCollection<StreamData>();
            foreach (KStudioEventStream stream in eventFile.EventStreams)
            {
                this.Streams.Add(new StreamData(stream));
            }
        }
Exemple #10
0
        /// <summary>
        /// Initializes a new instance of the FileData class and sets all properties to the values found within the KStudioEventFile object
        /// </summary>
        /// <param name="eventFile">A KStudioEventFile that is currently opened for read access</param>
        public FileData(KStudioEventFile eventFile)
        {
            if (eventFile == null)
            {
                throw new ArgumentNullException("eventFile");
            }

            this.FileName         = eventFile.FilePath;
            this.PublicMetadata   = eventFile.GetMetadata(KStudioMetadataType.Public);
            this.PersonalMetadata = eventFile.GetMetadata(KStudioMetadataType.PersonallyIdentifiableInformation);
            this.Streams          = new ObservableCollection <StreamData>();
            foreach (KStudioEventStream stream in eventFile.EventStreams)
            {
                this.Streams.Add(new StreamData(stream));
            }
        }
Exemple #11
0
        static void Main(string[] args)
        {
            if (args.Length < 1)
            {
                Console.WriteLine("ERROR: Missing filename");
                return;
            }
            if (args.Length < 2)
            {
                Console.WriteLine("ERROR: Missing output directory");
                return;
            }
            string fileName  = args[0];
            string outputDir = args[1];

            var outputDirPath = Environment.CurrentDirectory + "/" + outputDir;

            if (Directory.Exists(outputDirPath))
            {
                Directory.Delete(outputDirPath, true);
            }
            Directory.CreateDirectory(outputDirPath);
            Console.WriteLine(fileName);
            KStudioClient    client = KStudio.CreateClient();
            KStudioEventFile file   = client.OpenEventFile(fileName);

            foreach (KStudioSeekableEventStream stream in file.EventStreams)
            {
                if (stream.DataTypeName.Equals("Nui Uncompressed Color"))
                {
                    int    width     = 1920;
                    int    height    = 1080;
                    byte[] bufferYuv = new byte[width * height * 2];
                    uint   length    = stream.EventCount;
                    for (uint i = 0; i < length; i++)
                    {
                        var currentEvent = stream.ReadEvent(i);
                        currentEvent.CopyEventDataToArray(bufferYuv, 0);
                        string filePath = outputDirPath + "/" + i.ToString("D4");
                        File.WriteAllBytes(filePath, bufferYuv);
                    }
                }
            }
        }
Exemple #12
0
        /// <summary>
        /// Updates (add/edits) stream-level metadata in an event file
        /// </summary>
        /// <param name="client">KStudioClient to use for accessing the event file</param>
        /// <param name="fileName">Path to event file</param>
        /// <param name="streamName">Name of stream which should contain the metadata</param>
        /// <param name="type">Type of metadata to update (Public or Personal)</param>
        /// <param name="key">Key of metadata object to add/edit</param>
        /// <param name="value">Value of metadata object to add/edit</param>
        /// <returns>String which contains the updated contents of the target metadata object</returns>
        public static string UpdateStreamMetadata(KStudioClient client, string fileName, string streamName, KStudioMetadataType type, string key, object value)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            if (string.IsNullOrEmpty(streamName))
            {
                throw new ArgumentNullException("streamName");
            }

            string metadataText = string.Empty;

            using (KStudioEventFile file = client.OpenEventFileForEdit(fileName))
            {
                // find the stream in the file and alter its metadata
                Guid dataTypeId = StreamSupport.ConvertStreamStringToGuid(streamName);
                if (dataTypeId == KStudioEventStreamDataTypeIds.Null)
                {
                    throw new InvalidOperationException(Strings.ErrorNullStream);
                }

                KStudioEventStream stream = file.EventStreams.FirstOrDefault(s => s.DataTypeId == dataTypeId);
                if (stream != null)
                {
                    KStudioMetadata metadata = stream.GetMetadata(type);
                    Metadata.AlterMetadata(metadata, key, value);
                    metadataText = Metadata.GetMetadataAsText(metadata, type, stream.DataTypeName);
                }
            }

            return(metadataText);
        }
Exemple #13
0
        /// <summary>
        /// Updates (adds/edits) file-level metadata in an event file
        /// </summary>
        /// <param name="client">KStudioClient to use for accessing the event file</param>
        /// <param name="fileName">Path to event file</param>
        /// <param name="type">Type of metadata (Public or Personal)</param>
        /// <param name="key">Key of metadata object to add/edit</param>
        /// <param name="value">Value of metadata object to add/edit</param>
        /// <returns>String which contains the updated contents of the target metadata object</returns>
        public static string UpdateFileMetadata(KStudioClient client, string fileName, KStudioMetadataType type, string key, object value)
        {
            if (client == null)
            {
                throw new ArgumentNullException("client");
            }

            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }

            string metadataText = string.Empty;

            using (KStudioEventFile file = client.OpenEventFileForEdit(fileName))
            {
                KStudioMetadata metadata = file.GetMetadata(type);
                Metadata.AlterMetadata(metadata, key, value);
                metadataText = Metadata.GetMetadataAsText(metadata, type, string.Empty);
            }

            return(metadataText);
        }
        public WritableMetadataProxy(KStudioEventFile file, KStudioEventStream stream, KStudioMetadata metadata)
        {
            DebugHelper.AssertUIThread();

            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (metadata == null)
            {
                throw new ArgumentNullException("metadata");
            }

            this.file     = file as KStudioWritableEventFile;
            this.stream   = stream;
            this.metadata = metadata;
            this.metadata.CollectionChanged += Notify_CollectionChanged;

            lock (this.metadata)
            {
                LoadCollection();
            }
        }
        /// <summary>
        /// Handles the click event for the 'Compare Files' button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event args</param>
        private void CompareFiles_Click(object sender, RoutedEventArgs e)
        {
            State previous = this.currentState;
            this.WaitMessageText = Strings.WaitForCompareFiles;
            this.CurrentState = State.Wait;

            string file1 = string.Empty;
            string file2 = string.Empty;
            KStudioEventFile eventFile2 = null;

            try
            {
                // open the first file, if not already opened for View
                if (this.fileData == null)
                {
                    // open a new file
                    file1 = this.OpenFileForInspection();

                    // if user cancels from OpenFileDialog, return to previous state
                    if (string.IsNullOrEmpty(file1))
                    {
                        this.CurrentState = previous;
                        return;
                    }
                }

                // open a second file to compare with the first
                file2 = this.OpenFileForInspection();

                // if the user cancels from OpenFileDialog, return to the previous state
                if (string.IsNullOrEmpty(file2))
                {
                    this.CurrentState = previous;
                    return;
                }

                // create a FileData object for the first file, unless one already exists
                if (this.fileData == null)
                {
                    this.eventFile = this.client.OpenEventFile(file1);
                    this.fileData = new FileData(this.eventFile);
                }

                // create a second FileData object for comparison
                eventFile2 = this.client.OpenEventFile(file2);
                FileData fileData2 = new FileData(eventFile2);

                // compare data between files
                CompareFileData compareData = new CompareFileData(this.fileData, fileData2);
                this.ViewCompareFileDataGrid.DataContext = compareData;

                // show comparison data
                this.CurrentState = State.Compare;
            }
            catch (Exception ex)
            {
                this.ErrorMessageText = string.Format(Strings.ErrorCompareFilesFailed, ex.Message);
                this.CurrentState = State.Error;
            }
            finally
            {
                if (eventFile2 != null)
                {
                    eventFile2.Dispose();
                    eventFile2 = null;
                }
            }
        }
Exemple #16
0
        /// <summary>
        /// Handles the click event for the 'Compare Files' button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event args</param>
        private void CompareFiles_Click(object sender, RoutedEventArgs e)
        {
            State previous = this.currentState;

            this.WaitMessageText = Strings.WaitForCompareFiles;
            this.CurrentState    = State.Wait;

            string           file1      = string.Empty;
            string           file2      = string.Empty;
            KStudioEventFile eventFile2 = null;

            try
            {
                // open the first file, if not already opened for View
                if (this.fileData == null)
                {
                    // open a new file
                    file1 = this.OpenFileForInspection();

                    // if user cancels from OpenFileDialog, return to previous state
                    if (string.IsNullOrEmpty(file1))
                    {
                        this.CurrentState = previous;
                        return;
                    }
                }

                // open a second file to compare with the first
                file2 = this.OpenFileForInspection();

                // if the user cancels from OpenFileDialog, return to the previous state
                if (string.IsNullOrEmpty(file2))
                {
                    this.CurrentState = previous;
                    return;
                }

                // create a FileData object for the first file, unless one already exists
                if (this.fileData == null)
                {
                    this.eventFile = this.client.OpenEventFile(file1);
                    this.fileData  = new FileData(this.eventFile);
                }

                // create a second FileData object for comparison
                eventFile2 = this.client.OpenEventFile(file2);
                FileData fileData2 = new FileData(eventFile2);

                // compare data between files
                CompareFileData compareData = new CompareFileData(this.fileData, fileData2);
                this.ViewCompareFileDataGrid.DataContext = compareData;

                // show comparison data
                this.CurrentState = State.Compare;
            }
            catch (Exception ex)
            {
                this.ErrorMessageText = string.Format(Strings.ErrorCompareFilesFailed, ex.Message);
                this.CurrentState     = State.Error;
            }
            finally
            {
                if (eventFile2 != null)
                {
                    eventFile2.Dispose();
                    eventFile2 = null;
                }
            }
        }
Exemple #17
0
        /// <summary>
        /// Handles all command-line arguments
        /// </summary>
        /// <param name="args">Arguments array</param>
        /// <returns>CommandLineResult to indicate if the operation was successful or not</returns>
        private CommandLineResult ProcessCommandLine(string[] args)
        {
            string        logFile                        = string.Empty;
            List <string> streamList                     = new List <string>();
            bool          updatePersonalMetadata         = false;
            uint          loopCount                      = 0;
            Dictionary <string, List <string> > commands = new Dictionary <string, List <string> >();

            try
            {
                if (args == null)
                {
                    return(CommandLineResult.Succeeded);
                }

                if (args.Length == 0)
                {
                    return(CommandLineResult.Succeeded);
                }

                // gather commands and support parameters
                for (int i = 0; i < args.Length; i++)
                {
                    string arg = args[i];
                    if (this.IsArgument(arg))
                    {
                        string key = arg.Substring(1).ToUpperInvariant();

                        if (!commands.ContainsKey(key))
                        {
                            commands.Add(key, new List <string>());

                            for (int j = i + 1; j < args.Length; j++)
                            {
                                string param = args[j];
                                if (!this.IsArgument(param))
                                {
                                    commands[key].Add(param);
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                    }
                }

                // process all command args
                if (commands.ContainsKey("?") || commands.ContainsKey(Strings.Command_Help))
                {
                    this.RunCommandLine();
                    this.ShowCommandLineHelp();
                    return(CommandLineResult.SucceededExit);
                }

                // -log <filename>
                if (commands.ContainsKey(Strings.Command_Log))
                {
                    if (commands[Strings.Command_Log].Count != 1)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Log));
                        return(CommandLineResult.Invalid);
                    }

                    logFile = commands[Strings.Command_Log][0];
                }

                // -loop <count>
                if (commands.ContainsKey(Strings.Command_Loop))
                {
                    if (commands[Strings.Command_Loop].Count != 1)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Loop));
                        return(CommandLineResult.Invalid);
                    }

                    if (!uint.TryParse(commands[Strings.Command_Loop][0], out loopCount))
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Loop));
                        return(CommandLineResult.Invalid);
                    }
                }

                // -pii
                if (commands.ContainsKey(Strings.Command_PII))
                {
                    updatePersonalMetadata = true;
                }

                // -stream <stream1> <stream2> <stream3> ...
                if (commands.ContainsKey(Strings.Command_Stream))
                {
                    if (commands[Strings.Command_Stream].Count == 0)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Stream));
                        return(CommandLineResult.Invalid);
                    }

                    streamList = commands[Strings.Command_Stream];
                }

                // -view <filename>
                if (commands.ContainsKey(Strings.Command_View))
                {
                    this.RunCommandLine();
                    if (commands[Strings.Command_View].Count != 1)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_View));
                        return(CommandLineResult.Invalid);
                    }

                    string fileInfo = string.Empty;
                    string filePath = commands[Strings.Command_View][0];
                    this.CheckFile(filePath);
                    Console.WriteLine(Strings.WaitForViewFile);

                    using (KStudioClient client = KStudio.CreateClient())
                    {
                        if (filePath.ToUpperInvariant().StartsWith(Strings.ConsoleClipRepository.ToUpperInvariant()))
                        {
                            client.ConnectToService();
                        }

                        using (KStudioEventFile eventFile = client.OpenEventFile(filePath))
                        {
                            FileData data = new FileData(eventFile);
                            fileInfo = data.GetFileDataAsText();
                            Console.WriteLine(fileInfo);
                        }
                    }

                    if (!string.IsNullOrEmpty(logFile))
                    {
                        Logger.Start(logFile, true);
                        Logger.Log(fileInfo);
                        Logger.Stop();
                    }

                    Console.WriteLine(Strings.Done);
                    return(CommandLineResult.SucceededExit);
                }

                // -compare <filename1> <filename2>
                if (commands.ContainsKey(Strings.Command_Compare))
                {
                    this.RunCommandLine();
                    if (commands[Strings.Command_Compare].Count != 2)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Compare));
                        return(CommandLineResult.Invalid);
                    }

                    string fileInfo = string.Empty;
                    string file1    = commands[Strings.Command_Compare][0];
                    string file2    = commands[Strings.Command_Compare][1];
                    this.CheckFile(file1);
                    this.CheckFile(file2);
                    Console.WriteLine(Strings.WaitForCompareFiles);

                    using (KStudioClient client = KStudio.CreateClient())
                    {
                        if (file1.ToUpperInvariant().StartsWith(Strings.ConsoleClipRepository.ToUpperInvariant()) || file2.ToUpperInvariant().StartsWith(Strings.ConsoleClipRepository.ToUpperInvariant()))
                        {
                            client.ConnectToService();
                        }

                        using (KStudioEventFile eventFile1 = client.OpenEventFile(file1))
                            using (KStudioEventFile eventFile2 = client.OpenEventFile(file2))
                            {
                                FileData        fileData1   = new FileData(eventFile1);
                                FileData        fileData2   = new FileData(eventFile2);
                                CompareFileData compareData = new CompareFileData(fileData1, fileData2);
                                fileInfo = compareData.GetCompareFileDataAsText();
                                Console.WriteLine(fileInfo);
                            }
                    }

                    if (!string.IsNullOrEmpty(logFile))
                    {
                        Logger.Start(logFile, true);
                        Logger.Log(fileInfo);
                        Logger.Stop();
                    }

                    Console.WriteLine(Strings.Done);
                    return(CommandLineResult.SucceededExit);
                }

                // -update <filename> <metadata key> <metadata value>
                if (commands.ContainsKey(Strings.Command_Update))
                {
                    this.RunCommandLine();
                    if (commands[Strings.Command_Update].Count != 3)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Update));
                        return(CommandLineResult.Invalid);
                    }

                    string filePath = commands[Strings.Command_Update][0];
                    string key      = commands[Strings.Command_Update][1];
                    object value    = commands[Strings.Command_Update][2];
                    this.CheckFile(filePath);
                    string metadataText = string.Empty;

                    if (streamList.Count > 0)
                    {
                        // update stream metadata
                        foreach (string streamName in streamList)
                        {
                            Console.WriteLine(string.Format(CultureInfo.CurrentCulture, Strings.UpdatingStreamMetadata, streamName));
                            metadataText = this.EditMetadata(filePath, key, value, streamName, updatePersonalMetadata, true);
                            Console.WriteLine(metadataText);
                        }
                    }
                    else
                    {
                        // update file metadata
                        Console.WriteLine(Strings.UpdatingFileMetadata);
                        metadataText = this.EditMetadata(filePath, key, value, string.Empty, updatePersonalMetadata, false);
                        Console.WriteLine(metadataText);
                    }

                    Console.WriteLine(Strings.Done);
                    return(CommandLineResult.SucceededExit);
                }

                // -remove <filename> <metadata key>
                if (commands.ContainsKey(Strings.Command_Remove))
                {
                    this.RunCommandLine();
                    if (commands[Strings.Command_Remove].Count != 2)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Remove));
                        return(CommandLineResult.Invalid);
                    }

                    string filePath = commands[Strings.Command_Remove][0];
                    string key      = commands[Strings.Command_Remove][1];
                    this.CheckFile(filePath);
                    string metadataText = string.Empty;

                    if (streamList.Count > 0)
                    {
                        // update stream metadata
                        foreach (string streamName in streamList)
                        {
                            Console.WriteLine(string.Format(CultureInfo.CurrentCulture, Strings.UpdatingStreamMetadata, streamName));
                            metadataText = this.EditMetadata(filePath, key, null, streamName, updatePersonalMetadata, true);
                            Console.WriteLine(metadataText);
                        }
                    }
                    else
                    {
                        // update file metadata
                        Console.WriteLine(Strings.UpdatingFileMetadata);
                        metadataText = this.EditMetadata(filePath, key, null, string.Empty, updatePersonalMetadata, false);
                        Console.WriteLine(metadataText);
                    }

                    Console.WriteLine(Strings.Done);
                    return(CommandLineResult.SucceededExit);
                }

                // -play <filename>
                if (commands.ContainsKey(Strings.Command_Play))
                {
                    this.RunCommandLine();
                    if (commands[Strings.Command_Play].Count != 1)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Play));
                        return(CommandLineResult.Invalid);
                    }

                    string filePath = commands[Strings.Command_Play][0];
                    this.CheckFile(filePath);

                    using (KStudioClient client = KStudio.CreateClient())
                    {
                        Console.WriteLine(Strings.WaitToConnect);
                        client.ConnectToService();

                        Console.WriteLine(Strings.StartPlayback);
                        Playback.PlaybackClip(client, filePath, streamList, loopCount);
                        Console.WriteLine(Strings.StopPlayback);

                        client.DisconnectFromService();
                    }

                    Console.WriteLine(Strings.Done);
                    return(CommandLineResult.SucceededExit);
                }

                // -record <filename> <duration>
                if (commands.ContainsKey(Strings.Command_Record))
                {
                    this.RunCommandLine();
                    if (commands[Strings.Command_Record].Count != 2)
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Record));
                        return(CommandLineResult.Invalid);
                    }

                    string filePath = commands[Strings.Command_Record][0];
                    this.CheckDirectory(filePath);

                    double time = 0;
                    if (!double.TryParse(commands[Strings.Command_Record][1], out time))
                    {
                        Console.Error.WriteLine(string.Format(Strings.ErrorInvalidArgs, Strings.Command_Record));
                        return(CommandLineResult.Invalid);
                    }

                    TimeSpan duration = TimeSpan.FromSeconds(time);
                    string   errorMsg = string.Empty;
                    string   fileInfo = string.Empty;

                    using (KStudioClient client = KStudio.CreateClient())
                    {
                        Console.WriteLine(Strings.WaitToConnect);
                        client.ConnectToService();

                        Console.WriteLine(Strings.StartRecording);
                        Recording.RecordClip(client, filePath, duration, streamList);
                        Console.WriteLine(Strings.StopRecording);

                        using (KStudioEventFile eventFile = client.OpenEventFile(filePath))
                        {
                            FileData fileData = new FileData(eventFile);
                            fileInfo = fileData.GetFileDataAsText();
                            Console.WriteLine(fileInfo);
                        }

                        client.DisconnectFromService();
                    }

                    if (!string.IsNullOrEmpty(logFile))
                    {
                        Logger.Start(logFile, true);
                        Logger.Log(fileInfo);
                        Logger.Stop();
                    }

                    Console.WriteLine(Strings.Done);
                    return(CommandLineResult.SucceededExit);
                }
            }
            catch (Exception ex)
            {
                string errorMsg = string.Format(Strings.ErrorPrepend, ex.Message);
                Console.Error.WriteLine(errorMsg);
                return(CommandLineResult.Failed);
            }

            return(CommandLineResult.Invalid);
        }
        /// <summary>
        /// Handles the click event for the View File button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event</param>
        private void ViewFile_Click(object sender, RoutedEventArgs e)
        {
            State previous = this.currentState;
            this.WaitMessageText = Strings.WaitForViewFile;
            this.CurrentState = State.Wait;

            try
            {
                string filePath = this.OpenFileForInspection();

                if (!string.IsNullOrEmpty(filePath))
                {
                    this.eventFile = this.client.OpenEventFile(filePath);
                    this.fileData = new FileData(this.eventFile);
                    this.ViewFileDataGrid.DataContext = this.fileData;

                    // show the data
                    this.CurrentState = State.ViewFile;
                }
                else
                {
                    // user canceled the OpenFileDialog, return to previous state
                    this.CurrentState = previous;
                }
            }
            catch (Exception ex)
            {
                this.ErrorMessageText = string.Format(Strings.ErrorLoadFileFailed, ex.Message);
                this.CurrentState = State.Error;
            }
        }
        /// <summary>
        /// Handles the click event for the Exit button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event</param>
        private void Exit_Click(object sender, RoutedEventArgs e)
        {
            if (this.eventFile != null)
            {
                this.eventFile.Dispose();
                this.eventFile = null;
            }

            this.Close();
        }
        /// <summary>
        /// Handles the click event for the Exit button
        /// </summary>
        /// <param name="sender">sender object</param>
        /// <param name="e">routed event</param>
        private void CloseFile_Click(object sender, RoutedEventArgs e)
        {
            if (this.eventFile != null)
            {
                this.eventFile.Dispose();
                this.eventFile = null;
            }

            this.fileData = null;
            this.CurrentState = State.Welcome;
        }