Beispiel #1
0
 private void OnMenuSceneLoadedFresh()
 {
     VideoUI.Instance.OnLoad();
     ScreenManager.OnLoad();
     VideoLoader.OnLoad();
     CreateSettingsUI();
 }
Beispiel #2
0
        // private void OnMenuSceneLoaded()
        // {
        //     ScreenManager.OnLoad();
        // }

        private static void OnMenuSceneLoadedFresh(ScenesTransitionSetupDataSO scenesTransition)
        {
            YouTubeDownloader.OnLoad();
            ScreenManager.OnLoad();
            VideoLoader.OnLoad();
            VideoMenu.instance.OnLoad();
        }
Beispiel #3
0
        public Process MakeDebugYoutubeProcessAndReturnIt(VideoData video)
        {
            string levelPath = VideoLoader.GetLevelPath(video.level);

            if (!Directory.Exists(levelPath))
            {
                Directory.CreateDirectory(levelPath);
            }

            string videoFileName = video.title;

            // Strip invalid characters
            foreach (var c in Path.GetInvalidFileNameChars())
            {
                videoFileName = videoFileName.Replace(c, '-');
            }

            videoFileName = videoFileName.Replace('\\', '-');
            videoFileName = videoFileName.Replace('/', '-');

            video.videoPath = videoFileName + ".mp4";


            Plugin.logger.Info("Name Created");
            // Download the video via youtube-dl
            var ytProcess = new Process
            {
                StartInfo =
                {
                    FileName  = Environment.CurrentDirectory + "/Youtube-dl/youtube-dl.exe",
                    Arguments = "https://www.youtube.com" + video.URL +
                                " -f \"" + VideoQualitySetting.Format(quality) + "\"" + // Formats
                                " --no-cache-dir" +                                     // Don't use temp storage
                                $" -o \"{EscapeStringForPythonStringFormatter(videoFileName)}.%(ext)s\"" +
                                " --no-playlist" +                                      // Don't download playlists, only the first video
                                " --no-part" +                                          // Don't store download in parts, write directly to file
                                (hasFFMPEG
                                    ? " --recode-video mp4"
                                    : ""
                                ) +                      //Try to recode the video if ffmpeg is installed to fix issue with improper encoding
                                " --no-mtime" +          //Video last modified will be when it was downloaded, not when it was uploaded to youtube
                                " --socket-timeout 10" + //Retry if no response in 10 seconds Note: Not if download takes more than 10 seconds but if the time between any 2 messages from the server is 10 seconds
                                " --no-continue"         //overwrite existing file and force re-download
                    ,
                    RedirectStandardOutput = false,
                    RedirectStandardError  = false,
                    UseShellExecute        = true,
                    CreateNoWindow         = true,
                    WorkingDirectory       = levelPath
                },
                EnableRaisingEvents = true,
                //I think these are added only after Process Started
                //PriorityClass = ProcessPriorityClass.RealTime,
                //PriorityBoostEnabled = true
            };

            YouTubeDownloader.externalProcesses.Add(ytProcess);

            return(ytProcess);
        }
Beispiel #4
0
 private void OnMenuSceneLoadedFresh()
 {
     YouTubeDownloader.OnLoad();
     ScreenManager.OnLoad();
     VideoLoader.OnLoad();
     VideoMenu.instance.OnLoad();
 }
 private void DetailViewBackPressed()
 {
     VideoLoader.SaveVideoToDisk(selectedLevelVideo);
     finished?.Invoke(selectedLevelVideo);
     _freePlayFlowCoordinator.InvokePrivateMethod("DismissFlowCoordinator", new object[] { this, null, false });
     ScreenManager.Instance.PrepareVideo(selectedLevelVideo);
     ScreenManager.Instance.HideScreen();
 }
 private void Save()
 {
     if (selectedVideo != null)
     {
         StopPreview(false);
         VideoLoader.SaveVideoToDisk(selectedVideo);
     }
 }
Beispiel #7
0
        public override void Init()
        {
            WhiteColor = Def.Get("whiteColor", Color.white);
            BlackColor = Def.Get("blackColor", new Color(0, 0, 0, 0));
            toRepeat   = Def.Get("times", 1) - 1;
            FilePath   = Def.Get <string>("filePath");

            // Resolve the file path.
            ModContentPack mcp = Def.modContentPack;

            if (mcp == null)
            {
                string[] split = FilePath.Split('/');
                split[0] = split[0].ToLowerInvariant();
                Core.Warn($"Video program def '{Def.defName}' has been added by a patch operation. Attempting to resolve filepath...");
                var found = LoadedModManager.RunningModsListForReading.FirstOrFallback(mod => mod.PackageId.ToLowerInvariant() == split[0]);
                if (found == null)
                {
                    Core.Error($"Failed to resolve mod folder path from id '{split[0]}'. See below for how to solve this issue.");
                    Core.Error("If you mod's package ID is 'my.mod.name' and your video file is in 'MyModFolder/Videos/Video.bwcv' then the correct filePath would be 'my.mod.name/Videos/Video.bwcv'");
                    Remove();
                    return;
                }
                Core.Warn("Successfully resolved file path.");
                mcp = found;
            }
            FilePath = Path.Combine(mcp.RootDir, FilePath);
            if (string.IsNullOrEmpty(new FileInfo(FilePath).Extension))
            {
                FilePath += ".bwcv";
            }

            // Load video on another thread.
            Task.Run(() =>
            {
                try
                {
                    VideoLoader vid = new VideoLoader();
                    vid.Load(FilePath);
                    Core.Log($"Loaded {vid.BytesLoaded} bytes of video data from {FilePath}");
                    if (!vid.LoadNextFrame())
                    {
                        throw new Exception("Failed to load first frame");
                    }
                    this.video = vid;
                }
                catch (Exception e)
                {
                    Core.Error($"Exception loading video program from '{FilePath}'", e);
                    this.Remove();
                }
            });
        }
        public void Load(string filename)
        {
            if (filename == cachedVideo)
            {
                return;
            }

            var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), Game.ModData.VideoLoaders);

            Open(video);

            cachedVideo = filename;
        }
