123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767 |
- /*
- * Copyright (C) 2015 iZc
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- package de.nplusc.izc.iZpl.Utils;
- import com.sun.jna.Native;
- import com.sun.jna.NativeLibrary;
- import de.nplusc.izc.iZpl.API.IZPLApi;
- import de.nplusc.izc.iZpl.API.PlaybackPlugin;
- import de.nplusc.izc.iZpl.API.UIPlugin;
- import de.nplusc.izc.iZpl.API.shared.MultiPlayListItem;
- import de.nplusc.izc.iZpl.API.shared.PlayListItem;
- import de.nplusc.izc.iZpl.API.shared.SinglePlayListItem;
- import de.nplusc.izc.tools.baseTools.Detectors;
- import net.java.truevfs.access.TFile;
- import java.awt.Canvas;
- import java.io.File;
- import java.io.IOException;
- import java.util.Arrays;
- import javax.swing.JPanel;
- import org.apache.logging.log4j.LogManager;
- import org.apache.logging.log4j.Logger;
- import uk.co.caprica.vlcj.binding.LibVlc;
- import uk.co.caprica.vlcj.binding.RuntimeUtil;
- import uk.co.caprica.vlcj.player.base.MediaPlayer;
- import uk.co.caprica.vlcj.player.base.MediaPlayerEventListener;
- import uk.co.caprica.vlcj.factory.MediaPlayerFactory;
- import uk.co.caprica.vlcj.media.Media;
- import uk.co.caprica.vlcj.media.MediaRef;
- import uk.co.caprica.vlcj.media.TrackType;
- import uk.co.caprica.vlcj.player.embedded.EmbeddedMediaPlayer;
- /**
- *
- * @author inge
- */
- public class VlcInterface implements PlaybackPlugin , MediaPlayerEventListener
- {
- private static final Logger l = LogManager.getLogger();
- //private static VlcInterface instance=null;
- private InternalInterface adapter=null;
- private PlayListItem currentTrack;
- private boolean isInMultiItem;
- private SinglePlayListItem[] multiItemStorage = null;
- private int multiIndex=0;
- private boolean isPlaying;
- private String vlcpath;
- private boolean suppressVideo = false;
- private static String jarschiv = VlcInterface.class.getProtectionDomain().getCodeSource().getLocation().getPath();
- private UIPlugin selectedUIPlugin;
- private final String vlcVout;
- private boolean voutRequired = false;
- private int length = 0;
- private int position = 0;
- public VlcInterface ()
- {
- this(new File(jarschiv).getParent() + "\\vlcbinaries",true);
- }
- private VlcInterface (String vlcpath,boolean bundledVersion)
- {
- this.vlcpath=vlcpath;
- boolean isOnWindows = Detectors.getSystemClassification()[0].equals("windows");
- vlcVout = "direct3d9";
- voutRequired = isOnWindows;
- }
-
-
- @Override
- public String getPluginName()
- {
- return "VLC Embedded";
- }
-
-
- @Override
- public void initializePlugin()
- {
- String[] osmetadata = Detectors.getSystemClassification();
- initializeInterface(null, osmetadata[0].equals("windows"));
- }
-
- @SuppressWarnings("CallToPrintStackTrace")
- private void initializeInterface(String vlcpath, boolean embedded)
- {
- String[] osmetadata = Detectors.getSystemClassification();
- l.info("Os-data:"+Arrays.toString(osmetadata));
- if (osmetadata[0].equals("windows"))
- {
- if(embedded)
- {
- File target = new File(new File(jarschiv).getParent() + "\\vlcbinaries");
- if (!target.exists())
- {
- TFile zippo = new TFile(jarschiv + "\\vlc\\vlc-3.0.3-" + osmetadata[0] + "-" + osmetadata[1] + ".zip");
- try
- {
- zippo.cp_rp(target);
- }
- catch (IOException ex)
- {
- ex.printStackTrace();
- }
- }
- NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), target.getPath());
- }
- else
- {
- throw new UnsupportedOperationException("ERROR! Host VLC is not supported yet on Windows");
- }
- try
- {
- TFile jarschcrap = new TFile(jarschiv + "\\vlc\\");
- if(jarschcrap.exists())
- {
- jarschcrap.rm_r();//removal of the embedded VLC data after connecting to the System
- }
- }
- catch (IOException ex)
- {
- ex.printStackTrace();
- }
- }
- else
- {
- if(embedded)
- {
- throw new UnsupportedOperationException("ERROR! invalid OSType detected, embedded VLC doesnt work here");
- }
- }
- Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
-
- }
-
-
- private JPanel cachedVideoSurface;
- @Override
- public void connectToPlayer()
- {
- selectedUIPlugin=IZPLApi.getUIPlugin();
- l.info("Connected the player");
- if(adapter==null)
- {
- l.info("Loading VLC with suppressVideo = {}",suppressVideo);
- adapter=new VlcJIterface(vlcpath,this,suppressVideo);
- adapter.suppressVideoOut(suppressVideo);
- if(cachedVideoSurface!=null)
- {
- adapter.setVideoSurface(cachedVideoSurface);
- }
- }
- }
- @Override
- public void registerVideoSurface(JPanel p)
- {
- if(adapter!=null)
- {
- adapter.setVideoSurface(p);
- }
- cachedVideoSurface=p;
- }
-
-
-
-
-
-
-
-
-
-
-
-
- @Override
- public int getLengthInSeconds()
- {
- return length;
- }
- @Override
- public int getPosition()
- {
- return position;
- }
- @Override
- public void seek(int sekunde)
- {
- if(adapter!=null)
- adapter.seek(sekunde);
- }
-
- @Override
- public void skipTitle()
- {
- if(adapter!=null)
- {
- if(isInMultiItem)
- {
- if(multiIndex==multiItemStorage.length-1)
- {
- isInMultiItem=false;
- }
- currentTrack=multiItemStorage[multiIndex++];
- adapter.addTitle(((SinglePlayListItem)currentTrack).getPath());
- }
- else
- {
- adapter.skipTitle();
- }
- }
- }
-
-
- @Override
- public void setTitleToPlay(PlayListItem i)
- {
- if(adapter!=null)
- {
- isPlaying=true;
- if(i instanceof SinglePlayListItem)
- {
- currentTrack = i;
- adapter.addTitle(((SinglePlayListItem)i).getPath());
- String t = ((SinglePlayListItem) i).getTitle();
- if (t != null && !t.equals(""))
- {
- selectedUIPlugin.setTrackName(t.split(",")[1]);
- }
- else
- {
- selectedUIPlugin.setTrackName(((SinglePlayListItem) i).getPath());
- }
- }
- else
- {
- isInMultiItem=true;
- multiIndex=0;
- multiItemStorage = ((MultiPlayListItem)i).getSinglePlayListElements();
- currentTrack=multiItemStorage[0];
- adapter.addTitle(multiItemStorage[0].getPath());
- multiIndex++;
- }
- }
- }
- @Override
- public PlayListItem getCurrentTitle()
- {
- return currentTrack;
- }
-
- @Override
- public void play()
- {
- if(!isPlaying&&adapter!=null)
- {
- adapter.play();
- isPlaying=true;
- }
- }
- @Override
- public void pause()
- {
- if(isPlaying&&adapter!=null)
- {
- adapter.pause();
- isPlaying=false;
- }
- }
-
- @Override
- public void mediaChanged(MediaPlayer mp, MediaRef mr)
- {
- Thread t = new Thread(() ->
- {
- grabMediaData(mp,mr);
- try
- {
- Thread.sleep(1000);
- }
- catch (InterruptedException devnulled)
- {
- }
- grabMediaData(mp,mr);
- });
- t.setName("VLC MediaDataGrabber");
- t.start();
- }
-
- private void grabMediaData(MediaPlayer mp,MediaRef mr)
- {
- Media m = mr.duplicateMedia();
- //IZplGUIBackend.setTitle(mp.getMediaMeta().getTitle());
- l.trace("Parsing media meta");
- selectedUIPlugin.setTrackLength((int) Math.ceil(m.info().duration()/1000));
-
- length = (int) Math.ceil(m.info().duration()/1000);
- selectedUIPlugin.setTrackLength(length);
- m.release();
- // TODO Media img.
- /*
- Image img = mp.getMediaMeta().getArtwork();
- if(img !=null)
- {
- l.info("got media img");
- }
- selectedUIPlugin.setAlbumArt(img);
- */
- }
-
-
- public void finished_internal(boolean skip)
- {
- Thread t = new Thread(()-> //HACK, VLC race conditions
- {
- try
- {
- if(!skip)
- {
- Thread.sleep(2000);
- }
- }
- catch (InterruptedException ex)
- {
- ex.printStackTrace();
- }
- if(isInMultiItem)
- {
- skipTitle();
- }
- else
- {
- IZPLApi.playNextTrack();
- }
- });
- t.setName("VLC-HACK");
- t.start();
- }
-
- //@Override
- public void error(MediaPlayer mp)
- {
- l.error("Some error happened on the current playlist segment:\n {}",currentTrack.getM3UElement());
- l.error("Skipping the track!");
- finished_internal(false);
- }
- @Override
- public boolean playingStatus()
- {
- return isPlaying;
- }
- @Override
- public void suppressVideoOut(boolean suppress)
- {
- suppressVideo = suppress;
- if(adapter !=null)
- {
- adapter.suppressVideoOut(suppress);
- }
- }
- @Override
- public void elementaryStreamAdded(MediaPlayer mp, TrackType tt, int i)
- {
- }
- @Override
- public void elementaryStreamDeleted(MediaPlayer mp, TrackType tt, int i)
- {
- }
- @Override
- public void elementaryStreamSelected(MediaPlayer mp, TrackType tt, int i)
- {
- }
- @Override
- public void opening(MediaPlayer mp)
- {
- }
- @Override
- public void buffering(MediaPlayer mp, float f)
- {
- }
- @Override
- public void playing(MediaPlayer mp)
- {
- }
- @Override
- public void paused(MediaPlayer mp)
- {
- }
- @Override
- public void stopped(MediaPlayer mp)
- {
-
- }
- @Override
- public void forward(MediaPlayer mp)
- {
- }
- @Override
- public void backward(MediaPlayer mp)
- {
- }
- @Override
- public void finished(MediaPlayer mp)
- {
- finished_internal(false);
- }
- @Override
- public void seekableChanged(MediaPlayer mp, int i)
- {
-
- }
- @Override
- public void pausableChanged(MediaPlayer mp, int i)
- {
- }
- @Override
- public void titleChanged(MediaPlayer mp, int i)
- {
- }
- @Override
- public void snapshotTaken(MediaPlayer mp, String string)
- {
- }
- @Override
- public void lengthChanged(MediaPlayer mp, long l)
- {
- length = (int) Math.ceil(l/1000);
- selectedUIPlugin.setTrackLength(length);
- }
- @Override
- public void videoOutput(MediaPlayer mp, int i)
- {
- }
- @Override
- public void scrambledChanged(MediaPlayer mp, int i)
- {
- }
- @Override
- public void corked(MediaPlayer mp, boolean bln)
- {
- }
- @Override
- public void muted(MediaPlayer mp, boolean bln)
- {
- }
- @Override
- public void volumeChanged(MediaPlayer mp, float f)
- {
- }
- @Override
- public void audioDeviceChanged(MediaPlayer mp, String string)
- {
- }
- @Override
- public void chapterChanged(MediaPlayer mp, int i)
- {
-
- }
- @Override
- public void positionChanged(MediaPlayer mediaPlayer, float newPosition)
- {
- }
- @Override
- public void timeChanged(MediaPlayer mediaPlayer, long newTime)
- {
- position = (int) newTime/1000;
- selectedUIPlugin.setPlaybackPositionInSeconds(position);
- }
- @Override
- public void mediaPlayerReady(MediaPlayer mediaPlayer)
- {
- }
-
-
-
- private interface InternalInterface
- {
- public void addTitle(String vlcpath);
- public void seek(int sekunde);
- public void skipTitle();
- public void play();
- public void pause();
- public default void setVideoSurface(JPanel p){};
- public default void suppressVideoOut(boolean suppress){};
- }
-
- private class VlcJIterface implements InternalInterface
- {
-
- //HACK, vlc logic..., visualizers only load on initial load
- private boolean requiresReload=false;
- private Canvas c = new Canvas();
- private final VlcInterface parent;
- private EmbeddedMediaPlayer mpaccess;
- private MediaPlayerFactory f;
- private boolean registeredVideoSurface=false;
- private boolean suppressVideoInternal = false;
-
- public VlcJIterface(String vlcpath,VlcInterface parent,boolean suppress)
- {
- suppressVideoInternal = suppress;
- l.info("Video suppression is {}",suppressVideoInternal);
- this.parent=parent;
- if(IZPLApi.isInHTTPStreamMode())
- {
- l.info("Stream mode on port="+IZPLApi.getHTTPStreamPort()+"...");
- f= new MediaPlayerFactory("--no-video-title-show",
- "--sout=#gather:transcode{vcodec=none,acodec=mp3,ab=256,channels=2,samplerate=44100}:udp{dst=localhost:"+IZPLApi.getHTTPStreamPort()+"} :sout-keep}"
- ,"--sout-all","--sout-keep",IZPLApi.getVerbosity()>2?"-vvv":""
- );
-
- }
- else
- {
- f= new MediaPlayerFactory("--no-video-title-show",IZPLApi.getVerbosity()>2?"-vvv":"",suppressVideo?"--no-video":"",voutRequired?"-V":"",voutRequired?vlcVout:""
- );
- }
- mpaccess = f.mediaPlayers().newEmbeddedMediaPlayer();
- mpaccess.events().addMediaPlayerEventListener(parent);
- }
-
- @Override
- public void suppressVideoOut(boolean suppress)
- {
- if(suppress!=suppressVideoInternal)
- {
- requiresReload=true;
- }
- suppressVideoInternal = suppress;
- }
-
- @Override
- public void addTitle(String path)
- {
- String[] options = new String[0];
- mpaccess.controls().stop();
- l.info("Next title:{}",path);
- if(registeredVideoSurface&&requiresReload)
- {
- l.info("Reloading LibVLC due to a limit of it");
- if(IZPLApi.isInHTTPStreamMode())
- {
- l.error("Video surface with streaming mode doesn't work... Quitting immediately!");
- IZPLApi.quickQuitWithoutSaving();
- }
- // "--projectm-preset-path="+IZPLApi.VISUALIZERPATH+File.separator,"--audio-visual=projectM","--novideo"
- options = new String[]{"--no-video-title-show",IZPLApi.getVerbosity()>2?"-vvv":"","--audio-visual=projectM","--effect-list=scope", "--projectm-preset-path="+IZPLApi.VISUALIZERPATH+File.separator+""
- , "--projectm-width="+videowidth,"--projectm-height="+videoheight ,"--novideo" //TODO flag for switching those flags for jukebox mode and similar stuff /*projectM*/
- };
- mpaccess.release();
- f.release();
- f= new MediaPlayerFactory(options);
- mpaccess = f.mediaPlayers().newEmbeddedMediaPlayer();
- mpaccess.events().addMediaPlayerEventListener(parent);
- mpaccess.videoSurface().set(f.videoSurfaces().newVideoSurface(c));
- requiresReload=false;
- }
- else
- {
- if(requiresReload) //stripping the video surface off, got to disable visualizing
- {
- l.info("Video suppression is {}",suppressVideo);
- l.info("Reloading LibVLC due to a limit of it");
- mpaccess.release();
- f.release();
- f= new MediaPlayerFactory("--no-video-title-show",IZPLApi.getVerbosity()>2?"-vvv":"",suppressVideoInternal?"--no-video":"",voutRequired?"-V":"",voutRequired?vlcVout:"");
- mpaccess = f.mediaPlayers().newEmbeddedMediaPlayer();
- mpaccess.events().addMediaPlayerEventListener(parent);
- requiresReload=false;
- }
- }
- mpaccess.media().play(path,options);
- }
- @Override
- public void seek(int sekunde)
- {
- mpaccess.controls().setPosition(((float)sekunde)/((float)getLengthInSeconds()));
- }
- @Override
- public void skipTitle()
- {
- parent.finished_internal(true);//über bande spielen
- }
- @Override
- public void play()
- {
- mpaccess.controls().play();
- }
- @Override
- public void pause()
- {
- mpaccess.controls().pause();
- }
-
- private int videowidth=0;
- private int videoheight=0;
-
- private JPanel oldPanel = null;
- @Override
- public void setVideoSurface(JPanel p)
- {
- if(p!=null)
- {
- registeredVideoSurface=true;
- p.removeAll();
- l.info("Surface size: ("+p.getWidth()+"|"+p.getHeight()+")");
- c.setBounds(0, 0, p.getWidth(), p.getHeight());
- p.add(c);
- int newvideowidth=p.getWidth();
- int newvideoheight=p.getHeight();
-
- if(p !=oldPanel)
- {
- oldPanel = p;
- requiresReload=true;
- }
-
- p.invalidate();
- videowidth = newvideowidth;
- videoheight = newvideoheight;
- mpaccess.videoSurface().set(f.videoSurfaces().newVideoSurface(c));
- }
- else
- {
- requiresReload=true;
- mpaccess.videoSurface().set(null);
- registeredVideoSurface=false;
- }
-
-
-
- }
-
-
-
- }
-
- private class VlcTelnetInterface implements InternalInterface
- {
- @Override
- public void addTitle(String path)
- {
-
- }
-
- @Override
- public void seek(int sekunde)
- {
- }
- @Override
- public void skipTitle()
- {
- }
- @Override
- public void play()
- {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
- @Override
- public void pause()
- {
- throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
- }
- }
-
- @Override
- @SuppressWarnings("CallToPrintStackTrace")
- public void prepareUpgrade()
- {
- if(new TFile(jarschiv + "\\vlc").exists()) //nullroute falls reinit nicht möglich da files schon ausgepackt wurden
- {
- try
- {
- //killen der alten vlc-natives
- TFile f = new TFile(IZPLApi.APPDIR+File.separator+"lib"+File.separator+"vlcbinaries");
- if(f.exists())
- f.rm_r();
- }
- catch (IOException ex)
- {
- ex.printStackTrace();
- }
- }
- };
- }
-
-
-
|