예제 #1
0
        private void InterpretLine(string line)
        {
            if (!line.StartsWith("S") && !line.StartsWith("P"))
            {
                Debug.WriteLine("Whirligig: " + line);
            }

            if (_timeSource.CheckAccess())
            {
                if (line.StartsWith("S"))
                {
                    _timeSource.Pause();
                }
                else if (line.StartsWith("C"))
                {
                    string file = line.Substring(2).Trim('\t', ' ', '\"');
                    Debug.WriteLine($"Whirligig opened '{file}'");
                    OnFileOpened(file);
                }
                else if (line.StartsWith("P"))
                {
                    string   timeStamp = line.Substring(2).Trim();
                    double   seconds   = ParseWhirligigTimestap(timeStamp);
                    TimeSpan position  = TimeSpan.FromSeconds(seconds);

                    _timeSource.Play();

                    if (position == _lastReceivedTimestamp)
                    {
                        return;
                    }
                    _lastReceivedTimestamp = position;
                    _timeSource.SetPosition(position);
                }
                else if (line.StartsWith("dometype"))
                {
                }
                else if (line.StartsWith("duration"))
                {
                    string timeStamp = line.Substring(10).Trim();
                    double seconds   = ParseWhirligigTimestap(timeStamp);
                    _timeSource.SetDuration(TimeSpan.FromSeconds(seconds));
                }
                else
                {
                    Debug.WriteLine("Unknown Parameter: " + line);
                }

                //Unknown Parameter: dometype = 6180
                //Unknown Parameter: duration = 1389.141
            }
            else
            {
                _timeSource.Dispatcher.Invoke(() => InterpretLine(line));
            }
        }
예제 #2
0
        private void InterpretStatus(string statusXml)
        {
            if (!_timeSource.CheckAccess())
            {
                try
                {
                    _timeSource.Dispatcher.Invoke(() => InterpretStatus(statusXml));
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Exception in McpTimeSource.InterpretStatus: " + e.Message);
                }
                return;
            }

            try
            {
                MpcStatus newStatus = new MpcStatus(statusXml);

                if (newStatus.IsValid)
                {
                    if (!_previousStatus.IsValid || _previousStatus.FilePath != newStatus.FilePath)
                    {
                        OnFileOpened(newStatus.FilePath);
                    }

                    if (!_previousStatus.IsValid || _previousStatus.State != newStatus.State)
                    {
                        if (newStatus.State == MpcPlaybackState.Playing)
                        {
                            _timeSource.Play();
                        }
                        else
                        {
                            _timeSource.Pause();
                        }
                    }

                    if (!_previousStatus.IsValid || _previousStatus.Duration != newStatus.Duration)
                    {
                        _timeSource.SetDuration(TimeSpan.FromMilliseconds(newStatus.Duration));
                    }

                    if (!_previousStatus.IsValid || _previousStatus.Position != newStatus.Position)
                    {
                        _timeSource.SetPosition(TimeSpan.FromMilliseconds(newStatus.Position));
                    }
                }

                _previousStatus = newStatus;
            }
            catch (Exception exception)
            {
                Debug.WriteLine("Couldn't interpret MPC Status: " + exception.Message);
            }
        }