Beispiel #9
0
    void Start()
    {
        Vloader          = this.gameObject.GetComponent <VideoLoader>();
        Vplayer          = this.gameObject.GetComponent <VideoPlayer>();
        afterButtonVideo = GameObject.Find("afterButtonVideo");

        Vplayer.time = afterButtonTime = 0.0f;
        leftTime     = Random.Range(12.5f, 19.0f);
        rightTime    = Random.Range(12.5f, 19.0f);

        switched[0] = switched[1] = switched[2] = false;
        isHunged    = false;
    }
    // Use this for initialization
    void Start()
    {
        if (instance == null)
        {
            instance = this;
        }
        else
        {
            Destroy(this);
        }
        path     = Application.streamingAssetsPath + "/video";
        fileName = "video.ogv";
        player   = GetComponent <RawImage>();
        sound    = GetComponent <AudioSource>();

        StartCoroutine(loadMovie());
    }
Beispiel #11
0
        public Process MakeYoutubeProcessAndReturnIt(VideoData video)
        {
            string levelPath = VideoLoader.GetLevelPath(video.level);

            if (!Directory.Exists(levelPath))
            {
                Directory.CreateDirectory(levelPath);
            }

            string videoFileName = video.title;

            // Strip invalid characters
            foreach (var c in Path.GetInvalidFileNameChars())
            {
                videoFileName = videoFileName.Replace(c, '-');
            }
            videoFileName = videoFileName.Replace('\\', '-');
            videoFileName = videoFileName.Replace('/', '-');

            video.videoPath = videoFileName + ".mp4";

            // Download the video via youtube-dl
            var ytProcess = new Process
            {
                StartInfo =
                {
                    FileName  = Environment.CurrentDirectory + "/Youtube-dl/youtube-dl.exe",
                    Arguments = "https://www.youtube.com" + video.URL +
                                " -f \"" + VideoQualitySetting.Format(quality) + "\"" + // Formats
                                " --no-cache-dir" +                                     // Don't use temp storage
                                " -o \"" + levelPath + $"\\{videoFileName}.%(ext)s\"" +
                                " --no-playlist" +                                      // Don't download playlists, only the first video
                                " --no-part" +                                          // Don't store download in parts, write directly to file
                                (hasFFMPEG ? " --recode-video mp4" : ""),
                    RedirectStandardOutput = true,
                    RedirectStandardError  = true,
                    UseShellExecute        = false,
                    CreateNoWindow         = true
                },
                EnableRaisingEvents = true
            };

            return(ytProcess);
        }
Beispiel #12
0
        public override void Tick()
        {
            base.Tick();

            if (video == null)
            {
                return;
            }

            if (frameSwapInterval <= 0)
            {
                frameSwapInterval = 60 / VideoFrameRate;

                int gw   = DJStand.FloorBounds.Width;
                int gh   = DJStand.FloorBounds.Height;
                int offX = Mathf.RoundToInt((gw - VideoWidth) / 2f);
                int offZ = Mathf.RoundToInt((gh - VideoHeight) / 2f);
                int minX = DJStand.FloorBounds.minX + offX;
                int minZ = DJStand.FloorBounds.minZ + offZ;
                vidBounds = new CellRect(minX, minZ, VideoWidth, VideoHeight);
            }

            tickCounterCustom++;
            if (tickCounterCustom % frameSwapInterval == 0)
            {
                bool hasNextFrame = video.LoadNextFrame();
                if (!hasNextFrame)
                {
                    if (toRepeat > 0)
                    {
                        video.Restart();
                        tickCounterCustom = 1;
                        toRepeat--;
                    }
                    else
                    {
                        Remove();
                        video.Dispose();
                        video = null;
                    }
                }
            }
        }
        private void StartDownload(YTResult result)
        {
            // Delete existing
            if (selectedLevelVideo != null)
            {
                VideoLoader.Instance.RemoveVideo(selectedLevelVideo);

                switch (selectedLevelVideo.downloadState)
                {
                case DownloadState.Downloaded:
                    VideoLoader.Instance.DeleteVideo(selectedLevelVideo);
                    break;

                case DownloadState.Downloading:
                case DownloadState.Queued:
                    selectedLevelVideo.downloadState = DownloadState.Cancelled;     // stop download and dequeue
                    break;

                default:     // not downloaded, other
                    break;
                }
                selectedLevelVideo = null;
            }

            VideoData video = new VideoData(result);

            video.level        = selectedLevel;
            selectedLevelVideo = video;

            YouTubeDownloader.Instance.EnqueueVideo(video);
            VideoLoader.Instance.AddVideo(video);
            VideoLoader.SaveVideoToDisk(video);

            _videoDetailViewController.SetContent(video);
            _videoDetailViewController.UpdateContent();

            VideoDownloaderDownloadProgress(video);

            DismissViewController(_videoListViewController);
        }
