mirror of
https://github.com/ppy/osu.git
synced 2025-02-21 20:12:57 +08:00
Merge pull request #31307 from bdach/id3-tags
Populate metadata from ID3 tags when changing beatmap audio track in editor
This commit is contained in:
commit
ac348b8780
@ -28,33 +28,31 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
public override LocalisableString Title => EditorSetupStrings.MetadataHeader;
|
public override LocalisableString Title => EditorSetupStrings.MetadataHeader;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(SetupScreen? setupScreen)
|
||||||
{
|
{
|
||||||
var metadata = Beatmap.Metadata;
|
|
||||||
|
|
||||||
Children = new[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
ArtistTextBox = createTextBox<FormTextBox>(EditorSetupStrings.Artist,
|
ArtistTextBox = createTextBox<FormTextBox>(EditorSetupStrings.Artist),
|
||||||
!string.IsNullOrEmpty(metadata.ArtistUnicode) ? metadata.ArtistUnicode : metadata.Artist),
|
RomanisedArtistTextBox = createTextBox<FormRomanisedTextBox>(EditorSetupStrings.RomanisedArtist),
|
||||||
RomanisedArtistTextBox = createTextBox<FormRomanisedTextBox>(EditorSetupStrings.RomanisedArtist,
|
TitleTextBox = createTextBox<FormTextBox>(EditorSetupStrings.Title),
|
||||||
!string.IsNullOrEmpty(metadata.Artist) ? metadata.Artist : MetadataUtils.StripNonRomanisedCharacters(metadata.ArtistUnicode)),
|
RomanisedTitleTextBox = createTextBox<FormRomanisedTextBox>(EditorSetupStrings.RomanisedTitle),
|
||||||
TitleTextBox = createTextBox<FormTextBox>(EditorSetupStrings.Title,
|
creatorTextBox = createTextBox<FormTextBox>(EditorSetupStrings.Creator),
|
||||||
!string.IsNullOrEmpty(metadata.TitleUnicode) ? metadata.TitleUnicode : metadata.Title),
|
difficultyTextBox = createTextBox<FormTextBox>(EditorSetupStrings.DifficultyName),
|
||||||
RomanisedTitleTextBox = createTextBox<FormRomanisedTextBox>(EditorSetupStrings.RomanisedTitle,
|
sourceTextBox = createTextBox<FormTextBox>(BeatmapsetsStrings.ShowInfoSource),
|
||||||
!string.IsNullOrEmpty(metadata.Title) ? metadata.Title : MetadataUtils.StripNonRomanisedCharacters(metadata.ArtistUnicode)),
|
tagsTextBox = createTextBox<FormTextBox>(BeatmapsetsStrings.ShowInfoTags)
|
||||||
creatorTextBox = createTextBox<FormTextBox>(EditorSetupStrings.Creator, metadata.Author.Username),
|
|
||||||
difficultyTextBox = createTextBox<FormTextBox>(EditorSetupStrings.DifficultyName, Beatmap.BeatmapInfo.DifficultyName),
|
|
||||||
sourceTextBox = createTextBox<FormTextBox>(BeatmapsetsStrings.ShowInfoSource, metadata.Source),
|
|
||||||
tagsTextBox = createTextBox<FormTextBox>(BeatmapsetsStrings.ShowInfoTags, metadata.Tags)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (setupScreen != null)
|
||||||
|
setupScreen.MetadataChanged += reloadMetadata;
|
||||||
|
|
||||||
|
reloadMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
private TTextBox createTextBox<TTextBox>(LocalisableString label, string initialValue)
|
private TTextBox createTextBox<TTextBox>(LocalisableString label)
|
||||||
where TTextBox : FormTextBox, new()
|
where TTextBox : FormTextBox, new()
|
||||||
=> new TTextBox
|
=> new TTextBox
|
||||||
{
|
{
|
||||||
Caption = label,
|
Caption = label,
|
||||||
Current = { Value = initialValue },
|
|
||||||
TabbableContentContainer = this
|
TabbableContentContainer = this
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -94,10 +92,29 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
|
|
||||||
// for now, update on commit rather than making BeatmapMetadata bindables.
|
// for now, update on commit rather than making BeatmapMetadata bindables.
|
||||||
// after switching database engines we can reconsider if switching to bindables is a good direction.
|
// after switching database engines we can reconsider if switching to bindables is a good direction.
|
||||||
updateMetadata();
|
setMetadata();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMetadata()
|
private void reloadMetadata()
|
||||||
|
{
|
||||||
|
var metadata = Beatmap.Metadata;
|
||||||
|
|
||||||
|
RomanisedArtistTextBox.ReadOnly = false;
|
||||||
|
RomanisedTitleTextBox.ReadOnly = false;
|
||||||
|
|
||||||
|
ArtistTextBox.Current.Value = !string.IsNullOrEmpty(metadata.ArtistUnicode) ? metadata.ArtistUnicode : metadata.Artist;
|
||||||
|
RomanisedArtistTextBox.Current.Value = !string.IsNullOrEmpty(metadata.Artist) ? metadata.Artist : MetadataUtils.StripNonRomanisedCharacters(metadata.ArtistUnicode);
|
||||||
|
TitleTextBox.Current.Value = !string.IsNullOrEmpty(metadata.TitleUnicode) ? metadata.TitleUnicode : metadata.Title;
|
||||||
|
RomanisedTitleTextBox.Current.Value = !string.IsNullOrEmpty(metadata.Title) ? metadata.Title : MetadataUtils.StripNonRomanisedCharacters(metadata.ArtistUnicode);
|
||||||
|
creatorTextBox.Current.Value = metadata.Author.Username;
|
||||||
|
difficultyTextBox.Current.Value = Beatmap.BeatmapInfo.DifficultyName;
|
||||||
|
sourceTextBox.Current.Value = metadata.Source;
|
||||||
|
tagsTextBox.Current.Value = metadata.Tags;
|
||||||
|
|
||||||
|
updateReadOnlyState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setMetadata()
|
||||||
{
|
{
|
||||||
Beatmap.Metadata.ArtistUnicode = ArtistTextBox.Current.Value;
|
Beatmap.Metadata.ArtistUnicode = ArtistTextBox.Current.Value;
|
||||||
Beatmap.Metadata.Artist = RomanisedArtistTextBox.Current.Value;
|
Beatmap.Metadata.Artist = RomanisedArtistTextBox.Current.Value;
|
||||||
|
@ -35,6 +35,9 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private Editor? editor { get; set; }
|
private Editor? editor { get; set; }
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private SetupScreen setupScreen { get; set; } = null!;
|
||||||
|
|
||||||
private SetupScreenHeaderBackground headerBackground = null!;
|
private SetupScreenHeaderBackground headerBackground = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
@ -93,15 +96,37 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
if (!source.Exists)
|
if (!source.Exists)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
var tagSource = TagLib.File.Create(source.FullName);
|
||||||
|
|
||||||
changeResource(source, applyToAllDifficulties, @"audio",
|
changeResource(source, applyToAllDifficulties, @"audio",
|
||||||
metadata => metadata.AudioFile,
|
metadata => metadata.AudioFile,
|
||||||
(metadata, name) => metadata.AudioFile = name);
|
(metadata, name) =>
|
||||||
|
{
|
||||||
|
metadata.AudioFile = name;
|
||||||
|
|
||||||
|
string artist = tagSource.Tag.JoinedAlbumArtists;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(artist))
|
||||||
|
{
|
||||||
|
metadata.ArtistUnicode = artist;
|
||||||
|
metadata.Artist = MetadataUtils.StripNonRomanisedCharacters(metadata.ArtistUnicode);
|
||||||
|
}
|
||||||
|
|
||||||
|
string title = tagSource.Tag.Title;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(title))
|
||||||
|
{
|
||||||
|
metadata.TitleUnicode = title;
|
||||||
|
metadata.Title = MetadataUtils.StripNonRomanisedCharacters(metadata.TitleUnicode);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
music.ReloadCurrentTrack();
|
music.ReloadCurrentTrack();
|
||||||
|
setupScreen.MetadataChanged?.Invoke();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeResource(FileInfo source, bool applyToAllDifficulties, string baseFilename, Func<BeatmapMetadata, string> readFilename, Action<BeatmapMetadata, string> writeFilename)
|
private void changeResource(FileInfo source, bool applyToAllDifficulties, string baseFilename, Func<BeatmapMetadata, string> readFilename, Action<BeatmapMetadata, string> writeMetadata)
|
||||||
{
|
{
|
||||||
var set = working.Value.BeatmapSetInfo;
|
var set = working.Value.BeatmapSetInfo;
|
||||||
var beatmap = working.Value.BeatmapInfo;
|
var beatmap = working.Value.BeatmapInfo;
|
||||||
@ -148,10 +173,7 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
{
|
{
|
||||||
foreach (var b in otherBeatmaps)
|
foreach (var b in otherBeatmaps)
|
||||||
{
|
{
|
||||||
// This operation is quite expensive, so only perform it if required.
|
writeMetadata(b.Metadata, newFilename);
|
||||||
if (readFilename(b.Metadata) == newFilename) continue;
|
|
||||||
|
|
||||||
writeFilename(b.Metadata, newFilename);
|
|
||||||
|
|
||||||
// save the difficulty to re-encode the .osu file, updating any reference of the old filename.
|
// save the difficulty to re-encode the .osu file, updating any reference of the old filename.
|
||||||
//
|
//
|
||||||
@ -162,7 +184,7 @@ namespace osu.Game.Screens.Edit.Setup
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFilename(beatmap.Metadata, newFilename);
|
writeMetadata(beatmap.Metadata, newFilename);
|
||||||
|
|
||||||
// editor change handler cannot be aware of any file changes or other difficulties having their metadata modified.
|
// editor change handler cannot be aware of any file changes or other difficulties having their metadata modified.
|
||||||
// for simplicity's sake, trigger a save when changing any resource to ensure the change is correctly saved.
|
// for simplicity's sake, trigger a save when changing any resource to ensure the change is correctly saved.
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -13,12 +14,15 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Screens.Edit.Setup
|
namespace osu.Game.Screens.Edit.Setup
|
||||||
{
|
{
|
||||||
|
[Cached]
|
||||||
public partial class SetupScreen : EditorScreen
|
public partial class SetupScreen : EditorScreen
|
||||||
{
|
{
|
||||||
public const float COLUMN_WIDTH = 450;
|
public const float COLUMN_WIDTH = 450;
|
||||||
public const float SPACING = 28;
|
public const float SPACING = 28;
|
||||||
public const float MAX_WIDTH = 2 * COLUMN_WIDTH + SPACING;
|
public const float MAX_WIDTH = 2 * COLUMN_WIDTH + SPACING;
|
||||||
|
|
||||||
|
public Action? MetadataChanged { get; set; }
|
||||||
|
|
||||||
public SetupScreen()
|
public SetupScreen()
|
||||||
: base(EditorScreenMode.SongSetup)
|
: base(EditorScreenMode.SongSetup)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user