예제 #3
0
        private void InterpretData(DeoVrApiData data)
        {
            if (data == null)
            {
                return;
            }

            if (!_timeSource.CheckAccess())
            {
                _timeSource.Dispatcher.Invoke(() => InterpretData(data));
                return;
            }

            if (!string.IsNullOrEmpty(data.Path))
            {
                if (!String.Equals(data.Path, _previousData?.Path, StringComparison.InvariantCultureIgnoreCase))
                {
                    OnFileOpened(data.Path);
                }
            }

            if (data.PlaybackSpeed != null)
            {
                _timeSource.PlaybackRate = (float)data.PlaybackSpeed;
            }

            if (data.Duration != null)
            {
                _timeSource.SetDuration(TimeSpan.FromSeconds((float)data.Duration));
            }

            if (data.CurrentTime != null)
            {
                _timeSource.SetPosition(TimeSpan.FromSeconds((float)data.CurrentTime));
            }

            if (data.PlayerState != null)
            {
                bool isPlaying = (data.PlayerState == DeoVrPlayerState.Play);
                if (_timeSource.IsPlaying != isPlaying)
                {
                    if (isPlaying)
                    {
                        _timeSource.Play();
                    }
                    else
                    {
                        _timeSource.Pause();
                    }
                }
            }
        }
        private void InterpretLine(string line)
        {
            if (_timeSource.CheckAccess())
            {
                Debug.WriteLine(line);

                ZoomPlayerMessageCodes commandCode = (ZoomPlayerMessageCodes)int.Parse(line.Substring(0, 4));
                string parameter = line.Substring(4).Trim();

                switch (commandCode)
                {
                case ZoomPlayerMessageCodes.StateChanged:
                    ZoomPlayerPlaybackStates state = (ZoomPlayerPlaybackStates)int.Parse(parameter);
                    if (state == ZoomPlayerPlaybackStates.Playing)
                    {
                        _timeSource.Play();
                    }
                    else
                    {
                        _timeSource.Pause();
                    }

                    break;

                case ZoomPlayerMessageCodes.PositionUpdate:
                    string[] parts = parameter.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
                                     .Select(s => s.Trim()).ToArray();

                    string[] timeFormats = { "hh\\:mm\\:ss", "mm\\:ss" };

                    TimeSpan position = TimeSpan.ParseExact(parts[0], timeFormats, CultureInfo.InvariantCulture);
                    TimeSpan duration = TimeSpan.ParseExact(parts[1], timeFormats, CultureInfo.InvariantCulture);

                    _timeSource.SetDuration(duration);
                    _timeSource.SetPosition(position);
                    break;

                case ZoomPlayerMessageCodes.CurrentlyLoadedFile:
                    if (!String.IsNullOrWhiteSpace(parameter))
                    {
                        OnFileOpened(parameter);
                    }
                    break;
                }
            }
            else
            {
                _timeSource.Dispatcher.Invoke(() => InterpretLine(line));
            }
        }
예제 #5
0
        private void InterpretStatus(string statusXml)
        {
            if (!_timeSource.CheckAccess())
            {
                _timeSource.Dispatcher.Invoke(() => InterpretStatus(statusXml));
                return;
            }

            try
            {
                VlcStatus newStatus = new VlcStatus(statusXml);

                if (newStatus.IsValid)
                {
                    if (!_previousStatus.IsValid || _previousStatus.Filename != newStatus.Filename)
                    {
                        FindFullFilename(newStatus.Filename);
                    }

                    if (!_previousStatus.IsValid || _previousStatus.PlaybackState != newStatus.PlaybackState)
                    {
                        if (newStatus.PlaybackState == VlcPlaybackState.Playing)
                        {
                            _timeSource.Play();
                        }
                        else
                        {
                            _timeSource.Pause();
                        }
                    }

                    if (!_previousStatus.IsValid || _previousStatus.Duration != newStatus.Duration)
                    {
                        _timeSource.SetDuration(newStatus.Duration);
                    }

                    if (!_previousStatus.IsValid || _previousStatus.Progress != newStatus.Progress)
                    {
                        _timeSource.SetPosition(newStatus.Progress);
                    }
                }

                _previousStatus = newStatus;
            }
            catch (Exception exception)
            {
                Debug.WriteLine("Couldn't interpret VLC Status: " + exception.Message);
            }
        }
