void _u_Resync() { debug._u_Log("[TwitchChatBehavior] _u_Resync"); // Verify twitch URL is a twitch URL if (syncedURL != null) { string url = syncedURL.Get(); if (url.Length >= 23 && (url.StartsWith("https://www.twitch.tv/") || url.StartsWith("https://twitch.tv/"))) { urlIsTwitchChannel = true; } else { urlIsTwitchChannel = false; } } else { urlIsTwitchChannel = false; } // Pick a new broker for chat, only switch owners if necessary if (!_u_PlayerIsOnlineAndAvailable(Networking.GetOwner(gameObject)) && webManager.online) { // Go through synced order list of players so web connected connected clients // agree on who should be the new broker. // Could improve this by prioritizing the first online person with the fewest connections open VRCPlayerApi[] players = pool._u_GetPlayersOrdered(); if (players == null) { debug._u_Log("[TwitchChatBehavior] Error: ordered players array not initialized yet"); return; } foreach (VRCPlayerApi player in players) { if (_u_PlayerIsOnlineAndAvailable(player)) { if (player == Networking.LocalPlayer) { requestingOwnership = true; Networking.SetOwner(Networking.LocalPlayer, gameObject); } break; } } } _u_TryStartChat(); }
public override void OnVideoStart() { if (Networking.IsOwner(gameObject)) { if (_locallyPaused) { _videoStartNetworkTime = (float)Networking.GetServerTimeInSeconds() - _currentPlayer.GetTime(); } else { _videoStartNetworkTime = (float)Networking.GetServerTimeInSeconds() - _videoTargetStartTime; } _ownerPaused = _locallyPaused = false; _ownerPlaying = true; } else if (!_ownerPlaying) // Watchers pause and wait for sync from owner { _currentPlayer.Pause(); _waitForSync = true; } _statusStr = ""; _draggingSlider = false; lastVideoField.text = currentVideoField.text; currentVideoField.text = _syncedURL.Get(); _currentPlayer.SetTime(_videoTargetStartTime); _videoTargetStartTime = 0f; #if !UNITY_EDITOR // Causes null ref exceptions so just exclude it from the editor videoOwnerTextField.text = Networking.GetOwner(gameObject).displayName; #endif }
void StartVideoLoad(VRCUrl url) { if (Time.time < _delayStartLoad) { return; } if (url != null) { string urlStr = url.Get(); // RTSPT sources (and maybe others!?) trigger a spontaneous OnVideoEnd event at video start if (currentPlayerMode == PLAYER_MODE_STREAM && urlStr.Contains("rtspt://")) { _rtsptSource = true; Debug.Log("[USharpVideo] Detected RTSPT source"); } else { _rtsptSource = false; } } Debug.Log("[USharpVideo] Started video load"); _statusStr = "Loading video..."; SetStatusText(_statusStr); _delayStartLoad = 0f; _loadingVideo = true; _currentLoadingTime = 0f; _currentRetryCount = 0; _currentPlayer.Stop(); _currentPlayer.LoadURL(url); }
void _PlayVideo(VRCUrl url) { _pendingPlayTime = 0; DebugLog("Play video " + url); bool isOwner = Networking.IsOwner(gameObject); if (!isOwner && !_CanTakeControl()) { return; } if (!_IsUrlValid(url)) { return; } if (!isOwner) { Networking.SetOwner(Networking.LocalPlayer, gameObject); } _syncUrl = url; _syncVideoNumber += isOwner ? 1 : 2; _loadedVideoNumber = _syncVideoNumber; _syncOwnerPlaying = false; _syncVideoStartNetworkTime = float.MaxValue; RequestSerialization(); _videoTargetTime = _ParseTimeFromUrl(url.Get()); _StartVideoLoad(); }
public override void OnVideoStart() { Debug.Log("[USharpVideo] Video start"); if (Networking.IsOwner(gameObject)) { if (_locallyPaused) { _videoStartNetworkTime = (float)Networking.GetServerTimeInSeconds() - _currentPlayer.GetTime(); } else { _videoStartNetworkTime = (float)Networking.GetServerTimeInSeconds() - _videoTargetStartTime; } _ownerPaused = _locallyPaused = false; _ownerPlaying = true; } else if (!_ownerPlaying) // Watchers pause and wait for sync from owner { bool bypass = _streamBypassOwner && currentPlayerMode == PLAYER_MODE_STREAM; if (!bypass) { _currentPlayer.Pause(); _waitForSync = true; } } UpdateScreenMaterial(SCREEN_MODE_NORMAL); _statusStr = ""; _draggingSlider = false; lastVideoField.text = currentVideoField.text; currentVideoField.text = _syncedURL.Get(); if (currentPlayerMode == PLAYER_MODE_VIDEO) { _currentPlayer.SetTime(_videoTargetStartTime); } _videoTargetStartTime = 0f; #if !UNITY_EDITOR // Causes null ref exceptions so just exclude it from the editor videoOwnerTextField.text = Networking.GetOwner(gameObject).displayName; #endif }
public void OnURLChanged() { if (string.IsNullOrEmpty(_addressInput.GetUrl().Get())) { return; } DebugLog($"The URL has changed to `{_addressInput.GetUrl().Get()}`. Next serial is {_serialSync + 1}."); _urlSync = _addressInput.GetUrl(); _serialSync++; SetOffsetTime(GetOffsetTime(_urlSync.Get())); LoadURL(_urlSync, _serialSync); }
public void _HandleUrlInputChange() { if (!Utilities.IsValid(videoPlayer)) { return; } VRCUrl url = urlInput.GetUrl(); if (url.Get().Length > 0) { videoPlayer._UpdateQueuedUrl(urlInput.GetUrl()); } }
void _StartVideoLoad() { _pendingLoadTime = 0; if (_syncUrl == null || _syncUrl.Get() == "") { return; } DebugLog("Start video load " + _syncUrl); localPlayerState = PLAYER_STATE_LOADING; #if !UNITY_EDITOR _currentPlayer.LoadURL(_syncUrl); #endif }
void LoadURL(VRCUrl url, int serial) { if (!_player) { return; } DebugLog($"Load the video with the URL `{url.Get()}` and set the serial to {serial}."); _status = _status & ~_status_stop | _status_fetch; _url = url; _serial = serial; _messageText.text = $"Loading"; _player.Stop(); _player.LoadURL(url); ValidateView(); }
public override void OnDeserialization() { if (string.IsNullOrEmpty(_urlSync.Get())) { return; } if (_serial != _serialSync) { LoadURL(_urlSync, _serialSync); } if (_time != _timeSync) { SetElapsedTime(_timeSync); } }
bool _IsUrlValid(VRCUrl url) { if (!Utilities.IsValid(url)) { return(false); } string urlStr = url.Get(); if (urlStr == null || urlStr == "") { return(false); } return(true); }
public bool PlayVideo(VRCUrl playURL) { if (!IsValidURL(playURL.Get())) { OnVideoError(VideoError.InvalidURL); Debug.LogError($"[KineL] Loading Error: URL invalid"); return(false); } if (videoPlayer.IsPlaying) { videoPlayer.Stop(); } if (isPause) { isPauseLocal = false; } inputFieldLoadMessage.SetActive(true); videoLoadErrorController.hide(); if (Networking.IsOwner(Networking.LocalPlayer, this.gameObject)) { globalVideoID++; localVideoID = globalVideoID; isPause = false; isPlaying = true; syncedURL = playURL; url.SetUrl(VRCUrl.Empty); RequestSerialization(); Debug.Log($"[KineL] Loading ... : {syncedURL}"); SendCustomEventDelayedSeconds(nameof(OwnerPlayVideo), 1.5f); return(true); } Debug.Log($"[KineL] Loading ... : {syncedURL}"); videoPlayer.LoadURL(playURL); isPauseLocal = false; return(true); }
public string GetURLString() { return(url.Get()); }
void PlayVideo(VRCUrl url, bool disablePlaylist) { bool isOwner = Networking.IsOwner(gameObject); if (!isOwner && !Networking.IsMaster && _masterOnly) { return; } if (_syncedURL != null && url.Get() == "") { return; } if (!isOwner) { Networking.SetOwner(Networking.LocalPlayer, gameObject); } if (disablePlaylist) { // -1 means we have stopped using the playlist since we had manual input _nextPlaylistIndex = -1; } StopVideo(); _syncedURL = url; inputField.SetUrl(VRCUrl.Empty); if (isOwner) { _videoNumber++; } else // Add two to avoid having conflicts where the old owner increases the count { _videoNumber += 2; } _loadedVideoNumber = _videoNumber; StartVideoLoad(_syncedURL); _currentPlayer.Stop(); _ownerPlaying = false; _locallyPaused = _ownerPaused = false; _videoStartNetworkTime = float.MaxValue; if (Networking.IsOwner(gameObject)) { // Attempt to parse out a start time from YouTube links with t= or start= string urlStr = url.Get(); if (currentPlayerMode != PLAYER_MODE_STREAM && (urlStr.Contains("youtube.com/watch") || urlStr.Contains("youtu.be/"))) { int tIndex = -1; tIndex = urlStr.IndexOf("?t="); if (tIndex == -1) { tIndex = urlStr.IndexOf("&t="); } if (tIndex == -1) { tIndex = urlStr.IndexOf("?start="); } if (tIndex == -1) { tIndex = urlStr.IndexOf("&start="); } if (tIndex != -1) { char[] urlArr = urlStr.ToCharArray(); int numIdx = urlStr.IndexOf('=', tIndex) + 1; string intStr = ""; while (numIdx < urlArr.Length) { char currentChar = urlArr[numIdx]; if (!char.IsNumber(currentChar)) { break; } intStr += currentChar; ++numIdx; } if (intStr.Length > 0) { int secondsCount = 0; if (int.TryParse(intStr, out secondsCount)) { _videoTargetStartTime = secondsCount; } else { _videoTargetStartTime = 0f; } } else { _videoTargetStartTime = 0f; } } else { _videoTargetStartTime = 0f; } } else { _videoTargetStartTime = 0f; } } else { _videoTargetStartTime = 0f; } Debug.Log("[USharpVideo] Video URL Changed to " + _syncedURL); }
public override void OnDeserialization() { // Load new video when _videoNumber is changed if (Networking.IsOwner(gameObject)) { return; } if (_needsOwnerTransition) { _masterOnly = _masterOnlyLocal; Debug.Log("[USharpVideo] Deserialize needs transition -> " + _masterOnly); } else { _masterOnlyLocal = _masterOnly; masterLockedIcon.SetActive(_masterOnly && controlMode != CONTROL_MODE_ANY); masterUnlockedIcon.SetActive(!_masterOnly || controlMode == CONTROL_MODE_ANY); } playIcon.SetActive(_ownerPaused); pauseStopIcon.SetActive(!_ownerPaused); playlistNormalIcon.SetActive(_playlistMode == PLAYLIST_MODE_NORMAL); repeatIcon.SetActive(_playlistMode == PLAYLIST_MODE_REPEAT); // Needed to prevent "rewinding" behaviour of Udon synced strings/VRCUrl's where, when switching ownership the string will be populated with the second to last value locally observed. if (_deserializeCounter < 10) { _deserializeCounter++; return; } if (_localPlayerMode != currentPlayerMode) { ChangePlayerMode(); } if (!_ownerPaused && _locallyPaused) { Debug.Log("[USharpVideo] Play"); _currentPlayer.Play(); _locallyPaused = false; } if (_videoNumber == _loadedVideoNumber) { return; } if (_localUrl != null && _syncedURL != null && _syncedURL.Get() == _localUrl.Get()) { if (_currentPlayer.IsPlaying && _streamBypassOwner && currentPlayerMode == PLAYER_MODE_STREAM) { _loadedVideoNumber = _videoNumber; return; } } _localUrl = _syncedURL; _currentPlayer.Stop(); StartVideoLoad(_syncedURL); SyncVideo(); _loadedVideoNumber = _videoNumber; Debug.Log("[USharpVideo] Playing synced " + _syncedURL); }