Beispiel #14
0
        private IEnumerator DownloadVideo()
        {
            downloading = true;
            IncrementDownloadCount();
            if (!updated)
            {
                yield return(new WaitUntil(() => updated));
            }
            VideoDownload download = videoQueue.Peek();
            VideoData     video    = download.video;

//            Plugin.logger.Debug($"Starting Download with {video.title}");

            if (video.downloadState == DownloadState.Cancelled || download.downloadAttempts > MaxRetries)
            {
                // skip
                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
//                    Plugin.logger.Debug($"Starting Next Download");
                    // Start next download
                    DownloadVideo();
                }
                else
                {
//                    Plugin.logger.Debug($"Done Download");
                    // queue empty
                    downloading = false;
                    yield break;
                }
            }

            Plugin.logger.Info("Downloading: " + video.title);

            IEnumerator countdown = Countdown(download);

            StopCoroutine(countdown);

            video.downloadState = DownloadState.Downloading;
            downloadProgress?.Invoke(video);
            download.Update();

            ydl = MakeYoutubeProcessAndReturnIt(video);

            Plugin.logger.Info($"yt command: \"{ydl.StartInfo.FileName}\" {ydl.StartInfo.Arguments}");

            ydl.Start();

            // Hook up our output to console
            ydl.BeginOutputReadLine();
            ydl.BeginErrorReadLine();

            int logCount = 0;

            ydl.OutputDataReceived += (sender, e) =>
            {
                if (e.Data != null)
                {
                    Regex rx    = new Regex(@"(\d*).\d%+");
                    Match match = rx.Match(e.Data);
                    if (match.Success)
                    {
                        video.downloadProgress = Single.Parse(match.Value.Substring(0, match.Value.Length - 1)) / 100;
                        downloadProgress?.Invoke(video);
                        download.Update();

                        if (video.downloadState == DownloadState.Cancelled)
                        {
                            DownloadCancelled((Process)sender, video);
                        }
                    }

                    if (++logCount % 10 == 0 || video.downloadProgress > .95)
                    {
                        Plugin.logger.Info(e.Data);
                    }
                }
            };

            ydl.ErrorDataReceived += (sender, e) =>
            {
                if (e.Data.Length < 3)
                {
                    return;
                }
                Plugin.logger.Error(e.Data);
                //TODO: check these errors are problems - re-download or skip file when an error occurs
                //video.downloadState = DownloadState.Cancelled;
                downloadProgress?.Invoke(video);
                download.Update();

                if (video.downloadState == DownloadState.Cancelled || e.Data.Contains("Unable to extract video data"))
                {
                    DownloadCancelled((Process)sender, video);
                }
            };

            ydl.Exited += (sender, e) =>
            {
                StopCoroutine(countdown);

                if (video.downloadState == DownloadState.Cancelled)
                {
                    Plugin.logger.Info("Cancelled");
                    VideoLoader.DeleteVideo(video);
                }
                else
                {
                    // video.downloadState = DownloadState.Downloaded;
                    video.UpdateDownloadState();
                    VideoLoader.SaveVideoToDisk(video);
                    StartCoroutine(VerifyDownload(video));
                }

                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    // Start next download
//                    Plugin.logger.Debug("Starting Next Download");
                    DownloadVideo();
                }
                else
                {
                    // queue empty
                    downloading = false;
                }

                try
                {
                    ydl?.Dispose();
                } catch { }

                DecrementDownloadCount();
            };
        }
Beispiel #15
0
        //Must Call using StartCoroutine
        private IEnumerator DownloadVideo(VideoData video, bool logProgress = true)
        {
            Plugin.logger.Info($"Starting Download with {video.title}");
            IncrementDownloadCount();
            if (!updated)
            {
                yield return(new WaitUntil(() => updated));
            }
            //Plugin.logger.Debug("Update Finished");
            if (video.downloadState == DownloadState.Cancelled)
            {
//                Plugin.logger.Debug("Download Cancelled");
                yield return(null);
            }
            else
            {
                Plugin.logger.Info("Downloading: " + video.title);

                video.downloadState = DownloadState.Downloading;
//                Plugin.logger.Debug("Set State");
                downloadProgress?.Invoke(video);
//                Plugin.logger.Debug("Invoked");

                Process localDownloader = MakeYoutubeProcessAndReturnIt(video);

                Plugin.logger.Info(
                    $"yt command: \"{localDownloader.StartInfo.FileName}\" {localDownloader.StartInfo.Arguments}");

                var countdown = Countdown(localDownloader, new TimeSpan(0, 1, 0));
                // var outputCount = 0;
                var timer = new Timer(250);
                timer.Elapsed += (sender, args) => downloadProgress?.Invoke(video);
                localDownloader.OutputDataReceived += (sender, e) =>
                {
                    if (video.downloadState == DownloadState.Cancelled)
                    {
                        try
                        {
                            ((Process)sender)?.Kill();
                        } catch { }
                        Plugin.logger.Info("Cancelled");
                        VideoLoader.DeleteVideo(video, false);
                        YouTubeDownloader.externalProcesses.Remove(sender as Process);
                    }

                    // if(++outputCount % 10 != 0) return;
                    ParseDownload(video, logProgress, e);
                };
                localDownloader.ErrorDataReceived += (sender, e) =>
                {
                    if (e.Data.Length < 3)
                    {
                        return;
                    }
                    Plugin.logger.Error(e.Data);
                    //TODO: check these errors are problems - re-download or skip file when an error occurs
                    //video.downloadState = DownloadState.Cancelled;
                    downloadProgress?.Invoke(video);
                    if (video.downloadState == DownloadState.Cancelled ||
                        e.Data.Contains("Unable to extract video data"))
                    {
                        DownloadCancelled((Process)sender, video);
                    }
                };
                localDownloader.Exited += (sender, e) =>
                {
                    timer.Stop();
                    timer.Close();
                    StopCoroutine(countdown);
                    DecrementDownloadCount();
                    if (video.downloadState == DownloadState.Cancelled)
                    {
                        Plugin.logger.Info("Cancelled");
                        VideoLoader.DeleteVideo(video, false);
                    }
                    else
                    {
                        video.downloadState = DownloadState.Downloaded;
                        VideoLoader.SaveVideoToDisk(video);
                        StartCoroutine(VerifyDownload(video));
                        Plugin.logger.Info(
                            $"Done Downloading {video.title} with {VideosDownloading} remaining downloads");
                    }

                    try
                    {
                        localDownloader?.Dispose();
                    } catch { }

                    YouTubeDownloader.externalProcesses.Remove(localDownloader);
                    // Don't load video since it will be loaded (or not) after VerifyDownload
                };
                timer.Start();
                yield return(localDownloader.Start());

                StartCoroutine(countdown);

//                Plugin.logger.Debug("Started Downloaded For Realsies");
                // Hook up our output to console
                localDownloader.BeginOutputReadLine();
                localDownloader.BeginErrorReadLine();
            }
        }
