Jak odtworzyć mp4 video na JPanel lub JLabel?

0

Używam Xuggle library do odtwarzania video na JLabel lecz ładuje się ono przez 2-3 sekundy a na starszych komputerach jeszcze dłużej. Macie jakiś pomysł jak prawidłowo odtworzyć mp4 na JPanelu lub JLabelu żeby nie było buforowania?

0

możesz spróbwać vlcj ale on tylko na AWT Canvas odtwarza, ale nie ładuje się za długo

generalnie jest problem z porządnymi bibliotekami video do javy

pzdr

0

a czy vlcj sam potrafi dekodować mp4 czy korzysta z kodeków zainstalowanych w systemie? Potrzebuję otworzyć mp4 na panelu (ewentualnie innym komponencie) bez względu na kodeki zainstalowane na komputerze. Czy za pomocą vlcj uda mi się to osiągnąć?

1

vlcj używa bibliotek VLC, także dodatkowo będziesz musiał używać dll-ek. Natomiast możesz je dystrybuować razem z programem , te odpowiedzialne za odtwarzanie mp4 musiałbyś sam znaleźć ( w sumie wszystkie dll-ki zajmują ze 60 MB ale do jednego konkretnego jak rozdrobnisz to pewnie się zmieścisz 5-6 MB).

Oprócz tego możesz jeszcze spróbować http://gstreamer.freedesktop.org/ ale nie miałem z nim doczynienia w związku z czym nie potrafię Ci doradzić.

Możesz jeszcze spróbować zoptymalizować swój kod , w oddzielny wątek wrzucić odtwarzanie.

Jednak nie bardzo wierzę że uda Ci się stworzyć program który od razu bez opóźnień wyświetli Ci film. Nawet komercyjne odtwarzacze plików multimedialnych często się przywieszają na kilka sekund przy wczytaniu pliku.

0

Ok dzięki za info postaram się jakoś rozwiązać mój problem. Widocznie mam też coś nie do końca dobrze z wątkami, ponieważ mam JFrame'a na ktorym jest panel z filmem i etykiete z czasem ktora jest zarządzana przez Timer. Czyli etykieta z sekundami odświeżana przez Timer natomiast film leci w nowym wątku lecz przy wczytywaniu filmu etykieta pozostaje przez kilka sekund zamrozona i po trzech sekundach pojawia się nowa wartosc o 3 sekundy niższa (tzn timer odmierza czas prawidlowo ale odświeżanie widoku labelki nie następuje co sekundę)

0

A czy kod poniżej odtwarzający video za pomocą biblioteki Xuggle jest prawidłowy? Tzn czy wątek jest prawidłowo uruchamiany?

 public void setVideoName(final String videoName) {
    imageAndVideoPanel.removeAll();
    final VideoPanel videoPanel = new VideoPanel();
    videoPanel.setPreferredSize(Const.Dimensions.VIDEO_SIZE);
    videoPanel.setMinimumSize(Const.Dimensions.VIDEO_SIZE);
    videoPanel.setMaximumSize(Const.Dimensions.VIDEO_SIZE);
    imageAndVideoPanel.add(videoPanel);

    new Thread(new Runnable() {
        @Override
        public void run() {
            VideoCodec videoCodec =
                    new VideoCodec(videoPanel, videoName + TextsDao.getText("videoFilesExtension"));
        }
    }).start();
}
0

chyba ok ale nie lepiej stworzyć klasę implementującą Runnable i ją wywoływać niż tworzyć wątek w kodzie programu? Może ktoś mądrzejszy się wypowie, mi się wydaje że bardziej elegancko by było :-)

0

