|
@@ -1,631 +1,638 @@
|
|
|
-/*
|
|
|
- * 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 de.schlichtherle.truezip.file.TFile;
|
|
|
-import java.awt.Image;
|
|
|
-import java.io.File;
|
|
|
-import java.io.IOException;
|
|
|
-import java.util.Arrays;
|
|
|
-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.internal.libvlc_media_t;
|
|
|
-import uk.co.caprica.vlcj.player.MediaPlayer;
|
|
|
-import uk.co.caprica.vlcj.player.MediaPlayerEventListener;
|
|
|
-import uk.co.caprica.vlcj.player.MediaPlayerFactory;
|
|
|
-import uk.co.caprica.vlcj.runtime.RuntimeUtil;
|
|
|
-
|
|
|
-/**
|
|
|
- *
|
|
|
- * @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 static String jarschiv = VlcInterface.class.getProtectionDomain().getCodeSource().getLocation().getPath();
|
|
|
- private UIPlugin selectedUIPlugin;
|
|
|
- public VlcInterface ()
|
|
|
- {
|
|
|
- this(new File(jarschiv).getParent() + "\\vlcbinaries",true);
|
|
|
- }
|
|
|
- private VlcInterface (String vlcpath,boolean bundledVersion)
|
|
|
- {
|
|
|
- this.vlcpath=vlcpath;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public String getPluginName()
|
|
|
- {
|
|
|
- return "VLC Embedded";
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public void initializePlugin()
|
|
|
- {
|
|
|
- initializeInterface(null, true);
|
|
|
- }
|
|
|
-
|
|
|
- @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"))
|
|
|
- {
|
|
|
-
|
|
|
- File target = new File(new File(jarschiv).getParent() + "\\vlcbinaries");
|
|
|
- if (!target.exists())
|
|
|
- {
|
|
|
- TFile zippo = new TFile(jarschiv + "\\vlc\\vlc-2.1.5-" + osmetadata[0] + "-" + osmetadata[1] + ".zip");
|
|
|
- try
|
|
|
- {
|
|
|
- zippo.cp_rp(target);
|
|
|
- TFile jarschcrap = new TFile(jarschiv + "\\vlc\\");
|
|
|
- jarschcrap.rm_r();//removal of the embedded VLC data after connecting to the System
|
|
|
- }
|
|
|
- catch (IOException ex)
|
|
|
- {
|
|
|
- ex.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), target.getPath());
|
|
|
- Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- throw new UnsupportedOperationException("ERROR! invalid OSType detected, embedded VLC doesnt work here");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void connectToPlayer()
|
|
|
- {
|
|
|
- selectedUIPlugin=IZPLApi.getUIPlugin();
|
|
|
- l.info("Connected the player");
|
|
|
- if(adapter==null)
|
|
|
- adapter=new VlcJIterface(vlcpath,this);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- public int getLengthInSeconds()
|
|
|
- {
|
|
|
- return adapter.getLengthInSeconds();
|
|
|
- }
|
|
|
- @Override
|
|
|
- public int getPosition()
|
|
|
- {
|
|
|
- return adapter.getPosition();
|
|
|
- }
|
|
|
- @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, libvlc_media_t l, String string)
|
|
|
- {
|
|
|
- Thread t = new Thread(() ->
|
|
|
- {
|
|
|
- grabMediaData(mp);
|
|
|
- try
|
|
|
- {
|
|
|
- Thread.sleep(1000);
|
|
|
- }
|
|
|
- catch (InterruptedException devnulled)
|
|
|
- {
|
|
|
- }
|
|
|
- grabMediaData(mp);
|
|
|
- });
|
|
|
- t.setName("VLC MediaDataGrabber");
|
|
|
- t.start();
|
|
|
- }
|
|
|
-
|
|
|
- private void grabMediaData(MediaPlayer mp)
|
|
|
- {
|
|
|
- mp.parseMedia();
|
|
|
- //IZplGUIBackend.setTitle(mp.getMediaMeta().getTitle());
|
|
|
-
|
|
|
- l.trace("{}", mp.getMediaMeta());
|
|
|
- selectedUIPlugin.setTrackLength((int) Math.ceil(mp.getMediaMeta().getLength()/1000.0f));
|
|
|
- Image img = mp.getMediaMeta().getArtwork();
|
|
|
- if(img !=null)
|
|
|
- {
|
|
|
- selectedUIPlugin.setAlbumArt(img);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- @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(false);
|
|
|
- }
|
|
|
-
|
|
|
- public void finished(boolean skip)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- if(!skip)
|
|
|
- {
|
|
|
- Thread.sleep(2000);
|
|
|
- }
|
|
|
- }
|
|
|
- catch (InterruptedException ex)
|
|
|
- {
|
|
|
- ex.printStackTrace();
|
|
|
- }
|
|
|
- if(isInMultiItem)
|
|
|
- {
|
|
|
- skipTitle();
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- PlayListItem next = IZPLApi.getNextItem();
|
|
|
- setTitleToPlay(next);
|
|
|
- }
|
|
|
- }
|
|
|
- @Override
|
|
|
- public void timeChanged(MediaPlayer mp, long l)
|
|
|
- {
|
|
|
- selectedUIPlugin.setPlaybackPositionInSeconds((int) Math.ceil(l/1000.0));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void positionChanged(MediaPlayer mp, float f)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @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)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void videoOutput(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void error(MediaPlayer mp)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaMetaChanged(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaSubItemAdded(MediaPlayer mp, libvlc_media_t l)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaDurationChanged(MediaPlayer mp, long l)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaParsedChanged(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaFreed(MediaPlayer mp)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaStateChanged(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void newMedia(MediaPlayer mp)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void subItemPlayed(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void subItemFinished(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void endOfSubItems(MediaPlayer mp)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void scrambledChanged(MediaPlayer mp, int i)
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void elementaryStreamAdded(MediaPlayer mp, int i, int i1)
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void elementaryStreamDeleted(MediaPlayer mp, int i, int i1)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void elementaryStreamSelected(MediaPlayer mp, int i, int i1)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void mediaSubItemTreeAdded(MediaPlayer mp, libvlc_media_t l)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
- @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)
|
|
|
- {
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private interface InternalInterface
|
|
|
- {
|
|
|
- public void addTitle(String vlcpath);
|
|
|
- public int getLengthInSeconds();
|
|
|
- public int getPosition();
|
|
|
- public void seek(int sekunde);
|
|
|
- public void skipTitle();
|
|
|
- public void play();
|
|
|
- public void pause();
|
|
|
- }
|
|
|
-
|
|
|
- private class VlcJIterface implements InternalInterface
|
|
|
- {
|
|
|
- private final VlcInterface parent;
|
|
|
- private final MediaPlayer mpaccess;
|
|
|
- private MediaPlayerFactory f;
|
|
|
- public VlcJIterface(String vlcpath,VlcInterface parent)
|
|
|
- {
|
|
|
- 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"
|
|
|
- );
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- f= new MediaPlayerFactory("--no-video-title-show");
|
|
|
- }
|
|
|
- mpaccess = f.newHeadlessMediaPlayer();
|
|
|
- mpaccess.addMediaPlayerEventListener(parent);
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void addTitle(String path)
|
|
|
- {
|
|
|
- mpaccess.stop();
|
|
|
- mpaccess.playMedia(path);
|
|
|
- }
|
|
|
- @Override
|
|
|
- public int getLengthInSeconds()
|
|
|
- {
|
|
|
- return (int) (Math.ceil(mpaccess.getLength()/1000f));
|
|
|
- }
|
|
|
- @Override
|
|
|
- public int getPosition()
|
|
|
- {
|
|
|
- return (int) (Math.ceil((mpaccess.getLength()/1000f)*mpaccess.getPosition()));
|
|
|
- }
|
|
|
- @Override
|
|
|
- public void seek(int sekunde)
|
|
|
- {
|
|
|
- mpaccess.setPosition(((float)sekunde)/((float)getLengthInSeconds()));
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void skipTitle()
|
|
|
- {
|
|
|
- parent.finished(true);//über bande spielen
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void play()
|
|
|
- {
|
|
|
- mpaccess.play();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public void pause()
|
|
|
- {
|
|
|
- mpaccess.pause();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- private class VlcTelnetInterface implements InternalInterface
|
|
|
- {
|
|
|
- @Override
|
|
|
- public void addTitle(String path)
|
|
|
- {
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public int getLengthInSeconds()
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- @Override
|
|
|
- public int getPosition()
|
|
|
- {
|
|
|
- return 0;
|
|
|
- }
|
|
|
- @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();
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
+/*
|
|
|
+ * 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 de.schlichtherle.truezip.file.TFile;
|
|
|
+import java.awt.Image;
|
|
|
+import java.io.File;
|
|
|
+import java.io.IOException;
|
|
|
+import java.util.Arrays;
|
|
|
+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.internal.libvlc_media_t;
|
|
|
+import uk.co.caprica.vlcj.player.MediaPlayer;
|
|
|
+import uk.co.caprica.vlcj.player.MediaPlayerEventListener;
|
|
|
+import uk.co.caprica.vlcj.player.MediaPlayerFactory;
|
|
|
+import uk.co.caprica.vlcj.runtime.RuntimeUtil;
|
|
|
+
|
|
|
+/**
|
|
|
+ *
|
|
|
+ * @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 static String jarschiv = VlcInterface.class.getProtectionDomain().getCodeSource().getLocation().getPath();
|
|
|
+ private UIPlugin selectedUIPlugin;
|
|
|
+ public VlcInterface ()
|
|
|
+ {
|
|
|
+ this(new File(jarschiv).getParent() + "\\vlcbinaries",true);
|
|
|
+ }
|
|
|
+ private VlcInterface (String vlcpath,boolean bundledVersion)
|
|
|
+ {
|
|
|
+ this.vlcpath=vlcpath;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String getPluginName()
|
|
|
+ {
|
|
|
+ return "VLC Embedded";
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void initializePlugin()
|
|
|
+ {
|
|
|
+ initializeInterface(null, true);
|
|
|
+ }
|
|
|
+
|
|
|
+ @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"))
|
|
|
+ {
|
|
|
+
|
|
|
+ File target = new File(new File(jarschiv).getParent() + "\\vlcbinaries");
|
|
|
+ if (!target.exists())
|
|
|
+ {
|
|
|
+ TFile zippo = new TFile(jarschiv + "\\vlc\\vlc-2.2.4-" + osmetadata[0] + "-" + osmetadata[1] + ".zip");
|
|
|
+ try
|
|
|
+ {
|
|
|
+ zippo.cp_rp(target);
|
|
|
+ TFile jarschcrap = new TFile(jarschiv + "\\vlc\\");
|
|
|
+ jarschcrap.rm_r();//removal of the embedded VLC data after connecting to the System
|
|
|
+ }
|
|
|
+ catch (IOException ex)
|
|
|
+ {
|
|
|
+ ex.printStackTrace();
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), target.getPath());
|
|
|
+ Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ throw new UnsupportedOperationException("ERROR! invalid OSType detected, embedded VLC doesnt work here");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void connectToPlayer()
|
|
|
+ {
|
|
|
+ selectedUIPlugin=IZPLApi.getUIPlugin();
|
|
|
+ l.info("Connected the player");
|
|
|
+ if(adapter==null)
|
|
|
+ adapter=new VlcJIterface(vlcpath,this);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getLengthInSeconds()
|
|
|
+ {
|
|
|
+ return adapter.getLengthInSeconds();
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public int getPosition()
|
|
|
+ {
|
|
|
+ return adapter.getPosition();
|
|
|
+ }
|
|
|
+ @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, libvlc_media_t l, String string)
|
|
|
+ {
|
|
|
+ Thread t = new Thread(() ->
|
|
|
+ {
|
|
|
+ grabMediaData(mp);
|
|
|
+ try
|
|
|
+ {
|
|
|
+ Thread.sleep(1000);
|
|
|
+ }
|
|
|
+ catch (InterruptedException devnulled)
|
|
|
+ {
|
|
|
+ }
|
|
|
+ grabMediaData(mp);
|
|
|
+ });
|
|
|
+ t.setName("VLC MediaDataGrabber");
|
|
|
+ t.start();
|
|
|
+ }
|
|
|
+
|
|
|
+ private void grabMediaData(MediaPlayer mp)
|
|
|
+ {
|
|
|
+ mp.parseMedia();
|
|
|
+ //IZplGUIBackend.setTitle(mp.getMediaMeta().getTitle());
|
|
|
+
|
|
|
+ l.trace("{}", mp.getMediaMeta());
|
|
|
+ selectedUIPlugin.setTrackLength((int) Math.ceil(mp.getMediaMeta().getLength()/1000.0f));
|
|
|
+ Image img = mp.getMediaMeta().getArtwork();
|
|
|
+ if(img !=null)
|
|
|
+ {
|
|
|
+ selectedUIPlugin.setAlbumArt(img);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @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(false);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void finished(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
|
|
|
+ {
|
|
|
+ PlayListItem next = IZPLApi.getNextItem();
|
|
|
+ setTitleToPlay(next);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ t.setName("VLC-HACK");
|
|
|
+ t.start();
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void timeChanged(MediaPlayer mp, long l)
|
|
|
+ {
|
|
|
+ selectedUIPlugin.setPlaybackPositionInSeconds((int) Math.ceil(l/1000.0));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void positionChanged(MediaPlayer mp, float f)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @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)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void videoOutput(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void error(MediaPlayer mp)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaMetaChanged(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaSubItemAdded(MediaPlayer mp, libvlc_media_t l)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaDurationChanged(MediaPlayer mp, long l)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaParsedChanged(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaFreed(MediaPlayer mp)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaStateChanged(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void newMedia(MediaPlayer mp)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void subItemPlayed(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void subItemFinished(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void endOfSubItems(MediaPlayer mp)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void scrambledChanged(MediaPlayer mp, int i)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void elementaryStreamAdded(MediaPlayer mp, int i, int i1)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void elementaryStreamDeleted(MediaPlayer mp, int i, int i1)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void elementaryStreamSelected(MediaPlayer mp, int i, int i1)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void mediaSubItemTreeAdded(MediaPlayer mp, libvlc_media_t l)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+ @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)
|
|
|
+ {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private interface InternalInterface
|
|
|
+ {
|
|
|
+ public void addTitle(String vlcpath);
|
|
|
+ public int getLengthInSeconds();
|
|
|
+ public int getPosition();
|
|
|
+ public void seek(int sekunde);
|
|
|
+ public void skipTitle();
|
|
|
+ public void play();
|
|
|
+ public void pause();
|
|
|
+ }
|
|
|
+
|
|
|
+ private class VlcJIterface implements InternalInterface
|
|
|
+ {
|
|
|
+ private final VlcInterface parent;
|
|
|
+ private final MediaPlayer mpaccess;
|
|
|
+ private MediaPlayerFactory f;
|
|
|
+ public VlcJIterface(String vlcpath,VlcInterface parent)
|
|
|
+ {
|
|
|
+ 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"
|
|
|
+ );
|
|
|
+
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ f= new MediaPlayerFactory("--no-video-title-show");
|
|
|
+ }
|
|
|
+ mpaccess = f.newHeadlessMediaPlayer();
|
|
|
+ mpaccess.addMediaPlayerEventListener(parent);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void addTitle(String path)
|
|
|
+ {
|
|
|
+ mpaccess.stop();
|
|
|
+ l.info("Next title:{}",path);
|
|
|
+ mpaccess.playMedia(path);
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public int getLengthInSeconds()
|
|
|
+ {
|
|
|
+ return (int) (Math.ceil(mpaccess.getLength()/1000f));
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public int getPosition()
|
|
|
+ {
|
|
|
+ return (int) (Math.ceil((mpaccess.getLength()/1000f)*mpaccess.getPosition()));
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public void seek(int sekunde)
|
|
|
+ {
|
|
|
+ mpaccess.setPosition(((float)sekunde)/((float)getLengthInSeconds()));
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void skipTitle()
|
|
|
+ {
|
|
|
+ parent.finished(true);//über bande spielen
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void play()
|
|
|
+ {
|
|
|
+ mpaccess.play();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void pause()
|
|
|
+ {
|
|
|
+ mpaccess.pause();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private class VlcTelnetInterface implements InternalInterface
|
|
|
+ {
|
|
|
+ @Override
|
|
|
+ public void addTitle(String path)
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public int getLengthInSeconds()
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public int getPosition()
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ @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();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|