예제 #6
0
        private void InterpretKodiMsgNew(string json)
        {
            if (!_timeSource.CheckAccess())
            {
                _timeSource.Dispatcher.Invoke(() => InterpretKodiMsgNew(json));
                return;
            }

            JObject json_obj;

            try
            {
                json_obj = JObject.Parse(json);
            }
            catch (Exception)
            {
                return;
            }

            string method = json_obj["method"]?.ToString();

            switch (method)
            {
            case "Player.OnAVStart":     // only available since api v9 https://kodi.wiki/view/JSON-RPC_API/v9
                // OnAVStart occurs when the first frame is drawn
            {
                Pause();         // pause because of all the synchronous http post requests and could get badly out of sync

                // always get the filepath via http json api
                string filepath = GetCurrentPlayingFile();
                OnFileOpened(filepath);

                TimeSpan current_duration = GetCurrentDuration();
                _timeSource.SetDuration(current_duration);

                // for the times when the video was resumed
                TimeSpan current_time = GetCurrentTime();         // there doesn't seem to be a race condition in Kodi 18.1 like in Kodi 15
                                                                  // needs to be tested on a slower device
                _timeSource.SetPosition(current_time);

                Play();
                _timeSource.Play();
                break;
            }

            case "Player.OnPause":
            {
                _timeSource.Pause();
                break;
            }

            case "Player.OnResume":     // also api v9+ lower apis will instead send OnPlay :/
            {
                _timeSource.Play();
                break;
            }

            case "Player.OnStop":
            {
                Console.WriteLine("stop playback");
                _timeSource.Pause();
                _timeSource.SetPosition(TimeSpan.Zero);
                break;
            }

            case "Player.OnSeek":
            {
                JObject time = (JObject)json_obj["params"]["data"]["player"]["time"];
                if (time != null)
                {
                    double hours, minutes, seconds, milliseconds;
                    if (!double.TryParse(time["hours"]?.ToString(), out hours))
                    {
                        return;
                    }
                    if (!double.TryParse(time["minutes"]?.ToString(), out minutes))
                    {
                        return;
                    }
                    if (!double.TryParse(time["seconds"]?.ToString(), out seconds))
                    {
                        return;
                    }
                    if (!double.TryParse(time["milliseconds"]?.ToString(), out milliseconds))
                    {
                        return;
                    }

                    TimeSpan pos = TimeSpan.FromHours(hours);
                    pos += TimeSpan.FromMinutes(minutes);
                    pos += TimeSpan.FromSeconds(seconds);
                    pos += TimeSpan.FromMilliseconds(milliseconds);
                    Console.WriteLine("new pos:" + pos.ToString());
                    _timeSource.SetPosition(pos);
                }
                break;
            }

            case null:
            {
                Console.WriteLine("no method");
                return;
            }

            default:
            {
                Console.WriteLine("Unhandled method: " + method);
                break;
            }
            }
        }
예제 #7
0
        private void InterpretMessage(string message, IPEndPoint source)
        {
            if (!_timeSource.CheckAccess())
            {
                _timeSource.Dispatcher.Invoke(() => InterpretMessage(message, source));
                return;
            }



            JObject data = JObject.Parse(message);

            bool   outputCommand = true;
            string command       = data["cmd"].Value <string>();

            switch (command)
            {
            case "pause":
            {
                _timeSource.Pause();
                break;
            }

            case "play":
            {
                _timeSource.Play();
                break;
            }

            case "stop":
            {
                // Not sure if this will be useful:
                // Format of local files: {"cmd":"stop", "data":"/storage/emulated/0/Download/my_video.mp4"}
                // string filename = data["data"].Value<string>().Split(new[] { '/', '\\' }, StringSplitOptions.RemoveEmptyEntries).Last();

                _timeSource.Pause();
                _timeSource.SetPosition(TimeSpan.Zero);
                break;
            }

            case "load":
            {
                string title    = data["data"]["title"].Value <string>();
                string filename = title + ".mp4";


                OnFileOpened(filename);
                _timeSource.Play();

                break;
            }

            case "seekTo":
            {
                double   miliseconds = data["data"].Value <double>();
                TimeSpan position    = TimeSpan.FromMilliseconds(miliseconds);

                if (position == _lastReceivedTimestamp)
                {
                    return;
                }

                _lastReceivedTimestamp = position;
                _timeSource.SetPosition(position);
                break;
            }

            case "headpos2":
            {
                outputCommand = false;
                break;
            }
            }

            if (outputCommand)
            {
                Debug.WriteLine("Got '" + message + "' from " + source);
            }
        }