Beispiel #16
0
 public static IVideo LoadVideo(Stream s)
 {
     return(VideoLoader.GetVideo(s, true, Game.ModData.VideoLoaders));
 }
Beispiel #17
0
        private IEnumerator DownloadVideo()
        {
            Plugin.logger.Debug($"Starting Download");
            downloading = true;
            Plugin.logger.Debug($"Starting Download");

            if (!updated)
            {
                yield return(new WaitUntil(() => updated));
            }
            Plugin.logger.Debug($"Starting Download2");

            VideoDownload download = videoQueue.Peek();

            Plugin.logger.Debug($"Starting Download3");
            VideoData video = download.video;

            Plugin.logger.Debug($"Starting Download with {download.video.title}");

            if (video.downloadState == DownloadState.Cancelled || download.downloadAttempts > MaxRetries)
            {
                // skip
                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    Plugin.logger.Debug($"Starting Next Download");
                    // Start next download
                    DownloadVideo();
                }
                else
                {
                    Plugin.logger.Debug($"Done Download");
                    // queue empty
                    downloading = false;
                    yield break;
                }
            }
            Plugin.logger.Info("Downloading: " + video.title);

            StopCoroutine(Countdown(download));
            Plugin.logger.Debug($"Counting");

            video.downloadState = DownloadState.Downloading;
            downloadProgress?.Invoke(video);
            Plugin.logger.Debug($"Invoked");
            download.Update();
            Plugin.logger.Debug($"Updated");

            ydl = MakeYoutubeProcessAndReturnIt(video);

            Plugin.logger.Debug($"yt command: {ydl.StartInfo.FileName} {ydl.StartInfo.Arguments}");

            ydl.Start();

            // Hook up our output to console
            ydl.BeginOutputReadLine();
            ydl.BeginErrorReadLine();

            ydl.OutputDataReceived += (sender, e) => {
                if (e.Data != null)
                {
                    Regex rx    = new Regex(@"(\d*).\d%+");
                    Match match = rx.Match(e.Data);
                    if (match.Success)
                    {
                        video.downloadProgress = float.Parse(match.Value.Substring(0, match.Value.Length - 1)) / 100;
                        downloadProgress?.Invoke(video);
                        download.Update();

                        if (video.downloadState == DownloadState.Cancelled)
                        {
                            (sender as Process).Kill();
                        }
                    }
                    Plugin.logger.Info(e.Data);
                }
            };

            ydl.ErrorDataReceived += (sender, e) => {
                if (e.Data.Length < 3)
                {
                    return;
                }
                //TODO: check these errors are problems - re-download or skip file when an error occurs
                //video.downloadState = DownloadState.Cancelled;
                downloadProgress?.Invoke(video);
                download.Update();
            };

            ydl.Exited += (sender, e) => {
                StopCoroutine(Countdown(download));

                if (video.downloadState == DownloadState.Cancelled)
                {
                    Plugin.logger.Debug("Cancelled");
                    VideoLoader.Instance.DeleteVideo(video);
                }
                else
                {
                    video.downloadState = DownloadState.Downloaded;
                    VideoLoader.SaveVideoToDisk(video);
                    StartCoroutine(VerifyDownload(video));
                }

                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    // Start next download
                    Plugin.logger.Debug("Starting Next Download");
                    DownloadVideo();
                }
                else
                {
                    // queue empty
                    downloading = false;
                }
                ydl.Dispose();
            };
        }
