Example #1
0
        private void RefreshAudioCaptureDevices(IList <MediaDevice> audioCaptureDevices)
        {
            RunOnUiThread(() =>
            {
                var selectedMicrophoneId = SelectedMicrophone?.Id;
                SelectedMicrophone       = null;
                Microphones.Clear();
                foreach (MediaDevice audioCaptureDevice in audioCaptureDevices)
                {
                    Microphones.Add(audioCaptureDevice);
                    if (audioCaptureDevice.Id == selectedMicrophoneId)
                    {
                        SelectedMicrophone = Microphones.Last();
                    }
                }

                if (SelectedMicrophone == null)
                {
                    SelectedMicrophone = Microphones.FirstOrDefault();
                }

                if (SelectedMicrophone == null)
                {
                    SelectedMicrophone = Microphones.FirstOrDefault();
                }
            });
        }
Example #2
0
 internal Audio(CiscoTelePresenceCodec codec)
     : base(codec)
 {
     _microphones = new Microphones(this, "Microphones");
     _input       = new Input(this, "Input");
     _volume      = new Volume(this);
     _output      = new Output(this, "Output");
 }
        /// <summary>
        ///     Refresh audio capture devices list.
        /// </summary>
        private async Task RefreshAudioCaptureDevicesAsync()
        {
            var selectedMicrophoneId = SelectedMicrophone?.Id;
            var oldMicrophones       = Microphones;

            Microphones = await GetAudioCaptureDevicesAsync();

            var preferredMicrophone = Microphones.FirstOrDefault(c => c.IsPreferred);

            SelectedMicrophone = (selectedMicrophoneId != null
                ? Microphones.FirstOrDefault(c => c.Id == selectedMicrophoneId)
                : preferredMicrophone) ?? Microphones.First();
            if (EtwStatsEnabled)
            {
                var addedMicrophonesInfo =
                    Microphones.Where(microphone => oldMicrophones.FirstOrDefault(x => x.Id == microphone.Id) == null)
                    .Aggregate("",
                               (current, microphone) =>
                               string.Format("{0}id = {1} name = {2}\n", current, microphone.Id, microphone.Name));
                if (addedMicrophonesInfo != "")
                {
                    ETWEventLogger.Instance.LogEvent("Microphone(s) Added", addedMicrophonesInfo,
                                                     DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString());
                }

                var removedMicrophonesInfo =
                    oldMicrophones.Where(microphone => _microphones.FirstOrDefault(x => x.Id == microphone.Id) == null)
                    .Aggregate("",
                               (current, microphone) =>
                               string.Format("{0}id = {1} name = {2}\n", current, microphone.Id, microphone.Name));
                if (removedMicrophonesInfo != "")
                {
                    ETWEventLogger.Instance.LogEvent("Microphone(s) Removed", removedMicrophonesInfo,
                                                     DateTimeOffset.Now.ToUnixTimeMilliseconds().ToString());
                }
            }
        }
Example #4
0
        private void RenderList(List <FilePreview> l, int pageCount)
        {
            flowPreview.SuspendLayout();
            mediaPanelControl1.lblPage.Text = String.Format("{0} / {1}", (MediaPanelPage + 1), pageCount);

            var currentList = new List <PreviewBox>();

            for (int i = 0; i < flowPreview.Controls.Count; i++)
            {
                var pb = flowPreview.Controls[i] as PreviewBox;
                if (pb != null)
                {
                    var cd = pb.CreatedDate;
                    if (NeedsMediaRebuild || l.Count(p => p.CreatedDateTicks == cd.Ticks) == 0)
                    {
                        flowPreview.Controls.Remove(pb);
                        pb.MouseDown  -= PbMouseDown;
                        pb.MouseEnter -= PbMouseEnter;
                        pb.Dispose();
                        i--;
                    }
                    else
                    {
                        currentList.Add(pb);
                    }
                }
                else
                {
                    var lb = flowPreview.Controls[i] as Label;
                    if (lb != null)
                    {
                        flowPreview.Controls.Remove(lb);
                        i--;
                    }
                }
            }

            int      ci        = 0;
            DateTime dtCurrent = DateTime.MinValue;
            bool     first     = true;

            foreach (FilePreview fp in l)
            {
                var dt = new DateTime(fp.CreatedDateTicks);
                if (first || dtCurrent.DayOfYear != dt.DayOfYear)
                {
                    first     = false;
                    dtCurrent = dt;
                    var lb = new Label {
                        Text = dtCurrent.ToShortDateString(), Margin = new Padding(3), Padding = new Padding(0), ForeColor = Color.White, BackColor = Color.Black, Width = 96, Height = 73, TextAlign = ContentAlignment.MiddleCenter
                    };
                    flowPreview.Controls.Add(lb);
                    flowPreview.Controls.SetChildIndex(lb, ci);
                    ci++;
                }
                var cdt = new DateTime(fp.CreatedDateTicks);
                var pb  = currentList.FirstOrDefault(p => p.CreatedDate == cdt);
                if (pb == null)
                {
                    FilePreview fp1 = fp;
                    var         dir = Helper.GetMediaDirectory(fp1.ObjectTypeId, fp1.ObjectId);
                    switch (fp1.ObjectTypeId)
                    {
                    case 1:
                        var v = Microphones.SingleOrDefault(p => p.id == fp1.ObjectId);
                        if (v != null)
                        {
                            var filename = dir + "audio\\" + v.directory + "\\" + fp.Filename;
                            pb = AddPreviewControl(fp1, Resources.audio, filename, v.name);
                        }
                        break;

                    case 2:
                        var c = Cameras.SingleOrDefault(p => p.id == fp1.ObjectId);
                        if (c != null)
                        {
                            var filename = dir + "video\\" + c.directory + "\\" + fp.Filename;
                            var thumb    = dir + "video\\" + c.directory + "\\thumbs\\" +
                                           fp.Filename.Substring(0,
                                                                 fp.Filename.LastIndexOf(".", StringComparison.Ordinal)) +
                                           ".jpg";
                            pb = AddPreviewControl(fp1, thumb, filename, c.name);
                        }
                        break;
                    }
                }
                if (pb != null)
                {
                    flowPreview.Controls.SetChildIndex(pb, ci);
                    ci++;
                }
            }

            flowPreview.ResumeLayout(true);
            NeedsMediaRebuild = false;
        }
