implement id3v2.3 tagging
This commit is contained in:
@@ -97,6 +97,8 @@ dependencies {
|
||||
implementation 'net.sourceforge.streamsupport:streamsupport-minifuture:1.7.4'
|
||||
implementation 'com.google.guava:guava:32.0.0-android'
|
||||
|
||||
implementation 'com.mpatric:mp3agic:0.9.1'
|
||||
|
||||
implementation fileTree(dir: 'libs', include: ['*.aar'])
|
||||
compileOnly fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
@@ -355,4 +355,12 @@ public class Preferences {
|
||||
if (MediaImageEncoder.needToSkipCompression()) return 100;
|
||||
return origquality;
|
||||
}
|
||||
|
||||
public static String metadataSeparator() {
|
||||
return getPreferences().getString("metadata_separator", "; ");
|
||||
}
|
||||
|
||||
public static void setMetadataSeparator(String separator) {
|
||||
getPreferences().edit().putString("metadata_separator", separator).apply();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
package ru.vtosters.lite.music.downloader;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.mpatric.mp3agic.ID3v23Tag;
|
||||
import com.mpatric.mp3agic.InvalidDataException;
|
||||
import com.mpatric.mp3agic.Mp3File;
|
||||
import com.mpatric.mp3agic.NotSupportedException;
|
||||
import com.mpatric.mp3agic.UnsupportedTagException;
|
||||
import com.vk.dto.music.MusicTrack;
|
||||
import com.vk.dto.music.Artist;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
|
||||
public class ID3Tagger {
|
||||
public static void tag(File file, MusicTrack track) {
|
||||
try {
|
||||
// https://github.com/mpatric/mp3agic/issues/69#issuecomment-57897874
|
||||
var oldFile = new File(file.getAbsolutePath().replace(".mp3", "_old.mp3"));
|
||||
if (!file.renameTo(oldFile)) {
|
||||
Log.e("ID3Tagger", "Failed to rename file");
|
||||
return;
|
||||
}
|
||||
|
||||
var mp3File = new Mp3File(oldFile);
|
||||
if (mp3File.hasId3v2Tag()) {
|
||||
var id3v2Tag = new ID3v23Tag();
|
||||
|
||||
if (track.L == null || track.I == null) {
|
||||
id3v2Tag.setArtist(track.C);
|
||||
} else {
|
||||
var artists = track.L.stream().map(Artist::w1).collect(Collectors.joining(Preferences.metadataSeparator()));
|
||||
id3v2Tag.setArtist(artists);
|
||||
id3v2Tag.setAlbum(track.I.getTitle());
|
||||
}
|
||||
|
||||
id3v2Tag.setTitle(M3UDownloader.getTitle(track));
|
||||
|
||||
mp3File.setId3v2Tag(id3v2Tag);
|
||||
mp3File.save(file.getAbsolutePath());
|
||||
|
||||
if (!oldFile.delete()) {
|
||||
Log.e("ID3Tagger", "Failed to delete file");
|
||||
}
|
||||
}
|
||||
} catch (IOException | UnsupportedTagException | InvalidDataException |
|
||||
NotSupportedException e) {
|
||||
Log.e("ID3Tagger", "Failed to tag file", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,9 +6,13 @@ import android.util.Log;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.e;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.f;
|
||||
import com.google.android.exoplayer2.source.hls.playlist.f.a;
|
||||
import com.mpatric.mp3agic.InvalidDataException;
|
||||
import com.mpatric.mp3agic.Mp3File;
|
||||
import com.mpatric.mp3agic.UnsupportedTagException;
|
||||
import com.vk.dto.music.MusicTrack;
|
||||
import java8.util.concurrent.CompletableFuture;
|
||||
import java8.util.concurrent.CompletionException;
|
||||
import ru.vtosters.hooks.other.Preferences;
|
||||
import ru.vtosters.lite.music.cache.MusicCacheImpl;
|
||||
import ru.vtosters.lite.music.converter.ts.MpegDemuxer;
|
||||
import ru.vtosters.lite.music.converter.ts.TSMerger;
|
||||
@@ -72,6 +76,11 @@ public class M3UDownloader
|
||||
}
|
||||
})
|
||||
.thenRun(() -> callback.onProgress(10 + Math.round(80.0f * progress.addAndGet(1) / segments.size())))
|
||||
.thenRun(() -> {
|
||||
if (Preferences.getBoolValue("setMetaData", true)) {
|
||||
ID3Tagger.tag(resultMp3, track);
|
||||
}
|
||||
})
|
||||
.thenRun(() -> {
|
||||
if (cache) {
|
||||
MusicCacheImpl.addTrack(track);
|
||||
|
||||
@@ -162,6 +162,41 @@ public class MediaFragment extends TrackedMaterialPreferenceToolbarFragment {
|
||||
});
|
||||
|
||||
findPreference("maxquality").setEnabled(Preferences.isEnableExternalOpening());
|
||||
|
||||
findPreference("metadataSeparator").setOnPreferenceClickListener(preference -> {
|
||||
LinearLayout linearLayout = new LinearLayout(requireContext());
|
||||
linearLayout.setOrientation(LinearLayout.VERTICAL);
|
||||
|
||||
|
||||
EditText separator = new EditText(requireContext());
|
||||
separator.setHint("По-умолчанию: ; с пробелом");
|
||||
separator.setTextColor(ThemesUtils.getTextAttr());
|
||||
separator.setHintTextColor(ThemesUtils.getSTextAttr());
|
||||
separator.setBackgroundTintList(ThemesUtils.getAccenedColorStateList());
|
||||
separator.setText(Preferences.metadataSeparator());
|
||||
linearLayout.addView(separator);
|
||||
separator.getLayoutParams().width = ViewGroup.LayoutParams.MATCH_PARENT;
|
||||
ViewGroup.MarginLayoutParams margin = ((ViewGroup.MarginLayoutParams) separator.getLayoutParams());
|
||||
margin.setMargins(AndroidUtils.dp2px(20f), 0, AndroidUtils.dp2px(20f), 0);
|
||||
separator.setLayoutParams(margin);
|
||||
|
||||
|
||||
var t = new VkAlertDialog.Builder(requireContext())
|
||||
.setTitle("Разделитель")
|
||||
.setView(linearLayout)
|
||||
.setPositiveButton("Сохранить", (dialog, which) -> {
|
||||
if (separator.getText().toString().isEmpty()) {
|
||||
AndroidUtils.sendToast("Разделитель не может быть пустым");
|
||||
return;
|
||||
}
|
||||
Preferences.setMetadataSeparator(separator.getText().toString());
|
||||
})
|
||||
.setNegativeButton("Отмена", (dialog, which) -> dialog.cancel())
|
||||
.show();
|
||||
|
||||
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
private void lastfmAuth(Context ctx) {
|
||||
|
||||
@@ -55,6 +55,9 @@
|
||||
android:key="setMetaData"
|
||||
android:summary="Сохранять id3v2 теги для песен для MP3"
|
||||
android:title="Сохранять метадату песен"/>
|
||||
<Preference
|
||||
android:key="metadataSeparator"
|
||||
android:title="Разделитель для id3v2 тегов"/>
|
||||
<Preference
|
||||
android:key="audio_download"
|
||||
android:title="@string/audio_download_title"/>
|
||||
|
||||
Reference in New Issue
Block a user