Beispiel #18
0
        public AssetBrowserLogic(Widget widget, Action onExit, ModData modData, World world, Dictionary <string, MiniYaml> logicArgs)
        {
            this.world   = world;
            this.modData = modData;
            panel        = widget;

            var ticker = panel.GetOrNull <LogicTickerWidget>("ANIMATION_TICKER");

            if (ticker != null)
            {
                ticker.OnTick = () =>
                {
                    if (animateFrames)
                    {
                        SelectNextFrame();
                    }
                };
            }

            var sourceDropdown = panel.GetOrNull <DropDownButtonWidget>("SOURCE_SELECTOR");

            if (sourceDropdown != null)
            {
                sourceDropdown.OnMouseDown = _ => ShowSourceDropdown(sourceDropdown);
                var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
                sourceDropdown.GetText = () => sourceName.Update(assetSource);
            }

            var spriteWidget = panel.GetOrNull <SpriteWidget>("SPRITE");

            if (spriteWidget != null)
            {
                spriteWidget.GetSprite  = () => currentSprites != null ? currentSprites[currentFrame] : null;
                currentPalette          = spriteWidget.Palette;
                spriteWidget.GetPalette = () => currentPalette;
                spriteWidget.IsVisible  = () => !isVideoLoaded && !isLoadError && currentSprites != null;
            }

            var playerWidget = panel.GetOrNull <VideoPlayerWidget>("PLAYER");

            if (playerWidget != null)
            {
                playerWidget.IsVisible = () => isVideoLoaded && !isLoadError;
            }

            var modelWidget = panel.GetOrNull <ModelWidget>("VOXEL");

            if (modelWidget != null)
            {
                modelWidget.GetVoxel         = () => currentVoxel;
                currentPalette               = modelWidget.Palette;
                modelWidget.GetPalette       = () => currentPalette;
                modelWidget.GetPlayerPalette = () => currentPalette;
                modelWidget.GetRotation      = () => modelOrientation;
                modelWidget.IsVisible        = () => !isVideoLoaded && !isLoadError && currentVoxel != null;
            }

            var errorLabelWidget = panel.GetOrNull("ERROR");

            if (errorLabelWidget != null)
            {
                errorLabelWidget.IsVisible = () => isLoadError;
            }

            var paletteDropDown = panel.GetOrNull <DropDownButtonWidget>("PALETTE_SELECTOR");

            if (paletteDropDown != null)
            {
                paletteDropDown.OnMouseDown = _ => ShowPaletteDropdown(paletteDropDown, world);
                paletteDropDown.GetText     = () => currentPalette;
            }

            var colorPreview = panel.GetOrNull <ColorPreviewManagerWidget>("COLOR_MANAGER");

            if (colorPreview != null)
            {
                colorPreview.Color = Game.Settings.Player.Color;
            }

            var colorDropdown = panel.GetOrNull <DropDownButtonWidget>("COLOR");

            if (colorDropdown != null)
            {
                colorDropdown.IsDisabled  = () => currentPalette != colorPreview.PaletteName;
                colorDropdown.OnMouseDown = _ => ColorPickerLogic.ShowColorDropDown(colorDropdown, colorPreview, world);
                panel.Get <ColorBlockWidget>("COLORBLOCK").GetColor = () => Game.Settings.Player.Color;
            }

            filenameInput = panel.Get <TextFieldWidget>("FILENAME_INPUT");
            filenameInput.OnTextEdited = () => ApplyFilter();
            filenameInput.OnEscKey     = filenameInput.YieldKeyboardFocus;

            var frameContainer = panel.GetOrNull("FRAME_SELECTOR");

            if (frameContainer != null)
            {
                frameContainer.IsVisible = () => (currentSprites != null && currentSprites.Length > 1) ||
                                           (isVideoLoaded && player != null && player.Video != null && player.Video.Frames > 1);
            }

            frameSlider = panel.GetOrNull <SliderWidget>("FRAME_SLIDER");
            if (frameSlider != null)
            {
                frameSlider.OnChange += x =>
                {
                    if (!isVideoLoaded)
                    {
                        currentFrame = (int)Math.Round(x);
                    }
                };

                frameSlider.GetValue   = () => isVideoLoaded ? player.Video.CurrentFrame : currentFrame;
                frameSlider.IsDisabled = () => isVideoLoaded;
            }

            var frameText = panel.GetOrNull <LabelWidget>("FRAME_COUNT");

            if (frameText != null)
            {
                frameText.GetText = () =>
                                    isVideoLoaded ?
                                    "{0} / {1}".F(player.Video.CurrentFrame + 1, player.Video.Frames) :
                                    "{0} / {1}".F(currentFrame, currentSprites.Length - 1);
            }

            var playButton = panel.GetOrNull <ButtonWidget>("BUTTON_PLAY");

            if (playButton != null)
            {
                playButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Play();
                    }
                    else
                    {
                        animateFrames = true;
                    }
                };

                playButton.IsVisible = () => isVideoLoaded ? player.Paused : !animateFrames;
            }

            var pauseButton = panel.GetOrNull <ButtonWidget>("BUTTON_PAUSE");

            if (pauseButton != null)
            {
                pauseButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Pause();
                    }
                    else
                    {
                        animateFrames = false;
                    }
                };

                pauseButton.IsVisible = () => isVideoLoaded ? !player.Paused : animateFrames;
            }

            var stopButton = panel.GetOrNull <ButtonWidget>("BUTTON_STOP");

            if (stopButton != null)
            {
                stopButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    else
                    {
                        if (frameSlider != null)
                        {
                            frameSlider.Value = 0;
                        }

                        currentFrame  = 0;
                        animateFrames = false;
                    }
                };
            }

            var nextButton = panel.GetOrNull <ButtonWidget>("BUTTON_NEXT");

            if (nextButton != null)
            {
                nextButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        nextButton.OnClick = SelectNextFrame;
                    }
                };

                nextButton.IsVisible = () => !isVideoLoaded;
            }

            var prevButton = panel.GetOrNull <ButtonWidget>("BUTTON_PREV");

            if (prevButton != null)
            {
                prevButton.OnClick = () =>
                {
                    if (!isVideoLoaded)
                    {
                        SelectPreviousFrame();
                    }
                };

                prevButton.IsVisible = () => !isVideoLoaded;
            }

            var voxelContainer = panel.GetOrNull("VOXEL_SELECTOR");

            if (voxelContainer != null)
            {
                voxelContainer.IsVisible = () => currentVoxel != null;
            }

            var rollSlider = panel.GetOrNull <SliderWidget>("ROLL_SLIDER");

            if (rollSlider != null)
            {
                rollSlider.OnChange += x =>
                {
                    var roll = (int)x;
                    modelOrientation = modelOrientation.WithRoll(new WAngle(roll));
                };

                rollSlider.GetValue = () => modelOrientation.Roll.Angle;
            }

            var pitchSlider = panel.GetOrNull <SliderWidget>("PITCH_SLIDER");

            if (pitchSlider != null)
            {
                pitchSlider.OnChange += x =>
                {
                    var pitch = (int)x;
                    modelOrientation = modelOrientation.WithPitch(new WAngle(pitch));
                };

                pitchSlider.GetValue = () => modelOrientation.Pitch.Angle;
            }

            var yawSlider = panel.GetOrNull <SliderWidget>("YAW_SLIDER");

            if (yawSlider != null)
            {
                yawSlider.OnChange += x =>
                {
                    var yaw = (int)x;
                    modelOrientation = modelOrientation.WithYaw(new WAngle(yaw));
                };

                yawSlider.GetValue = () => modelOrientation.Yaw.Angle;
            }

            var assetBrowserModData = modData.Manifest.Get <AssetBrowser>();

            allowedExtensions = assetBrowserModData.SupportedExtensions;

            acceptablePackages = modData.ModFiles.MountedPackages.Where(p =>
                                                                        p.Contents.Any(c => allowedExtensions.Contains(Path.GetExtension(c).ToLowerInvariant())));

            assetList = panel.Get <ScrollPanelWidget>("ASSET_LIST");
            template  = panel.Get <ScrollItemWidget>("ASSET_TEMPLATE");
            PopulateAssetList();

            var closeButton = panel.GetOrNull <ButtonWidget>("CLOSE_BUTTON");

            if (closeButton != null)
            {
                closeButton.OnClick = () =>
                {
                    if (isVideoLoaded)
                    {
                        player.Stop();
                    }
                    Ui.CloseWindow();
                    onExit();
                }
            }
            ;
        }

        void SelectNextFrame()
        {
            currentFrame++;
            if (currentFrame >= currentSprites.Length)
            {
                currentFrame = 0;
            }
        }

        void SelectPreviousFrame()
        {
            currentFrame--;
            if (currentFrame < 0)
            {
                currentFrame = currentSprites.Length - 1;
            }
        }

        Dictionary <string, bool> assetVisByName = new Dictionary <string, bool>();

        bool FilterAsset(string filename)
        {
            var filter = filenameInput.Text;

            if (string.IsNullOrWhiteSpace(filter))
            {
                return(true);
            }

            if (filename.IndexOf(filter, StringComparison.OrdinalIgnoreCase) >= 0)
            {
                return(true);
            }

            return(false);
        }

        void ApplyFilter()
        {
            assetVisByName.Clear();
            assetList.Layout.AdjustChildren();
            assetList.ScrollToTop();

            // Select the first visible
            var firstVisible = assetVisByName.FirstOrDefault(kvp => kvp.Value);

            if (firstVisible.Key != null && modData.DefaultFileSystem.TryGetPackageContaining(firstVisible.Key, out var package, out var filename))
            {
                LoadAsset(package, filename);
            }
        }

        void AddAsset(ScrollPanelWidget list, string filepath, IReadOnlyPackage package, ScrollItemWidget template)
        {
            var item = ScrollItemWidget.Setup(template,
                                              () => currentFilename == filepath && currentPackage == package,
                                              () => { LoadAsset(package, filepath); });

            var label = item.Get <LabelWithTooltipWidget>("TITLE");

            WidgetUtils.TruncateLabelToTooltip(label, filepath);

            item.IsVisible = () =>
            {
                if (assetVisByName.TryGetValue(filepath, out var visible))
                {
                    return(visible);
                }

                visible = FilterAsset(filepath);
                assetVisByName.Add(filepath, visible);
                return(visible);
            };

            list.AddChild(item);
        }

        bool LoadAsset(IReadOnlyPackage package, string filename)
        {
            if (isVideoLoaded)
            {
                player.Stop();
                player        = null;
                isVideoLoaded = false;
            }

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!package.Contains(filename))
            {
                return(false);
            }

            isLoadError = false;

            try
            {
                currentPackage  = package;
                currentFilename = filename;
                var prefix = "";

                if (modData.DefaultFileSystem is OpenRA.FileSystem.FileSystem fs)
                {
                    prefix = fs.GetPrefix(package);
                    if (prefix != null)
                    {
                        prefix += "|";
                    }
                }

                var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), Game.ModData.VideoLoaders);
                if (video != null)
                {
                    player = panel.Get <VideoPlayerWidget>("PLAYER");
                    player.Load(prefix + filename);
                    player.DrawOverlay = false;
                    isVideoLoaded      = true;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)player.Video.Frames - 1;
                        frameSlider.Ticks        = 0;
                    }

                    return(true);
                }

                if (Path.GetExtension(filename.ToLowerInvariant()) == ".vxl")
                {
                    var voxelName = Path.GetFileNameWithoutExtension(filename);
                    currentVoxel   = world.ModelCache.GetModel(voxelName);
                    currentSprites = null;
                }
                else
                {
                    currentSprites = world.Map.Rules.Sequences.SpriteCache[prefix + filename];
                    currentFrame   = 0;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                        frameSlider.Ticks        = currentSprites.Length;
                    }

                    currentVoxel = null;
                }
            }
            catch (Exception ex)
            {
                isLoadError = true;
                Log.AddChannel("assetbrowser", "assetbrowser.log");
                Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine);

                return(false);
            }

            return(true);
        }

        bool ShowSourceDropdown(DropDownButtonWidget dropdown)
        {
            var sourceName = new CachedTransform <IReadOnlyPackage, string>(GetSourceDisplayName);
            Func <IReadOnlyPackage, ScrollItemWidget, ScrollItemWidget> setupItem = (source, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => assetSource == source,
                                                  () => { assetSource = source; PopulateAssetList(); });

                item.Get <LabelWidget>("LABEL").GetText = () => sourceName.Update(source);
                return(item);
            };

            var sources = new[] { (IReadOnlyPackage)null }.Concat(acceptablePackages);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, sources, setupItem);
            return(true);
        }

        void PopulateAssetList()
        {
            assetList.RemoveChildren();

            var files = new SortedList <string, List <IReadOnlyPackage> >();

            if (assetSource != null)
            {
                foreach (var content in assetSource.Contents)
                {
                    files.Add(content, new List <IReadOnlyPackage> {
                        assetSource
                    });
                }
            }
            else
            {
                foreach (var mountedPackage in modData.ModFiles.MountedPackages)
                {
                    foreach (var content in mountedPackage.Contents)
                    {
                        if (!files.ContainsKey(content))
                        {
                            files.Add(content, new List <IReadOnlyPackage> {
                                mountedPackage
                            });
                        }
                        else
                        {
                            files[content].Add(mountedPackage);
                        }
                    }
                }
            }

            foreach (var file in files.OrderBy(s => s.Key))
            {
                if (!allowedExtensions.Any(ext => file.Key.EndsWith(ext, true, CultureInfo.InvariantCulture)))
                {
                    continue;
                }

                foreach (var package in file.Value)
                {
                    AddAsset(assetList, file.Key, package, template);
                }
            }
        }

        bool ShowPaletteDropdown(DropDownButtonWidget dropdown, World world)
        {
            Func <string, ScrollItemWidget, ScrollItemWidget> setupItem = (name, itemTemplate) =>
            {
                var item = ScrollItemWidget.Setup(itemTemplate,
                                                  () => currentPalette == name,
                                                  () => currentPalette = name);
                item.Get <LabelWidget>("LABEL").GetText = () => name;

                return(item);
            };

            var palettes = world.WorldActor.TraitsImplementing <IProvidesAssetBrowserPalettes>()
                           .SelectMany(p => p.PaletteNames);

            dropdown.ShowDropDown("LABEL_DROPDOWN_TEMPLATE", 280, palettes, setupItem);
            return(true);
        }

        string GetSourceDisplayName(IReadOnlyPackage source)
        {
            if (source == null)
            {
                return("All Packages");
            }

            // Packages that are explicitly mounted in the filesystem use their explicit mount name
            var fs   = (OpenRA.FileSystem.FileSystem)modData.DefaultFileSystem;
            var name = fs.GetPrefix(source);

            // Fall back to the path relative to the mod, engine, or support dir
            if (name == null)
            {
                name = source.Name;
                var compare = Platform.CurrentPlatform == PlatformType.Windows ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
                if (name.StartsWith(modData.Manifest.Package.Name, compare))
                {
                    name = "$" + modData.Manifest.Id + "/" + name.Substring(modData.Manifest.Package.Name.Length + 1);
                }
                else if (name.StartsWith(Platform.EngineDir, compare))
                {
                    name = "./" + name.Substring(Platform.EngineDir.Length);
                }
                else if (name.StartsWith(Platform.SupportDir, compare))
                {
                    name = "^" + name.Substring(Platform.SupportDir.Length);
                }
            }

            if (name.Length > 18)
            {
                name = "..." + name.Substring(name.Length - 15);
            }

            return(name);
        }
    }
