diff --git a/HOWTO.md b/HOWTO.md index f04a487..ab63a96 100644 --- a/HOWTO.md +++ b/HOWTO.md @@ -4,19 +4,35 @@ This is a guide to populating the `data` working folder found in this applicatio **This project will only repack audio on Reverse 3.07 properly.** ## Table of Contents (sorted by descending time consumption) -1. [Song Audio](#song-audio-datamer_bgm) -2. [Jackets](#jackets-datajackets) -3. [Metadata](#metadata-datamusicparametertable) -4. [Charts](#charts-datamusicdata) +1. [Videos](#videos-datamovies) +2. [Song Audio](#song-audio-datamer_bgm) +3. [Jackets](#jackets-datajackets) +4. [Metadata](#metadata-datamusicparametertable) +5. [Charts](#charts-datamusicdata) + +## Videos (`data/movies`) +*~4.1 GB* + +If you want to export music videos, the process for doing so involves a **lot** of waiting; it's automated but took me ~1 hour to finish and used up all of my CPU bandwidth during that time, though I could do some steps while this ran. + +Videos exported using this process may not play properly as mentioned in [this issue](https://github.com/muskit/WacK-Repackager/issues/2). + +You will need [FFmpeg](https://www.ffmpeg.org/download.html) installed and on PATH. + +1. Set the paths in `convert-videos.bat/sh` as needed: + - `video_path` to `app/WindowsNoEditor/Mercury/Content/Movie` + - `export_path` to `data/movies` +2. Run `convert-videos.bat/sh` to convert all .usm videos to .mp4 in your data folder. + - This script will take a **very** long time to finish. ## Song Audio (`data/MER_BGM`) -*~18.8 GB for WAVs* +*~18.8 GB WAVs* Due to the audio indexing data in this project only done for **Reverse 3.07**, this process will only work for files of that version. You will need the latest version of [Audio Cue Editor (ACE)](https://github.com/LazyBone152/ACE). -For each of the files below located in `/app/WindowsNoEditor/Mercury/Content/Sound/Bgm`... +For each of the files below located in `app/WindowsNoEditor/Mercury/Content/Sound/Bgm`... - MER_BGM.awb - MER_BGM_V3_01.awb @@ -50,7 +66,7 @@ For each of the files below located in `/app/WindowsNoEditor/Mercury/Conten For this, you will need [UE Viewer](https://www.gildor.org/en/projects/umodel). 1. Run `umodel_64.exe` and configure its Startup Options. - - Set "Path to game files" to `/app/WindowsNoEditor/Mercury/Content/UI/Textures/JACKET`. + - Set "Path to game files" to `app/WindowsNoEditor/Mercury/Content/UI/Textures/JACKET`. - Enable "Override game detection" and set it to "Unreal engine 4.19". - Click OK. 2. In the left panel, right click on "All packages", then click on "Export folder content". @@ -60,8 +76,8 @@ For this, you will need [UE Viewer](https://www.gildor.org/en/projects/umodel). ## Metadata (`data/MusicParameterTable.*`) *<1 MB* -In `/app/WindowsNoEditor/Mercury/Content/Table/`, simply copy `MusicParameterTable.uasset` and `MusicParameterTable.uexp` into `data`. +In `app/WindowsNoEditor/Mercury/Content/Table/`, simply copy `MusicParameterTable.uasset` and `MusicParameterTable.uexp` into `data`. ## Charts (`data/MusicData`) *~59.5 MB* -Simply copy the `MusicData` folder at `/app/WindowsNoEditor/Mercury/Content/` into `data`. +Simply copy the `MusicData` folder at `app/WindowsNoEditor/Mercury/Content/` into `data`. diff --git a/convert-videos.bat b/convert-videos.bat new file mode 100644 index 0000000..6aa8f38 --- /dev/null +++ b/convert-videos.bat @@ -0,0 +1,7 @@ +@echo off + +:: Set paths here first before running!!! +set video_path="\app\WindowsNoEditor\Mercury\Content\Movie" +set export_path=".\data\movies" + +for %%i in (%video_path%\*.usm) do ffmpeg -n -f mpegvideo -i "%%i" "%export_path%\%%~ni.mp4" \ No newline at end of file diff --git a/convert-videos.sh b/convert-videos.sh new file mode 100755 index 0000000..7dcbf32 --- /dev/null +++ b/convert-videos.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +# Set paths here first before running!!! +video_path="App/WindowsNoEditor/Mercury/Content/Movie/" +output_path="./data/movies/" + +for file in "$video_path"/*.usm; do + output_file="$output_path/$(basename "$file" .usm).mp4" + echo $file + echo $output_file + ffmpeg -n -f mpegvideo -i "$file" "$output_file" +done \ No newline at end of file diff --git a/src/Data/Song/Consts.cs b/src/Data/Song/Consts.cs index 16910b4..7ef3ee8 100644 --- a/src/Data/Song/Consts.cs +++ b/src/Data/Song/Consts.cs @@ -66,4 +66,12 @@ public static class Consts {Difficulty.Expert, "NotesDesignerExpert"}, {Difficulty.Inferno, "NotesDesignerInferno"}, }; + + public static readonly IReadOnlyDictionary DIFF_MOVIE_KEY = new Dictionary() + { + {Difficulty.Normal, "MovieAssetName"}, + {Difficulty.Hard, "MovieAssetNameHard"}, + {Difficulty.Expert, "MovieAssetNameExpert"}, + {Difficulty.Inferno, "MovieAssetNameInferno"}, + }; } \ No newline at end of file diff --git a/src/ExportOperation/Exporter.cs b/src/ExportOperation/Exporter.cs index c965bbc..1339b4f 100644 --- a/src/ExportOperation/Exporter.cs +++ b/src/ExportOperation/Exporter.cs @@ -2,8 +2,10 @@ using System; using System.Collections.Generic; using System.Diagnostics.Contracts; using System.IO; +using Avalonia.Data.Converters; using MercuryConverter.Data; using MercuryConverter.UI.Views; +using MercuryConverter.Utility; using SaturnData.Notation.Serialization; namespace MercuryConverter.ExportOperation; @@ -43,14 +45,16 @@ public class Exporter Console.WriteLine($"Exporting {song.Id} to {exportSongPath}"); var entryCharts = song.GetEntryCharts(); - HashSet processedAudio = new(); + HashSet finishedAudio = new(); + HashSet finishedMovies = new(); + string prevMovie = "-"; foreach (var ec in entryCharts) { /// AUDIO /// var audioKey = ec.Item1.AudioPath; var audioExportFileName = $"{audioKey}.{options.AudioFormat.ToString().ToLower()}"; - if (!processedAudio.Contains(audioKey) && Database.AudioPaths.ContainsKey(audioKey)) + if (!finishedAudio.Contains(audioKey) && Database.AudioPaths.ContainsKey(audioKey)) { var audioSourcePath = Database.AudioPaths[audioKey]; @@ -65,10 +69,40 @@ public class Exporter File.Copy(audioSourcePath, Path.Combine(exportSongPath, audioExportFileName), true); break; } - processedAudio.Add(audioKey); + finishedAudio.Add(audioKey); } ec.Item1.AudioPath = audioExportFileName; + /// VIDEO /// + // mv_... = set video + // null = use previously set video + // - = disable video + if (!options.ExcludeVideo) + { + var movieProp = song.assetData[Consts.DIFF_MOVIE_KEY[ec.Item1.Difficulty]]; + + string movie; + if (movieProp.RawValue == null) + movie = prevMovie; + else + movie = movieProp.ToString()!; + + if (movie != "-") + { + var vidFileName = $"{movie}.mp4"; + if (!finishedMovies.Contains(movie)) + { + var vidPath = Path.Combine(Settings.I!.DataPath, "movies", vidFileName); + // TODO: check file's existence to avoid program crash + File.Copy(vidPath, Path.Combine(exportSongPath, vidFileName), true); + + finishedMovies.Add(movie); + } + ec.Item1.VideoPath = vidFileName; + } + prevMovie = movie; + } + /// CHART /// var chartExt = options.ChartFormat == FormatVersion.SatV1 || @@ -81,8 +115,7 @@ public class Exporter ec.Item1, ec.Item2, new NotationWriteArgs { FormatVersion = options.ChartFormat } ); - - // restore audio key in db AFTER exporting metadata / chart + // restore audio key in db AFTER exporting metadata ec.Item1.AudioPath = audioKey; } diff --git a/src/UI/Views/Export/Export.axaml b/src/UI/Views/Export/Export.axaml index fbc243f..06509d4 100644 --- a/src/UI/Views/Export/Export.axaml +++ b/src/UI/Views/Export/Export.axaml @@ -40,7 +40,7 @@ - +