Example #5
0
        public MainWindowViewModel(
            [NotNull] IAppArguments appArguments,
            [NotNull] IFactory <IStartupManager, StartupManagerArgs> startupManagerFactory,
            [NotNull] IMicrophoneControllerEx microphoneController,
            [NotNull] IMicSwitchOverlayViewModel overlay,
            [NotNull] IAudioNotificationsManager audioNotificationsManager,
            [NotNull] IFactory <IAudioNotificationSelectorViewModel> audioSelectorFactory,
            [NotNull] IApplicationUpdaterViewModel appUpdater,
            [NotNull][Dependency(WellKnownWindows.MainWindow)] IWindowTracker mainWindowTracker,
            [NotNull] IConfigProvider <MicSwitchConfig> configProvider,
            [NotNull] IComplexHotkeyTracker hotkeyTracker,
            [NotNull] IMicrophoneProvider microphoneProvider,
            [NotNull] IImageProvider imageProvider,
            [NotNull] IViewController viewController,
            [NotNull][Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler)
        {
            var startupManagerArgs = new StartupManagerArgs
            {
                UniqueAppName   = $"{appArguments.AppName}{(appArguments.IsDebugMode ? "-debug" : string.Empty)}",
                ExecutablePath  = appUpdater.GetLatestExecutable().FullName,
                CommandLineArgs = appArguments.StartupArgs,
                AutostartFlag   = appArguments.AutostartFlag
            };

            this.startupManager = startupManagerFactory.Create(startupManagerArgs);

            this.appArguments         = appArguments;
            this.microphoneController = microphoneController;

            ApplicationUpdater     = appUpdater;
            this.mainWindowTracker = mainWindowTracker;
            this.configProvider    = configProvider;
            this.imageProvider     = imageProvider;
            this.RaiseWhenSourceValue(x => x.IsActive, mainWindowTracker, x => x.IsActive).AddTo(Anchors);

            AudioSelectorWhenMuted   = audioSelectorFactory.Create();
            AudioSelectorWhenUnmuted = audioSelectorFactory.Create();

            Observable.Merge(
                AudioSelectorWhenMuted.ObservableForProperty(x => x.SelectedValue, skipInitial: true),
                AudioSelectorWhenUnmuted.ObservableForProperty(x => x.SelectedValue, skipInitial: true))
            .Subscribe(() => this.RaisePropertyChanged(nameof(AudioNotification)), Log.HandleException)
            .AddTo(Anchors);

            configProvider.ListenTo(x => x.Notification)
            .ObserveOn(uiScheduler)
            .Subscribe(cfg =>
            {
                Log.Debug($"Applying new notification configuration: {cfg.DumpToTextRaw()} (current: {AudioNotification.DumpToTextRaw()})");
                AudioNotification = cfg;
            }, Log.HandleException)
            .AddTo(Anchors);

            configProvider.ListenTo(x => x.IsPushToTalkMode)
            .ObserveOn(uiScheduler)
            .Subscribe(x =>
            {
                IsPushToTalkMode = x;
                if (isPushToTalkMode)
                {
                    MuteMicrophoneCommand.Execute(true);
                }
            }, Log.HandleException)
            .AddTo(Anchors);

            configProvider.ListenTo(x => x.SuppressHotkey)
            .ObserveOn(uiScheduler)
            .Subscribe(x => SuppressHotkey = x, Log.HandleException)
            .AddTo(Anchors);

            Observable.Merge(configProvider.ListenTo(x => x.MicrophoneHotkey), configProvider.ListenTo(x => x.MicrophoneHotkeyAlt))
            .Select(x => new
            {
                Hotkey    = (HotkeyGesture) new HotkeyConverter().ConvertFrom(configProvider.ActualConfig.MicrophoneHotkey ?? string.Empty),
                HotkeyAlt = (HotkeyGesture) new HotkeyConverter().ConvertFrom(configProvider.ActualConfig.MicrophoneHotkeyAlt ?? string.Empty),
            })
            .ObserveOn(uiScheduler)
            .Subscribe(cfg =>
            {
                Log.Debug($"Setting new hotkeys configuration: {cfg.DumpToTextRaw()} (current: {hotkey}, alt: {hotkeyAlt})");
                Hotkey    = cfg.Hotkey;
                HotkeyAlt = cfg.HotkeyAlt;
            }, Log.HandleException)
            .AddTo(Anchors);

            Overlay = overlay;

            this.RaiseWhenSourceValue(x => x.RunAtLogin, startupManager, x => x.IsRegistered, uiScheduler).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.MicrophoneVolume, microphoneController, x => x.VolumePercent, uiScheduler).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.MicrophoneMuted, microphoneController, x => x.Mute, uiScheduler).AddTo(Anchors);
            ImageProvider = imageProvider;

            microphoneProvider.Microphones
            .ToObservableChangeSet()
            .ObserveOn(uiScheduler)
            .Bind(out var microphones)
            .Subscribe()
            .AddTo(Anchors);
            Microphones = microphones;

            this.ObservableForProperty(x => x.MicrophoneMuted, skipInitial: true)
            .DistinctUntilChanged()
            .Where(x => !MicrophoneLine.IsEmpty)
            .Skip(1)     // skip initial setup
            .Subscribe(x =>
            {
                var cfg = configProvider.ActualConfig.Notification;
                var notificationToPlay = x.Value ? cfg.On : cfg.Off;
                Log.Debug($"Playing notification {notificationToPlay} (cfg: {cfg.DumpToTextRaw()})");
                audioNotificationsManager.PlayNotification(notificationToPlay);
            }, Log.HandleUiException)
            .AddTo(Anchors);

            this.WhenAnyValue(x => x.MicrophoneLine)
            .DistinctUntilChanged()
            .Subscribe(x => microphoneController.LineId = x, Log.HandleUiException)
            .AddTo(Anchors);

            Observable.Merge(
                configProvider.ListenTo(x => x.MicrophoneLineId).ToUnit(),
                Microphones.ToObservableChangeSet().ToUnit())
            .Select(_ => configProvider.ActualConfig.MicrophoneLineId)
            .ObserveOn(uiScheduler)
            .Subscribe(configLineId =>
            {
                Log.Debug($"Microphone line configuration changed, lineId: {configLineId}, known lines: {Microphones.DumpToTextRaw()}");

                var micLine = Microphones.FirstOrDefault(line => line.Equals(configLineId));
                if (micLine.IsEmpty)
                {
                    Log.Debug($"Selecting first one of available microphone lines, known lines: {Microphones.DumpToTextRaw()}");
                    micLine = Microphones.FirstOrDefault();
                }
                MicrophoneLine = micLine;
                MuteMicrophoneCommand.ResetError();
            }, Log.HandleUiException)
            .AddTo(Anchors);

            hotkeyTracker
            .WhenAnyValue(x => x.IsActive)
            .ObserveOn(uiScheduler)
            .Subscribe(async isActive =>
            {
                if (isPushToTalkMode)
                {
                    await MuteMicrophoneCommandExecuted(!isActive);
                }
                else
                {
                    await MuteMicrophoneCommandExecuted(!MicrophoneMuted);
                }
            }, Log.HandleUiException)
            .AddTo(Anchors);

            ToggleOverlayLockCommand = CommandWrapper.Create(
                () =>
            {
                if (overlay.IsLocked && overlay.UnlockWindowCommand.CanExecute(null))
                {
                    overlay.UnlockWindowCommand.Execute(null);
                }
                else if (!overlay.IsLocked && overlay.LockWindowCommand.CanExecute(null))
                {
                    overlay.LockWindowCommand.Execute(null);
                }
            });

            ExitAppCommand = CommandWrapper.Create(
                () =>
            {
                Log.Debug("Closing application");
                configProvider.Save(configProvider.ActualConfig);
                Application.Current.Shutdown();
            });

            this.WhenAnyValue(x => x.WindowState)
            .Subscribe(x => ShowInTaskbar = x != WindowState.Minimized, Log.HandleUiException)
            .AddTo(Anchors);

            ShowAppCommand = CommandWrapper.Create(
                () =>
            {
                if (Visibility != Visibility.Visible)
                {
                    viewController.Show();
                }
                else
                {
                    viewController.Hide();
                }
            });

            OpenAppDataDirectoryCommand = CommandWrapper.Create(OpenAppDataDirectory);

            ResetOverlayPositionCommand = CommandWrapper.Create(ResetOverlayPositionCommandExecuted);

            RunAtLoginToggleCommand          = CommandWrapper.Create <bool>(RunAtLoginCommandExecuted);
            MuteMicrophoneCommand            = CommandWrapper.Create <bool>(MuteMicrophoneCommandExecuted);
            SelectMicrophoneIconCommand      = CommandWrapper.Create(SelectMicrophoneIconCommandExecuted);
            SelectMutedMicrophoneIconCommand = CommandWrapper.Create(SelectMutedMicrophoneIconCommandExecuted);
            ResetMicrophoneIconsCommand      = CommandWrapper.Create(ResetMicrophoneIconsCommandExecuted);

            var executingAssemblyName = Assembly.GetExecutingAssembly().GetName();

            Title = $"{(appArguments.IsDebugMode ? "[D]" : "")} {executingAssemblyName.Name} v{executingAssemblyName.Version}";

            WindowState = WindowState.Minimized;
            viewController
            .WhenLoaded
            .Take(1)
            .Select(() => configProvider.ListenTo(y => y.StartMinimized))
            .Switch()
            .Take(1)
            .ObserveOn(uiScheduler)
            .Subscribe(
                x =>
            {
                if (x)
                {
                    Log.Debug($"StartMinimized option is active - minimizing window, current state: {WindowState}");
                    StartMinimized = true;
                    viewController.Hide();
                }
                else
                {
                    Log.Debug($"StartMinimized option is not active - showing window as Normal, current state: {WindowState}");
                    StartMinimized = false;
                    viewController.Show();
                }
            }, Log.HandleUiException)
            .AddTo(Anchors);

            // config processing
            Observable.Merge(
                this.ObservableForProperty(x => x.MicrophoneLine, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.IsPushToTalkMode, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.AudioNotification, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.HotkeyAlt, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.Hotkey, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.SuppressHotkey, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.StartMinimized, skipInitial: true).ToUnit())
            .Throttle(ConfigThrottlingTimeout)
            .ObserveOn(uiScheduler)
            .Subscribe(() =>
            {
                var config = configProvider.ActualConfig.CloneJson();
                config.IsPushToTalkMode    = IsPushToTalkMode;
                config.MicrophoneHotkey    = (Hotkey ?? new HotkeyGesture()).ToString();
                config.MicrophoneHotkeyAlt = (HotkeyAlt ?? new HotkeyGesture()).ToString();
                config.MicrophoneLineId    = MicrophoneLine;
                config.Notification        = AudioNotification;
                config.SuppressHotkey      = SuppressHotkey;
                config.StartMinimized      = StartMinimized;
                configProvider.Save(config);
            }, Log.HandleUiException)
            .AddTo(Anchors);
        }
