Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Визуальная часть MusicBar (UPD. by Snegopadd....) | EvaWare v3

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
26 Янв 2025
Сообщения
12
Реакции
1
Выберите загрузчик игры
  1. Fabric
Я хз вроде Рокстар едишион (ХЗ) xD.
гпт


SS:
1770055772035.png
1770055801773.png

1770055845939.png

1770055752596.png



CODE:
MediaUtils:
Expand Collapse Copy
package sweetie.evaware.api.utils.media;

import by.bonenaut7.mediatransport4j.api.MediaSession;
import by.bonenaut7.mediatransport4j.api.MediaTransport;
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.texture.NativeImage;
import net.minecraft.client.texture.NativeImageBackedTexture;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class MediaUtils {
    private static boolean initialized = false;
    private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    private static volatile MediaInfo mediaInfo = null;
    private static final Map<String, AbstractTexture> textureCache = new ConcurrentHashMap<>();

    private static String lastMetadataKey = "";
    private static String currentTextureHash = "";

    private static final float[] waveHeights = new float[4];
    private static final float[] waveTargets = new float[4];
    private static long lastWaveUpdate = 0L;

    public enum Status {
        PLAYING, PAUSED
    }

    public static class MediaInfo {
        public final String title;
        public final String artist;
        public final String textureHash;
        public final Status status;
        public final float[] heights;

        public MediaInfo(String title, String artist, String textureHash, Status status, float[] heights) {
            this.title = title;
            this.artist = artist;
            this.textureHash = textureHash;
            this.status = status;
            this.heights = heights.clone();
        }

        public AbstractTexture getTexture() {
            return textureCache.get(textureHash);
        }
    }

    public static MediaInfo getCurrentMedia() {
        if (!initialized) {
            MediaTransport.init();
            initialized = true;

            scheduler.scheduleAtFixedRate(() -> {
                try {
                    List<MediaSession> sessions = MediaTransport.getMediaSessions();
                    if (sessions != null && !sessions.isEmpty()) {
                        MediaSession session = sessions.get(0);

                        String title = session.getTitle() != null ? session.getTitle() : "Unknown";
                        String artist = session.getArtist() != null ? session.getArtist() : "Artist";
                        String metadataKey = title + artist;

                        if (!metadataKey.equals(lastMetadataKey)) {
                            clearCache();

                            if (session.hasThumbnail()) {
                                ByteBuffer buffer = session.getThumbnail();
                                AbstractTexture texture = convertTexture(buffer);
                                if (texture != null) {
                                    currentTextureHash = String.valueOf(metadataKey.hashCode());
                                    textureCache.put(currentTextureHash, texture);
                                }
                            } else {
                                currentTextureHash = "";
                            }
                            lastMetadataKey = metadataKey;
                        }

                        boolean playing = session.isPlaying();
                        updateWaveLogic(playing);

                        mediaInfo = new MediaInfo(
                                title,
                                artist,
                                currentTextureHash,
                                playing ? Status.PLAYING : Status.PAUSED,
                                waveHeights
                        );
                    } else {
                        if (mediaInfo != null) {
                            clearCache();
                            mediaInfo = null;
                            lastMetadataKey = "";
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, 0, 50, TimeUnit.MILLISECONDS);
        }
        return mediaInfo;
    }

    private static void updateWaveLogic(boolean playing) {
        if (playing) {
            if (System.currentTimeMillis() - lastWaveUpdate > 90) {
                lastWaveUpdate = System.currentTimeMillis();
                waveTargets[0] = 4.0f + (float) (Math.random() * 6.0f);
                waveTargets[1] = 2.0f + (float) (Math.random() * 10.0f);
                waveTargets[2] = 5.0f + (float) (Math.random() * 4.0f);
                waveTargets[3] = 3.0f + (float) (Math.random() * 5.0f);
            }
        } else {
            for (int i = 0; i < 4; i++) waveTargets[i] = 0f;
        }

        for (int i = 0; i < 4; i++) {
            float smoothness = (i == 1) ? 0.1f : 0.25f;
            waveHeights[i] += (waveTargets[i] - waveHeights[i]) * smoothness;
        }
    }

    private static AbstractTexture convertTexture(ByteBuffer buffer) {
        try {
            ByteBuffer duplicate = buffer.asReadOnlyBuffer();
            duplicate.clear();
            byte[] bytes = new byte[duplicate.remaining()];
            duplicate.get(bytes);

            BufferedImage img = ImageIO.read(new ByteArrayInputStream(bytes));
            if (img == null) return null;

            NativeImage ni = new NativeImage(img.getWidth(), img.getHeight(), false);
            for (int y = 0; y < img.getHeight(); y++) {
                for (int x = 0; x < img.getWidth(); x++) {
                    ni.setColorArgb(x, y, img.getRGB(x, y));
                }
            }
            return new NativeImageBackedTexture(ni);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    private static void clearCache() {
        textureCache.values().forEach(AbstractTexture::close);
        textureCache.clear();
        currentTextureHash = "";
    }
}
MusicBarWidget:
Expand Collapse Copy
package sweetie.evaware.client.ui.widget.overlay;

import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.texture.AbstractTexture;
import net.minecraft.client.util.math.MatrixStack;
import sweetie.evaware.api.utils.media.MediaUtils;
import sweetie.evaware.api.utils.render.RenderUtil;
import sweetie.evaware.api.utils.render.fonts.Font;
import sweetie.evaware.api.utils.render.fonts.Fonts;
import sweetie.evaware.api.utils.color.UIColors;
import sweetie.evaware.client.ui.widget.Widget;

import java.awt.*;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class MusicBarWidget extends Widget {
    private static final char WIFI_GLYPH = 'N';
    private Font iconFont;
    private float scrollOffset = 0f;
    private long lastUpdate = System.currentTimeMillis();

    public MusicBarWidget() {
        super(0f, 5f);
    }

    @Override
    public String getName() {
        return "MusicBar";
    }

    @Override
    public void render(MatrixStack matrixStack) {
        if (!isEnabled()) return;

        MediaUtils.MediaInfo mediaInfo = MediaUtils.getCurrentMedia();
        if (mediaInfo == null) return;

        String title = (mediaInfo.title == null || mediaInfo.title.isEmpty()) ? "Unknown" : mediaInfo.title;
        String artist = (mediaInfo.artist == null || mediaInfo.artist.isEmpty()) ? "Artist" : mediaInfo.artist;
        String label = title + " - " + artist;

        Font font = Fonts.SF_REGULAR;
        Font boldFont = Fonts.SF_BOLD != null ? Fonts.SF_BOLD : font;
        Color textColor = UIColors.textColor(255);
        Color accentColor = UIColors.primary(255);

//fonts
        float fontSize = scaled(8.0f);
        float timeFontSize = scaled(9.0f);
        float artSize = scaled(14.0f);
        float panelHeight = scaled(18.0f);
        float maxTextWidth = scaled(100.0f);

        String timeStr = LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm"));
        float timeWidth = boldFont.getWidth(timeStr, timeFontSize);
        float timeGap = scaled(6.0f);

        float waveBlockWidth = scaled(12.5f);
        boolean hasArt = mediaInfo.getTexture() != null;
        float leftOffset = scaled(4.0f);
        float gapAfterArt = hasArt ? scaled(6.0f) : 0f;
        float rightOffset = scaled(6.0f);
        float gapAfterText = scaled(8.0f);

        float textWidth = font.getWidth(label, fontSize);
        float displayTabWidth = Math.min(textWidth, maxTextWidth);

        float panelWidth = leftOffset + (hasArt ? artSize + gapAfterArt : 0) + displayTabWidth + gapAfterText + waveBlockWidth + rightOffset;

//wifi
        Font wifiFont = getIconFont();
        float wifiSize = scaled(10.0f);
        float wifiWidth = (wifiFont != null) ? wifiFont.getWidth(String.valueOf(WIFI_GLYPH), wifiSize) : 0.0f;
        float wifiGap = scaled(8.0f);

//position
        float totalWidth = timeWidth + timeGap + panelWidth + (wifiWidth > 0 ? wifiGap + wifiWidth : 0);
        float groupX = (mc.getWindow().getScaledWidth() - totalWidth) / 2.0f;
        float y = getDraggable().getY();
        float centerY = y + (panelHeight / 2.0f);
        float barX = groupX + timeWidth + timeGap;

// time
        boldFont.drawText(matrixStack, timeStr, groupX, centerY - (timeFontSize / 2.0f), timeFontSize, textColor);

        drawBackground(matrixStack, barX, y, panelWidth, panelHeight, scaled(9.0f));

 // content
        float currentX = barX + leftOffset;

        if (hasArt) {
            drawTexture(matrixStack, mediaInfo.getTexture(), currentX, centerY - (artSize / 2.0f), artSize, artSize, scaled(5.0f));
            currentX += artSize + gapAfterArt;
        }

        renderMarqueeText(matrixStack, font, label, currentX, centerY - (fontSize / 2.0f) + scaled(0.5f), displayTabWidth, fontSize, textColor);
        currentX += displayTabWidth + gapAfterText;

// pause
        renderVisualizer(matrixStack, mediaInfo, currentX, centerY, waveBlockWidth, accentColor, textColor);

// ic (wifiI)
        if (wifiFont != null) {
            float wifiX = barX + panelWidth + wifiGap;
            wifiFont.drawText(matrixStack, String.valueOf(WIFI_GLYPH), wifiX, centerY - (wifiSize / 2.0f), wifiSize, textColor);
        }

// Обновляем данные драггабла
        getDraggable().setWidth(totalWidth);
        getDraggable().setHeight(panelHeight);
        getDraggable().setX(groupX);
    }

    private void renderMarqueeText(MatrixStack ms, Font font, String text, float x, float y, float maxWidth, float size, Color color) {
        float textWidth = font.getWidth(text, size);

        if (textWidth <= maxWidth) {
            font.drawText(ms, text, x, y, size, color);
            return;
        }

        long now = System.currentTimeMillis();
        float delta = (now - lastUpdate) / 1000f;
        lastUpdate = now;

        float speed = 20f;
        float gap = 30f;
        scrollOffset += delta * speed;
        if (scrollOffset > textWidth + gap) scrollOffset = 0;

        double scale = mc.getWindow().getScaleFactor();
        int scissorX = (int) (x * scale);
        int scissorY = (int) (mc.getWindow().getHeight() - (y + size + scaled(2)) * scale);
        int scissorW = (int) (maxWidth * scale);
        int scissorH = (int) ((size + scaled(5)) * scale);

        RenderSystem.enableScissor(scissorX, scissorY, scissorW, scissorH);

        font.drawText(ms, text, x - scrollOffset, y, size, color);
        font.drawText(ms, text, x - scrollOffset + textWidth + gap, y, size, color);

        RenderSystem.disableScissor();
    }

    private void renderVisualizer(MatrixStack ms, MediaUtils.MediaInfo info, float x, float centerY, float width, Color accent, Color text) {
        if (info.status == MediaUtils.Status.PLAYING) {
            float barW = scaled(2.5f), barG = scaled(1.5f);
            float barBaseY = centerY + scaled(4.0f);
            for (int i = 0; i < 4; i++) {
                float h = Math.min(scaled(info.heights[i]), scaled(10.0f));
                RenderUtil.RECT.draw(ms, x + i * (barW + barG), barBaseY - h, barW, h, scaled(1.0f), accent);
            }
        } else {
            float pW = scaled(2.0f), pH = scaled(7.0f), pG = scaled(2.0f);
            float pX = x + (width - (pW * 2 + pG)) / 2.0f;
            RenderUtil.RECT.draw(ms, pX, centerY - (pH / 2.0f), pW, pH, scaled(0.5f), text);
            RenderUtil.RECT.draw(ms, pX + pW + pG, centerY - (pH / 2.0f), pW, pH, scaled(0.5f), text);
        }
    }

    private void drawBackground(MatrixStack ms, float x, float y, float w, float h, float r) {
        RenderUtil.BLUR_RECT.draw(ms, x, y, w, h, r, UIColors.widgetBlur(255));
        RenderUtil.RECT.draw(ms, x, y, w, h, r, UIColors.backgroundBlur(255));
    }

    private void drawTexture(MatrixStack ms, AbstractTexture texture, float x, float y, float w, float h, float radius) {
        if (texture != null) {
            RenderUtil.TEXTURE_RECT.draw(ms, x, y, w, h, radius, Color.WHITE, 0f, 0f, 1f, 1f, texture.getGlId());
        }
    }

    private Font getIconFont() {
        if (iconFont != null) return iconFont;
        try {
            iconFont = Font.builder().find("other/icons").load();
        } catch (Exception ignored) {}
        return iconFont;
    }
}


Решил чуть чуть обновить мьюзик бар от снегопада. Если вам не нравится можете настроить под себя | поставил коментарии для вашего решения.

Что я обновил?
1. Добавил прикольный скроллинг если название песни более 25 символов.
2. Пофиксил шрифты (от снегопада почти 0 визуала). | Пофикшены вылеты и все дела.
3. А еще добнул для цвета соответствующие темам выбранные в клиенте.

Как добнуть библиотеку? 1 - Заходите в гитхаб и скачиваете mediatransport4j-1.0.3 и все и дальше регаете его в build.gradle (ну или же по другому)
и обязательные аддоны
Код:
Expand Collapse Copy
implementation 'net.java.dev.jna:jna:5.13.0'
implementation 'net.java.dev.jna:jna-platform:5.13.0'
 
Назад
Сверху Снизу