Beispiel #19
0
 private void OnMenuSceneLoadedFresh(ScenesTransitionSetupDataSO scenesTransition)
 {
     ScreenManager.OnLoad();
     VideoLoader.OnLoad();
     VideoMenu.instance.OnLoad();
 }
        bool LoadAsset(IReadOnlyPackage package, string filename)
        {
            ClearLoadedAssets();

            if (string.IsNullOrEmpty(filename))
            {
                return(false);
            }

            if (!package.Contains(filename))
            {
                return(false);
            }

            isLoadError = false;

            try
            {
                currentPackage  = package;
                currentFilename = filename;
                var prefix = "";

                if (modData.DefaultFileSystem is OpenRA.FileSystem.FileSystem fs)
                {
                    prefix = fs.GetPrefix(package);
                    if (prefix != null)
                    {
                        prefix += "|";
                    }
                }

                var fileExtension = Path.GetExtension(filename.ToLowerInvariant());
                if (allowedSpriteExtensions.Contains(fileExtension))
                {
                    currentSprites = world.Map.Rules.Sequences.SpriteCache[prefix + filename];
                    currentFrame   = 0;

                    if (frameSlider != null)
                    {
                        frameSlider.MaximumValue = (float)currentSprites.Length - 1;
                        frameSlider.Ticks        = currentSprites.Length;
                    }

                    currentVoxel = null;
                }
                else if (allowedModelExtensions.Contains(fileExtension))
                {
                    var voxelName = Path.GetFileNameWithoutExtension(filename);
                    currentVoxel   = world.ModelCache.GetModel(voxelName);
                    currentSprites = null;
                }
                else if (allowedAudioExtensions.Contains(fileExtension))
                {
                    // Mute music so it doesn't interfere with the current asset.
                    MuteSounds();

                    currentAudioStream = Game.ModData.DefaultFileSystem.Open(prefix + filename);
                    foreach (var modDataSoundLoader in Game.ModData.SoundLoaders)
                    {
                        if (modDataSoundLoader.TryParseSound(currentAudioStream, out currentSoundFormat))
                        {
                            if (frameSlider != null)
                            {
                                frameSlider.MaximumValue = currentSoundFormat.LengthInSeconds * currentSoundFormat.SampleRate;
                                frameSlider.Ticks        = 0;
                            }

                            break;
                        }
                    }
                }
                else if (allowedVideoExtensions.Contains(fileExtension))
                {
                    // Mute music so it doesn't interfere with the current asset.
                    MuteSounds();

                    var video = VideoLoader.GetVideo(Game.ModData.DefaultFileSystem.Open(filename), true, Game.ModData.VideoLoaders);
                    if (video != null)
                    {
                        player = panel.Get <VideoPlayerWidget>("PLAYER");
                        player.Load(prefix + filename);
                        player.DrawOverlay = false;
                        isVideoLoaded      = true;

                        if (frameSlider != null)
                        {
                            frameSlider.MaximumValue = (float)player.Video.FrameCount - 1;
                            frameSlider.Ticks        = 0;
                        }
                    }
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception ex)
            {
                isLoadError = true;
                Log.AddChannel("assetbrowser", "assetbrowser.log");
                Log.Write("assetbrowser", "Error reading {0}:{3} {1}{3}{2}", filename, ex.Message, ex.StackTrace, Environment.NewLine);

                return(false);
            }

            return(true);
        }
        private IEnumerator DownloadVideo()
        {
            downloading = true;

            if (!updated)
            {
                yield return(new WaitUntil(() => updated));
            }

            VideoDownload download = videoQueue.Peek();
            VideoData     video    = download.video;

            if (video.downloadState == DownloadState.Cancelled || download.downloadAttempts > MaxRetries)
            {
                // skip
                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    // Start next download
                    DownloadVideo();
                }
                else
                {
                    // queue empty
                    downloading = false;
                    yield break;
                }
            }

            StopCoroutine(Countdown(download));

            video.downloadState = DownloadState.Downloading;
            downloadProgress?.Invoke(video);
            download.Update();

            string levelPath = VideoLoader.GetLevelPath(video.level);

            if (!Directory.Exists(levelPath))
            {
                Directory.CreateDirectory(levelPath);
            }

            string videoFileName = video.title;

            // Strip invalid characters
            foreach (var c in Path.GetInvalidFileNameChars())
            {
                videoFileName = videoFileName.Replace(c, '-');
            }
            videoFileName = videoFileName.Replace('\\', '-');
            videoFileName = videoFileName.Replace('/', '-');

            video.videoPath = videoFileName + ".mp4";

            // Download the video via youtube-dl
            ydl = new Process();

            ydl.StartInfo.FileName  = Environment.CurrentDirectory + "\\Youtube-dl\\youtube-dl.exe";
            ydl.StartInfo.Arguments =
                "https://www.youtube.com" + video.URL +
                " -f \"" + VideoQualitySetting.Format(quality) + "\"" + // Formats
                " --no-cache-dir" +                                     // Don't use temp storage
                " -o \"" + levelPath + $"\\{videoFileName}.%(ext)s\"" +
                " --no-playlist" +                                      // Don't download playlists, only the first video
                " --no-part";                                           // Don't store download in parts, write directly to file

            ydl.StartInfo.RedirectStandardOutput = true;
            ydl.StartInfo.RedirectStandardError  = true;
            ydl.StartInfo.UseShellExecute        = false;
            ydl.StartInfo.CreateNoWindow         = true;
            ydl.EnableRaisingEvents = true;

            ydl.Start();

            // Hook up our output to console
            ydl.BeginOutputReadLine();
            ydl.BeginErrorReadLine();

            ydl.OutputDataReceived += (sender, e) => {
                if (e.Data != null)
                {
                    Regex rx    = new Regex(@"(\d*).\d%+");
                    Match match = rx.Match(e.Data);
                    if (match.Success)
                    {
                        video.downloadProgress = float.Parse(match.Value.Substring(0, match.Value.Length - 1)) / 100;
                        downloadProgress?.Invoke(video);
                        download.Update();
                    }
                }
            };

            ydl.ErrorDataReceived += (sender, e) => {
                if (e.Data.Length < 3)
                {
                    return;
                }
                //to do: check these errors are problems - redownload or skip file when an error occurs
                //video.downloadState = DownloadState.Cancelled;
                downloadProgress?.Invoke(video);
                download.Update();
            };

            ydl.Exited += (sender, e) => {
                StopCoroutine(Countdown(download));

                if (video.downloadState == DownloadState.Cancelled)
                {
                    VideoLoader.Instance.DeleteVideo(video);
                }
                else
                {
                    video.downloadState = DownloadState.Downloaded;
                    VideoLoader.SaveVideoToDisk(video);
                    StartCoroutine(VerifyDownload(video));
                }

                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    // Start next download
                    DownloadVideo();
                }
                else
                {
                    // queue empty
                    downloading = false;
                }
                ydl.Dispose();
            };
        }
        private void DownloadVideo()
        {
            VideoData video = videoQueue.Peek();

            if (video.downloadState == DownloadState.Cancelled)
            {
                // skip
                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    // Start next download
                    DownloadVideo();
                }
                else
                {
                    // queue empty
                    downloading = false;
                    return;
                }
            }

            downloading         = true;
            video.downloadState = DownloadState.Downloading;
            downloadProgress?.Invoke(video);
            string levelPath = VideoLoader.GetLevelPath(video.level);

            if (!Directory.Exists(levelPath))
            {
                Directory.CreateDirectory(levelPath);
            }
            // Download the video via youtube-dl
            ydl = new Process();

            string videoFileName = video.title;

            // Strip invalid characters
            foreach (var c in Path.GetInvalidFileNameChars())
            {
                videoFileName = videoFileName.Replace(c, '-');
            }
            video.videoPath = videoFileName + ".mp4";

            ydl.StartInfo.FileName  = Environment.CurrentDirectory + "/Youtube-dl/youtube-dl.exe";
            ydl.StartInfo.Arguments =
                "https://www.youtube.com" + video.URL +
                " -f \"" + VideoQualitySetting.Format(quality) + "\"" + // Formats
                " --no-cache-dir" +                                     // Don't use temp storage
                " -o \"" + levelPath + $"\\{videoFileName}.%(ext)s\"" +
                " --no-playlist" +                                      // Don't download playlists, only the first video
                " --no-part";                                           // Don't store download in parts, write directly to file


            ydl.StartInfo.RedirectStandardOutput = true;
            ydl.StartInfo.RedirectStandardError  = true;
            ydl.StartInfo.UseShellExecute        = false;
            ydl.StartInfo.CreateNoWindow         = true;
            ydl.EnableRaisingEvents = true;

            ydl.Start();

            // Hook up our output to console
            ydl.BeginOutputReadLine();
            ydl.BeginErrorReadLine();

            ydl.OutputDataReceived += (sender, e) => {
                if (e.Data != null)
                {
                    //[download]  81.8% of 40.55MiB at  4.80MiB/s ETA 00:01
                    //[download] Resuming download at byte 48809440
                    //
                    Regex rx    = new Regex(@"(\d+).\d%+");
                    Match match = rx.Match(e.Data);
                    if (match.Success)
                    {
                        video.downloadProgress = float.Parse(match.Value.Substring(0, match.Value.Length - 2)) / 100;
                        downloadProgress?.Invoke(video);
                    }
                    Console.WriteLine(e.Data);
                }
            };

            ydl.ErrorDataReceived += (sender, e) => {
                Console.WriteLine(e.Data);
                //to do: check these errors problems - redownload or skip file when an error occurs
            };

            ydl.Exited += (sender, e) => {
                // to do: check that the file was indeed downloaded correctly

                if (video.downloadState == DownloadState.Cancelled)
                {
                    VideoLoader.Instance.DeleteVideo(video);
                }
                else
                {
                    video.downloadState = DownloadState.Downloaded;
                    VideoLoader.SaveVideoToDisk(video);
                    StartCoroutine(VerifyDownload(video));
                }

                videoQueue.Dequeue();

                if (videoQueue.Count > 0)
                {
                    // Start next download
                    DownloadVideo();
                }
                else
                {
                    // queue empty
                    downloading = false;
                }
            };
        }