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

Гайд Как сделать плашку с музыкой и кнопками в худе MCP 1.16.5

Начинающий
Начинающий
Статус
Оффлайн
Регистрация
9 Июн 2024
Сообщения
183
Реакции
1
Гайд поможет реализовать показ текущий воспроизводимый трек в худе клиента. Это может включать название песни, исполнителя, обложку альбома, прогресс воспроизведения и элементы управления, такие как пауза, воспроизведение и переключение треков. Для реализации используется библиотека, позволяющая получать информацию о системных медиа сессиях.​

Библиотека
Для получения информации о треках используется библиотека
Пожалуйста, авторизуйтесь для просмотра ссылки.
. Она предоставляет список активных медиасессий и позволяет управлять воспроизведением: пауза, продолжение, переключение треков. (для корректной работы ещё потребуется либка
Пожалуйста, авторизуйтесь для просмотра ссылки.
)

Создание модуля
Создаём модуль, который будет хранить текущий трек, медиасессию и текстуру обложки. Также понадобится отдельный поток для асинхронного обновления, чтобы не блокировать игровой поток.

поля и поток:
Expand Collapse Copy
private volatile MediaInfo currentTrack;
private volatile IMediaSession currentSession;
private long lastMediaUpdate;

private final ExecutorService mediaExecutor =
        Executors.newSingleThreadExecutor(r -> {
            Thread t = new Thread(r, "media-thread");
            t.setDaemon(true);
            return t;
        });


Обновление информации о треке
Информацию о музыке удобно обновлять в евенттике. Делать это каждый тик не нужно - достаточно раз в 1-2 секунды.

обновление:
Expand Collapse Copy
@EventHandler
public void onTick(TickEvent e) {
    long now = System.currentTimeMillis();
    if (now - lastMediaUpdate < 1500) return;
    lastMediaUpdate = now;
    updateMediaAsync();
}

Асинхронное получение медиасессии:
получение сессии:
Expand Collapse Copy
private void updateMediaAsync() {
    mediaExecutor.execute(() -> {
        List<IMediaSession> sessions = MediaPlayerInfo.Instance.getMediaSessions();

        if (sessions == null || sessions.isEmpty()) {
            currentTrack = null;
            currentSession = null;
            return;
        }

        MediaInfo found = null;
        IMediaSession foundSession = null;

        for (IMediaSession session : sessions) {
            if (session == null) continue;

            MediaInfo media;
            try {
                media = session.getMedia();
            } catch (Exception e) {
                continue;
            }

            if (media == null) continue;

            if (media.getPlaying()) {
                found = media;
                foundSession = session;
                break;
            }

            if (found == null) {
                found = media;
                foundSession = session;
            }
        }

        currentTrack = found;
        currentSession = foundSession;
    });
}


Загрузка обложки трека
Если плеер отдаёт обложку, её можно превратить в текстуру Minecraft.

отрисовка обложки трека:
Expand Collapse Copy
private ResourceLocation artworkTexture;

private void applyArtwork(byte[] artBytes) {
    try {
        NativeImage img = NativeImage.read(new ByteArrayInputStream(artBytes));
        DynamicTexture texture = new DynamicTexture(img);
        artworkTexture = Minecraft.getInstance()
                .getTextureManager()
                .getDynamicTextureLocation("media_art", texture);
    } catch (Exception ignored) {}
}


Отрисовка в HUD
Рендер худа у меня выполняется в событии HudRenderEvent, там и буду рисовать панельку. Здесь выводится обложка, название трека, исполнитель и прогресс. На примере всё будет прям в методе события, но желательно вынести в отдельный метод.
(методы и аргументация методов будет отличатся, база своя)
код отрисовки:
Expand Collapse Copy
@EventHandler
public void onHudRender(HudRenderEvent e) {
    if (currentTrack == null) return;

    Minecraft mc = Minecraft.getInstance();

    String title = currentTrack.getTitle().isEmpty()
            ? "Unknown"
            : currentTrack.getTitle();

    String artist = currentTrack.getArtist().isEmpty()
            ? "Unknown"
            : currentTrack.getArtist();

    long position = currentTrack.getPosition();
    long duration = currentTrack.getDuration();
    float progress = duration > 0 ? (float) position / duration : 0f;

    float x = mc.getMainWindow().getScaledWidth() / 2f - 60;
    float y = 20;

    RenderUtils.drawRoundedRect(x, y, 120, 40, 6f, 0xAA000000, 0xAA000000);

    if (artworkTexture != null) {
        RenderUtils.drawImage(artworkTexture, x + 4, y + 4, 32, 32, 0xFFFFFFFF);
    }

    FontRenderer font = FontManager.getInstance().getDefaultFont();
    font.drawString(title, x + 40, y + 8, 0xFFFFFFFF);
    font.drawString(artist, x + 40, y + 20, 0xFFAAAAAA);

    RenderUtils.drawRoundedRect(
            x + 4,
            y + 36,
            112 * progress,
            2,
            1,
            0xFFFFFFFF,
            0xFFFFFFFF
    );
}


Кнопки управления
Можно добавить управление воспроизведением: предыдущий трек, пауза/воспроизведение и следующий.
обработка клика:
Expand Collapse Copy
private void handleMediaClick(float mouseX, float mouseY) {
    if (currentSession == null || currentTrack == null) return;

    if (isInside(mouseX, mouseY, prevX, prevY, prevWidth)) {
        mediaExecutor.execute(currentSession::previous);
    } else if (isInside(mouseX, mouseY, playX, playY, playWidth)) {
        mediaExecutor.execute(() -> {
            if (currentTrack.getPlaying()) {
                currentSession.pause();
            } else {
                currentSession.play();
            }
        });
    } else if (isInside(mouseX, mouseY, nextX, nextY, nextWidth)) {
        mediaExecutor.execute(currentSession::next);
    }
}

Форматирование времени трека
форматирование:
Expand Collapse Copy
private String formatTime(long seconds) {
    if (seconds <= 0) return "0:00";
    long minutes = seconds / 60;
    long secs = seconds % 60;
    return String.format("%d:%02d", minutes, secs);
}
 
media-player-info-0.1.0.jar - старая ломаная библиотека, вобще не советую её использовать. Если хотите нормальный плеер то вам нужно делать DLL для этого
Вот пример
Пожалуйста, авторизуйтесь для просмотра ссылки.
Пожалуйста, авторизуйтесь для просмотра ссылки.
 
В релиз воткни её через пару часов будут лаги и фризы. Пульс и нур вырезали её иза фризов как раз
Также понадобится отдельный поток для асинхронного обновления, чтобы не блокировать игровой поток.
 
так юзать или ломанная?
Screenshot 2026-05-16 192326.png
 
"чатгпт придумай тупому пастеру с югейма предъяву насчёт его гайда, а то мне скучно живётся надо поумничать"
Пастер? XD ты даже мой клиент не видел чтобы так гововрить
 
Назад
Сверху Снизу