Example #6
0
        }                                      //根据语音音量变化判断是否在录音中

        /// <summary>
        /// 加载会议
        /// </summary>
        public void Loading(string code = null, MeetingDTO meeting = null)
        {
            //meeting
            if (!meeting.IsNull())
            {
                Meeting = meeting;
            }
            else if (!code.IsEmpty())
            {
                var result = PlugCoreHelper.ApiUrl.Meeting.MeetingGetCode.GetResult <MeetingDTO, MeetingEditInput>(new MeetingEditInput()
                {
                    Num = code
                });
                if (result.Code == EnumCode.成功)
                {
                    Meeting = meeting;
                }
            }
            else if (Meeting.IsNull())
            {
                //else if(Meeting.IsNull()) 全局会议保持
                var result = PlugCoreHelper.ApiUrl.Meeting.MeetingInsert.GetResult <MeetingDTO, MeetingEditInput>(new MeetingEditInput()
                {
                    Id       = Guid.Empty,
                    Name     = culture.Lang.metName,
                    Descript = culture.Lang.metDescript,
                    Setting  = JsonHelper.Serialize(Setting)
                });
                if (result.Code == EnumCode.成功)
                {
                    Meeting = result.Obj;
                }
            }
            if (Meeting.IsNull() || (!Meeting.IsNull() && (Meeting.Id.IsEmpty() || Meeting.Num.IsEmpty())))
            {
                throw new DbxException(EnumCode.初始失败);
            }

            //device
            Microphones = RecordingHelper.Microphones();
            Microphone  = Microphones.FirstOrDefault();

            //二维码
            var codeBitmap = QrCodeHelper.GetCode(string.Format(EngineHelper.Configuration.Settings.GetValue("meetingViewUrl"), Meeting.Id));

            MeetingCode = WpfHelper.BitmapToSource(codeBitmap);

            //本地数据库
            var meetingDatabasePath = MeetingHelper.GetMeetingDatabaseFile(Meeting.Id);

            if (!File.Exists(meetingDatabasePath))
            {
                FilesHelper.CopyFile(MeetingHelper.TemplateDatabaseFilePath, meetingDatabasePath);
            }

            //记录字体
            RecordFontSize = Setting.FontSize;

            //同步任务
            SyncTask();

            //同步状态
            SyncUI(EnumTaskStatus.Default);
            SyncUI(EnumTaskStatus.Init);

            //远程服务同步任务
            AppHelper.ServerObj.MeetingSyncTask();
        }