Próbowałem wczoraj użyć biblioteki vlcj i odtwarza filmy (dllki można dorzućić do wynikowego jara) lecz mam z nią problemy, ponieważ na oknie mam kilkanascie etykiet które po kliknięciu uruchamiają inny filmik i gdy zbyt szybko klikam w ikony (zmieniając tym samym wyświetlany film na inny) to przy 5 szybkim kliknięciu wyskakuje albo, że program przestał działać albo w miejscu gdzie powinien być filmik jest biały panel. Z biblioteką Xuggle nie mam takich problemów lecz wydaje mi się, że działa ona wolniej. Może przy bibliotece vlcj w nieprawidłowy sposób zamykam mediaplayera?

0

a przy vlcj używasz jendego mediaplayera czy różnych? tzn masz kilka różnych płacht na których wyświetlasz czy jedną którą zmieniasz?

0

Próbowałem na panel dodać za każdym razem nowy player a poźniej utworzyłem MediaPlayer we właściowści klkasy i za każdym razem do referencji mediaPlayer tworzyłem nowy player i ustawiałem żeby odtwarzal określone video. Może spróbować na jednym MediaPlayierze żeby był cały czas aktywny a tylko podmieniać URL do filmu?

1

Dokładnie tak :-)
nie musisz tworzyć nowego obiektu embeddedmediaplayer możesz mu tylko zmieniać parametr
w ogóle jak wiesz dokładnie jakie filmy mają być grane ( nie są wybierane przez użytkownika ) możesz stworzyć MediaListPlayer do którego dokładasz media list i odtwarzasz konkretny film który chcesz.

Na szybko spróbowałem i działa elegancko :)

0

Ok dzięki, przetestuję jeszcze dziasiaj i dam znać jak to działa :)

0

Jeszcze mam mały problem ponieważ przy użyciu vlsj mam obiekt EmbedeMediaPlayer który wrzucam na panel lecz po kilku przełączeniach filmik lekko się rozjeżdza na panelu. Jak można to najlepiej zrobić? Obecnie mam leftPanel na ramce na ktorym jest panel z filmikiem i przy zmianie filmiku / obrazka na tym panelu usuwam wsyzstko co na nim jest metodą removeAll() a pozniej dodaje panel z filmikiem lub jlabel z obrazkiem. Czy zamysł jest dobry? Używam BorderLayout, Box Layout oraz GrigLayot, moze jakby layout ustawić na null i podawać na sztywno jakiej wielkosci ma byc panel to wtedy nie byloby problemów?

0

Zmieniłem bibliotekę na VLCJ oraz dodałem .dll do jara i teraz filmiki odtwarzają się płynnie :) Akurat mediaPlayer pasuje mi pod tym względem, że odtwarza też obrazki. Działa to tak że użytkownik wybiera etykiete na którą chce kliknąć i jeśli kliknie to odtwarza mu się wybrany filmik/ obrazek (jeden obiekt media player i tylko zmieniam źródło) Dzięki za pomoc :)

0

Poradziłem sobie z odtwarzaniem filmików w ten sposób:

public class ExamQuestionsLeftPanel extends JPanel {
private EmbeddedMediaPlayerComponent component;
private EmbeddedMediaPlayer player;
...

public ExamQuestionsLeftPanel() {
    setUpPanel();
    initializeComponents();
}

private void setUpPanel() {
    NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), "VLCx86");
    component = new EmbeddedMediaPlayerComponent();
    player = component.getMediaPlayer();

    Border emptyBorder = BorderFactory.createEmptyBorder(10, 10, 10, 10);

    setLayout(null);
    setBackground(Const.Colors.EXAM_BACKGROUND_COLOR);
    setAlignmentX(Component.LEFT_ALIGNMENT);
    setBorder(emptyBorder);
}
...

public void setImageName(String imageName) {
    player.stop();
    player.prepareMedia("media" + File.separator + imageName);
    player.parseMedia();
    player.play();
}

public void setVideoName(final String videoTitle) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            player.stop();
            player.prepareMedia("media" + File.separator + videoTitle);
            player.parseMedia();
            player.play();
        }
    }).start();
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1