Example #7
0
        public MicrophoneControllerViewModel(
            IMicrophoneControllerEx microphoneController,
            IMicrophoneProvider microphoneProvider,
            IComplexHotkeyTracker hotkeyTracker,
            IFactory <IHotkeyTracker> hotkeyTrackerFactory,
            IFactory <IHotkeyEditorViewModel> hotkeyEditorFactory,
            IConfigProvider <MicSwitchConfig> configProvider,
            IConfigProvider <MicSwitchHotkeyConfig> hotkeyConfigProvider,
            [Dependency(WellKnownSchedulers.UI)] IScheduler uiScheduler)
        {
            microphoneProvider.Microphones
            .ToObservableChangeSet()
            .ObserveOn(uiScheduler)
            .Bind(out var microphones)
            .SubscribeToErrors(Log.HandleUiException)
            .AddTo(Anchors);
            Microphones = microphones;

            this.microphoneController = microphoneController;
            this.hotkeyTrackerFactory = hotkeyTrackerFactory;
            this.hotkeyEditorFactory  = hotkeyEditorFactory;
            this.hotkeyConfigProvider = hotkeyConfigProvider;
            this.uiScheduler          = uiScheduler;
            MuteMicrophoneCommand     = CommandWrapper.Create <object>(MuteMicrophoneCommandExecuted);
            Hotkey           = PrepareHotkey("Mute/Un-mute microphone", x => x.Hotkey, (config, hotkeyConfig) => config.Hotkey = hotkeyConfig);
            HotkeyToggle     = PrepareHotkey("Toggle microphone state", x => x.HotkeyForToggle, (config, hotkeyConfig) => config.HotkeyForToggle = hotkeyConfig);
            HotkeyMute       = PrepareHotkey("Mute microphone", x => x.HotkeyForMute, (config, hotkeyConfig) => config.HotkeyForMute = hotkeyConfig);
            HotkeyUnmute     = PrepareHotkey("Un-mute microphone", x => x.HotkeyForUnmute, (config, hotkeyConfig) => config.HotkeyForUnmute = hotkeyConfig);
            HotkeyPushToMute = PrepareHotkey("Push-To-Mute", x => x.HotkeyForPushToMute, (config, hotkeyConfig) => config.HotkeyForPushToMute = hotkeyConfig);
            HotkeyPushToTalk = PrepareHotkey("Push-To-Talk", x => x.HotkeyForPushToTalk, (config, hotkeyConfig) => config.HotkeyForPushToTalk = hotkeyConfig);

            PrepareTracker(HotkeyMode.Click, HotkeyToggle)
            .ObservableForProperty(x => x.IsActive, skipInitial: true)
            .SubscribeSafe(x =>
            {
                Log.Debug($"[{x.Sender}] Toggling microphone state: {microphoneController}");
                microphoneController.Mute = !microphoneController.Mute;
            }, Log.HandleUiException)
            .AddTo(Anchors);

            PrepareTracker(HotkeyMode.Hold, HotkeyMute)
            .ObservableForProperty(x => x.IsActive, skipInitial: true)
            .Where(x => x.Value)
            .SubscribeSafe(x =>
            {
                Log.Debug($"[{x.Sender}] Muting microphone: {microphoneController}");
                microphoneController.Mute = true;
            }, Log.HandleUiException)
            .AddTo(Anchors);

            PrepareTracker(HotkeyMode.Hold, HotkeyUnmute)
            .ObservableForProperty(x => x.IsActive, skipInitial: true)
            .Where(x => x.Value)
            .SubscribeSafe(x =>
            {
                Log.Debug($"[{x.Sender}] Un-muting microphone: {microphoneController}");
                microphoneController.Mute = false;
            }, Log.HandleUiException)
            .AddTo(Anchors);

            PrepareTracker(HotkeyMode.Hold, HotkeyPushToTalk)
            .ObservableForProperty(x => x.IsActive, skipInitial: true)
            .SubscribeSafe(x =>
            {
                Log.Debug($"[{x.Sender}] Processing push-to-talk hotkey for microphone: {microphoneController}");
                microphoneController.Mute = !x.Value;
            }, Log.HandleUiException)
            .AddTo(Anchors);

            PrepareTracker(HotkeyMode.Hold, HotkeyPushToMute)
            .ObservableForProperty(x => x.IsActive, skipInitial: true)
            .SubscribeSafe(x =>
            {
                Log.Debug($"[{x.Sender}] Processing push-to-mute hotkey for microphone: {microphoneController}");
                microphoneController.Mute = x.Value;
            }, Log.HandleUiException)
            .AddTo(Anchors);

            this.RaiseWhenSourceValue(x => x.MicrophoneVolume, microphoneController, x => x.VolumePercent, uiScheduler).AddTo(Anchors);
            this.RaiseWhenSourceValue(x => x.MicrophoneMuted, microphoneController, x => x.Mute, uiScheduler).AddTo(Anchors);

            this.WhenAnyValue(x => x.MicrophoneLine)
            .DistinctUntilChanged()
            .SubscribeSafe(x => microphoneController.LineId = x, Log.HandleUiException)
            .AddTo(Anchors);

            hotkeyConfigProvider.ListenTo(x => x.MuteMode)
            .ObserveOn(uiScheduler)
            .Subscribe(x =>
            {
                Log.Debug($"Mute mode loaded from config: {x}");
                MuteMode = x;
            })
            .AddTo(Anchors);

            hotkeyConfigProvider.ListenTo(x => x.EnableAdvancedHotkeys)
            .ObserveOn(uiScheduler)
            .Subscribe(x => EnableAdditionalHotkeys = x)
            .AddTo(Anchors);

            hotkeyConfigProvider.ListenTo(x => x.InitialMicrophoneState)
            .ObserveOn(uiScheduler)
            .Subscribe(x => InitialMicrophoneState = x)
            .AddTo(Anchors);

            configProvider.ListenTo(x => x.VolumeControlEnabled)
            .ObserveOn(uiScheduler)
            .SubscribeSafe(x => MicrophoneVolumeControlEnabled = x, Log.HandleException)
            .AddTo(Anchors);

            Observable.Merge(
                configProvider.ListenTo(x => x.MicrophoneLineId).ToUnit(),
                Microphones.ToObservableChangeSet().ToUnit())
            .Select(_ => configProvider.ActualConfig.MicrophoneLineId)
            .ObserveOn(uiScheduler)
            .SubscribeSafe(configLineId =>
            {
                Log.Debug($"Microphone line configuration changed, lineId: {configLineId}, known lines: {Microphones.DumpToTextRaw()}");

                var micLine = Microphones.FirstOrDefault(line => line.Equals(configLineId));
                if (micLine.IsEmpty)
                {
                    Log.Debug($"Selecting first one of available microphone lines, known lines: {Microphones.DumpToTextRaw()}");
                    micLine = Microphones.FirstOrDefault();
                }
                MicrophoneLine = micLine;
                MuteMicrophoneCommand.ResetError();
            }, Log.HandleUiException)
            .AddTo(Anchors);

            this.WhenAnyValue(x => x.MuteMode, x => x.InitialMicrophoneState)
            .ObserveOn(uiScheduler)
            .SubscribeSafe(_ =>
            {
                Log.Debug($"Processing muteMode: {muteMode}, {microphoneController}.Mute: {microphoneController.Mute}");
                switch (muteMode)
                {
                case MuteMode.PushToTalk:
                    Log.Debug($"{muteMode} mute mode is enabled, un-muting microphone");
                    microphoneController.Mute = true;
                    break;

                case MuteMode.PushToMute:
                    microphoneController.Mute = false;
                    Log.Debug($"{muteMode} mute mode is enabled, muting microphone");
                    break;

                case MuteMode.ToggleMute when initialMicrophoneState == MicrophoneState.Mute:
                    Log.Debug($"{muteMode} enabled, muting microphone");
                    microphoneController.Mute = true;
                    break;

                case MuteMode.ToggleMute when initialMicrophoneState == MicrophoneState.Unmute:
                    Log.Debug($"{muteMode} enabled, un-muting microphone");
                    microphoneController.Mute = false;
                    break;

                default:
                    Log.Debug($"{muteMode} enabled, action is not needed");
                    break;
                }
            }, Log.HandleUiException)
            .AddTo(Anchors);

            hotkeyTracker
            .WhenAnyValue(x => x.IsActive)
            .Skip(1)
            .ObserveOn(uiScheduler)
            .SubscribeSafe(async isActive =>
            {
                Log.Debug($"Handling hotkey press (isActive: {isActive}), mute mode: {muteMode}");
                switch (muteMode)
                {
                case MuteMode.PushToTalk:
                    microphoneController.Mute = !isActive;
                    break;

                case MuteMode.PushToMute:
                    microphoneController.Mute = isActive;
                    break;

                case MuteMode.ToggleMute:
                    microphoneController.Mute = !microphoneController.Mute;
                    break;

                default:
                    throw new ArgumentOutOfRangeException(nameof(muteMode), muteMode, @"Unsupported mute mode");
                }
            }, Log.HandleUiException)
            .AddTo(Anchors);

            Observable.Merge(
                this.ObservableForProperty(x => x.MuteMode, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.EnableAdditionalHotkeys, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.InitialMicrophoneState, skipInitial: true).ToUnit(),
                Hotkey.ObservableForProperty(x => x.Properties, skipInitial: true).ToUnit())
            .Throttle(ConfigThrottlingTimeout)
            .ObserveOn(uiScheduler)
            .SubscribeSafe(() =>
            {
                var hotkeyConfig      = hotkeyConfigProvider.ActualConfig.CloneJson();
                hotkeyConfig.Hotkey   = Hotkey.Properties;
                hotkeyConfig.MuteMode = muteMode;
                hotkeyConfig.EnableAdvancedHotkeys  = enableAdvancedHotkeys;
                hotkeyConfig.InitialMicrophoneState = initialMicrophoneState;
                hotkeyConfigProvider.Save(hotkeyConfig);
            }, Log.HandleUiException)
            .AddTo(Anchors);

            Observable.Merge(
                this.ObservableForProperty(x => x.MicrophoneLine, skipInitial: true).ToUnit(),
                this.ObservableForProperty(x => x.MicrophoneVolumeControlEnabled, skipInitial: true).ToUnit())
            .Throttle(ConfigThrottlingTimeout)
            .ObserveOn(uiScheduler)
            .SubscribeSafe(() =>
            {
                var config = configProvider.ActualConfig.CloneJson();
                config.MicrophoneLineId     = microphoneLine;
                config.VolumeControlEnabled = microphoneVolumeControlEnabled;
                configProvider.Save(config);
            }, Log.HandleUiException)
            .AddTo(Anchors);
        }
Example #8
0
        private void RenderList(List <FilePreview> l, int pageCount)
        {
            var currentList = new List <PreviewBox>();



            int      ci        = 0;
            DateTime dtCurrent = DateTime.MinValue;
            bool     first     = true;

            foreach (FilePreview fp in l)
            {
                var dt = new DateTime(fp.CreatedDateTicks);
                if (first || dtCurrent.DayOfYear != dt.DayOfYear)
                {
                    first     = false;
                    dtCurrent = dt;
                    DateTime tag = new DateTime(dtCurrent.Year, dtCurrent.Month, dtCurrent.Day);
                    var      lb  = new Label {
                        Text = dtCurrent.ToShortDateString(), Tag = tag, Margin = new Padding(3), Padding = new Padding(0), ForeColor = Color.White, BackColor = Color.Black, Width = 96, Height = 73, TextAlign = ContentAlignment.MiddleCenter
                    };
                    lb.Click += Lb_Click;
                    lb.Cursor = Cursors.Hand;

                    ci++;
                }
                var cdt = new DateTime(fp.CreatedDateTicks);
                var pb  = currentList.FirstOrDefault(p => p.CreatedDate == cdt);
                if (pb == null)
                {
                    FilePreview fp1 = fp;
                    var         dir = Helper.GetMediaDirectory(fp1.ObjectTypeId, fp1.ObjectId);
                    switch (fp1.ObjectTypeId)
                    {
                    case 1:
                        var v = Microphones.SingleOrDefault(p => p.id == fp1.ObjectId);
                        if (v != null)
                        {
                            var filename = dir + "audio\\" + v.directory + "\\" + fp.Filename;
                            pb = AddPreviewControl(fp1, Resources.audio, filename, v.name);
                        }
                        break;

                    case 2:
                        var c = Cameras.SingleOrDefault(p => p.id == fp1.ObjectId);
                        if (c != null)
                        {
                            var filename = dir + "video\\" + c.directory + "\\" + fp.Filename;
                            var thumb    = dir + "video\\" + c.directory + "\\thumbs\\" +
                                           fp.Filename.Substring(0,
                                                                 fp.Filename.LastIndexOf(".", StringComparison.Ordinal)) +
                                           ".jpg";
                            pb = AddPreviewControl(fp1, thumb, filename, c.name);
                        }
                        break;
                    }
                }
                if (pb != null)
                {
                    ci++;
                }
            }


            NeedsMediaRebuild = false;
        }
        private async void LoadSettings()
        {
            await _callChannel.InitializeRtcAsync();

            SignalingServerPort = int.Parse(SignalingSettings.SignalingServerPort);
            SignalingServerHost = SignalingSettings.SignalingServerHost;
            Domain             = RegistrationSettings.Domain;
            AppInsightsEnabled = SignalingSettings.AppInsightsEnabled;
            RegisteredUserName = RegistrationSettings.Name;

            if (_localSettings.Values[nameof(NtpServerIp)] != null)
            {
                NtpServerIp = (string)_localSettings.Values[nameof(NtpServerIp)];
            }

            Cameras        = new ObservableCollection <MediaDevice>((await _mediaSettings.GetVideoCaptureDevicesAsync()).Devices);
            SelectedCamera = Cameras.FirstOrDefault(c => c.IsPreferred) ?? Cameras.FirstOrDefault();

            Microphones = await GetAudioCaptureDevicesAsync();

            SelectedMicrophone = Microphones.FirstOrDefault(c => c.IsPreferred);
            if (SelectedMicrophone == null)
            {
                SelectedMicrophone = Microphones.First();
                await _mediaSettings.SetAudioDeviceAsync(SelectedMicrophone.Id == DefaultAudioDeviceId
                                                         ?null
                                                         : SelectedMicrophone);
            }

            AudioPlayoutDevices = await GetAudioPlayoutDevicesAsync();

            SelectedAudioPlayoutDevice = AudioPlayoutDevices.FirstOrDefault(c => c.IsPreferred);
            if (SelectedAudioPlayoutDevice == null)
            {
                SelectedAudioPlayoutDevice = AudioPlayoutDevices.First();
                await _mediaSettings.SetAudioPlayoutDeviceAsync(SelectedAudioPlayoutDevice.Id == DefaultAudioDeviceId
                                                                ?null
                                                                : SelectedAudioPlayoutDevice);
            }

            AudioCodecs = new ObservableCollection <CodecInfo>();
            var audioCodecList = await _mediaSettings.GetAudioCodecsAsync();

            foreach (var audioCodec in audioCodecList.Codecs)
            {
                if (!_incompatibleAudioCodecs.Contains(audioCodec.Name + audioCodec.ClockRate))
                {
                    AudioCodecs.Add(audioCodec);
                }
            }
            SelectedAudioCodec = null;
            if (_localSettings.Values[nameof(SelectedAudioCodec)] != null)
            {
                var audioCodecId = (int)_localSettings.Values[nameof(SelectedAudioCodec)];
                var audioCodec   = AudioCodecs.SingleOrDefault(a => a.Id.Equals(audioCodecId));
                if (audioCodec != null)
                {
                    SelectedAudioCodec = audioCodec;
                }
            }
            if (SelectedAudioCodec == null && AudioCodecs.Count > 0)
            {
                SelectedAudioCodec = AudioCodecs.First();
            }
            await _mediaSettings.SetAudioCodecAsync(SelectedAudioCodec);

            var videoCodecList = (await _mediaSettings.GetVideoCodecsAsync()).Codecs.OrderBy(codec =>
            {
                switch (codec.Name)
                {
                case "VP8":
                    return(1);

                case "VP9":
                    return(2);

                case "H264":
                    return(3);

                default:
                    return(99);
                }
            });

            VideoCodecs        = new ObservableCollection <CodecInfo>(videoCodecList);
            SelectedVideoCodec = null;
            if (_localSettings.Values[nameof(SelectedVideoCodec)] != null)
            {
                var videoCodecId = (int)_localSettings.Values[nameof(SelectedVideoCodec)];
                var videoCodec   = VideoCodecs.SingleOrDefault(v => v.Id.Equals(videoCodecId));
                if (videoCodec != null)
                {
                    SelectedVideoCodec = videoCodec;
                }
            }
            if (SelectedVideoCodec == null && VideoCodecs.Count > 0)
            {
                SelectedVideoCodec = VideoCodecs.First();
            }
            await _mediaSettings.SetVideoCodecAsync(SelectedVideoCodec);

            IceServers = new ObservableCollection <IceServerViewModel>(
                IceServerSettings.IceServers.Select(ices => new IceServerViewModel(ices)));

            if (_localSettings.Values[nameof(StatsServerPort)] != null)
            {
                StatsServerPort = (int)_localSettings.Values[nameof(StatsServerPort)];
            }
            else
            {
                StatsServerPort = 47005;
            }

            if (_localSettings.Values[nameof(StatsServerHost)] != null)
            {
                StatsServerHost = (string)_localSettings.Values[nameof(StatsServerHost)];
            }
            else
            {
                StatsServerHost = "localhost";
            }
        }