📄 nativemediaplayerwindowsds.java
字号:
/* * File: NativeMediaPlayerWindowsDS.java * Project: MPI Linguistic Application * Date: 02 May 2007 * * Copyright (C) 2001-2007 Max Planck Institute for Psycholinguistics * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package mpi.eudico.client.annotator.player;import com.jniwrapper.DefaultLibraryLoader;import com.jniwrapper.DoubleFloat;import com.jniwrapper.ExternalArrayPointer;import com.jniwrapper.Int32;import com.jniwrapper.Parameter;import com.jniwrapper.Pointer;import com.jniwrapper.PrimitiveArray;import com.jniwrapper.UInt8;import com.jniwrapper.win32.automation.IDispatch;import com.jniwrapper.win32.automation.types.BStr;import com.jniwrapper.win32.com.ComException;import com.jniwrapper.win32.com.types.ClsCtx;import com.jniwrapper.win32.com.types.LongPtr;import com.jniwrapper.win32.ole.OleFunctions;import com.jniwrapper.win32.ui.WindowProc;import com.jniwrapper.win32.ui.WindowTools;import com.jniwrapper.win32.ui.Wnd;import com.jniwrapper.win32.ui.WndClass;import mpi.eudico.client.annotator.ElanLayoutManager;import mpi.eudico.client.annotator.ElanLocale;import mpi.eudico.client.annotator.export.ImageExporter;import mpi.eudico.client.annotator.gui.FormattedMessageDlg;import mpi.eudico.client.annotator.nativemedia.quartztypelib.*;import mpi.eudico.client.annotator.nativemedia.quartztypelib.impl.*;import mpi.eudico.client.mediacontrol.ControllerEvent;import mpi.eudico.client.mediacontrol.ControllerListener;import mpi.eudico.client.mediacontrol.ControllerManager;import mpi.eudico.server.corpora.clomimpl.abstr.MediaDescriptor;import mpi.util.TimeFormatter;//import mpi.eudico.client.annotator.nativemedia.wmplib.*;import java.awt.Component;import java.awt.Image;import java.awt.Panel;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.ComponentEvent;import java.awt.event.ComponentListener;import java.awt.event.HierarchyEvent;import java.awt.event.HierarchyListener;import java.awt.event.MouseAdapter;import java.awt.event.WindowEvent;import java.awt.event.WindowListener;import java.awt.image.BufferedImage;import java.util.Vector;import javax.swing.JMenuItem;import javax.swing.JOptionPane;import javax.swing.JPopupMenu;import javax.swing.SwingUtilities;/** * The direct show based implementation of an elan media player */public class NativeMediaPlayerWindowsDS extends ControllerManager implements ElanMediaPlayer, ControllerListener, ActionListener { /** Holds value of property DOCUMENT ME! */ private final static int STATE_STOP = 0; /** Holds value of property DOCUMENT ME! */ private final static int STATE_PAUSE = 1; /** Holds value of property DOCUMENT ME! */ private final static int STATE_RUN = 2; /** Holds value of property DOCUMENT ME! */ private final static int DIRECT_SHOW_TRUE = -1; /** Holds value of property DOCUMENT ME! */ private static final String CALLBACK_WINDOW_CLASS_NAME = "CallbackWindowClass"; /** Holds value of property DOCUMENT ME! */ private final static String MEDIA_TYPE_WAVE = "{e436eb8b-524f-11ce-9f53-0020af0ba770}"; /** Holds value of property DOCUMENT ME! */ private final static String MEDIA_TYPE_MPG1 = "{e436eb84-524f-11ce-9f53-0020af0ba770}"; /** Holds value of property DOCUMENT ME! */ private final static String MEDIA_TYPE_MPG2 = "{e06d8022-db46-11cf-b4d1-00805f6cbbea}"; private static boolean regFiltersPrinted = false; private MediaDescriptor mediaDescriptor; private IMediaControl mediaControl; private IMediaPosition mediaPosition; private IBasicAudio basicAudio; private IBasicVideo2 basicVideo; private IVideoWindow videoWindow; /** Holds value of property DOCUMENT ME! */ private IMediaEventEx mediaEvent; private IMediaTypeInfo mediaTypeInfo; private VisualComponent visualComponent; private Wnd videoWnd; private boolean playing; private long offset; private long duration; private long stopTime; private boolean adjustedStopTime; private float aspectRatio; private double millisPerSample; private JPopupMenu popup; private JMenuItem durationItem; /** Holds value of property DOCUMENT ME! */ protected JMenuItem detachItem; private JMenuItem infoItem; private JMenuItem saveItem; private ElanLayoutManager layoutManager; private boolean detached; private boolean isWaveMedia; private boolean isMpeg1Media; private boolean isMpeg2Media; private boolean mediaInfoDetected; private boolean frameRateAutoDetected = true; /** * Create a JMFMediaPlayer for a media URL * * @param mediaDescriptor DOCUMENT ME! * * @throws NoPlayerException DOCUMENT ME! */ public NativeMediaPlayerWindowsDS(MediaDescriptor mediaDescriptor) throws NoPlayerException { try { this.mediaDescriptor = mediaDescriptor; // make sure that the jniwrapper library is available if (DefaultLibraryLoader.getInstance().findLibrary("jniwrap") == null) { // relative path to the cvs MPI directory which is the user.dir for developers DefaultLibraryLoader.getInstance().addPath("lib/java/jniwrapper"); DefaultLibraryLoader.getInstance().loadLibrary("jniwrap"); } String URLString = mediaDescriptor.mediaURL; if (URLString.startsWith("file:") && !URLString.startsWith("file:///")) { URLString = URLString.substring(5); } OleFunctions.oleInitialize(); // jniwrapper 2.x //mediaControl = FilgraphManager.create(new ClsCtx( // ClsCtx.CLSCTX_INPROC_SERVER)); // jniwrapper/comfyj 3.x mediaControl = FilgraphManager.create(ClsCtx.INPROC_SERVER); printRegisteredFilters(); mediaControl.renderFile(new BStr(URLString)); final IMediaPositionImpl mp = new IMediaPositionImpl(); mediaControl.queryInterface(mp.getIID(), mp); mediaPosition = mp; final IVideoWindowImpl vw = new IVideoWindowImpl(); mediaControl.queryInterface(vw.getIID(), vw); videoWindow = vw; final IBasicVideo2Impl bv = new IBasicVideo2Impl(); mediaControl.queryInterface(bv.getIID(), bv); basicVideo = bv; final IBasicAudioImpl ba = new IBasicAudioImpl(); mediaControl.queryInterface(ba.getIID(), ba); basicAudio = ba; final IMediaEventExImpl me = new IMediaEventExImpl(); mediaControl.queryInterface(me.getIID(), me); mediaEvent = me; // analyse the filter structure and force mpeg1 stream splitter for mpeg1 media detectMediaType(); try { adjustFiltersIfNeeded(); } catch (ComException cex) { System.out.println("Could not adjust media filters..."); cex.printStackTrace(); } // make distinction between audio and video // side effect of prepareFilters where media type is determined if (isWaveMedia || mediaDescriptor.mimeType.equals( MediaDescriptor.GENERIC_AUDIO_TYPE)) { visualComponent = null; millisPerSample = 40; // arbitrary choice, user always has pixel step frameRateAutoDetected = false; } else { visualComponent = new VisualComponent(); visualComponent.addMouseListener(new MouseHandler()); mediaControl.pause(); Int32 plX = new Int32(); Int32 plY = new Int32(); basicVideo.getPreferredAspectRatio(plX, plY); aspectRatio = ((float) plX.getValue()) / plY.getValue(); if (aspectRatio == 0.0) { aspectRatio = ((float) basicVideo.getSourceWidth().getValue()) / basicVideo.getSourceHeight() .getValue(); } //System.out.println("Video w: " + basicVideo.getSourceWidth() + " h: " + basicVideo.getSourceHeight()); System.out.println("Aspect Ratio: " + aspectRatio); double tpf = basicVideo.getAvgTimePerFrame().getValue(); millisPerSample = 1000 * tpf; System.out.println("Millis per Sample: " + millisPerSample); if (millisPerSample == 0) { millisPerSample = 40; frameRateAutoDetected = false; } } offset = mediaDescriptor.timeOrigin; System.out.println("offset: " + offset); duration = (long) (1000 * mediaPosition.getDuration().getValue()) - offset; System.out.println("duration: " + duration); stopTime = duration; /* DISABLED BLOCK WITH EXPERIMENTAL ACTIVE CALLBACK CODE WndClass callbackWndClass = new WndClass(new CallbackWindowProc(), CALLBACK_WINDOW_CLASS_NAME); //WndClass callbackWndClass = new WndClass(new CallbackWindowProc(), NativeMediaPlayerWindowsDS.class.getName()); Int16 result = callbackWndClass.register(); System.out.println("result " + result.getValue()); //Wnd listeningWindow = Wnd.createWindow(CALLBACK_WINDOW_CLASS_NAME); Module hModule = Module.getCurrent(); Handle NULL = new Handle(); Wnd nullParent = new Wnd(); Wnd listeningWindow = Wnd.createWindow( CALLBACK_WINDOW_CLASS_NAME, "NativeMediaPlayerWindowsDS", Wnd.WS_CHILD, 0, 0, 0, 0, //nullParent, nullParent, NULL, hModule, NULL); LongPtr windowHandle = new LongPtr(); windowHandle.setValue(listeningWindow.getValue()); me.setNotifyWindow(windowHandle, new Int32(12345), null);*/ JPopupMenu.setDefaultLightWeightPopupEnabled(false); popup = new JPopupMenu(); infoItem = new JMenuItem(ElanLocale.getString("Player.Info")); infoItem.addActionListener(this); durationItem = new JMenuItem(ElanLocale.getString("Player.duration") + ": " + TimeFormatter.toString(getMediaDuration())); durationItem.setEnabled(false); saveItem = new JMenuItem(ElanLocale.getString("Player.SaveFrame")); saveItem.addActionListener(this); popup.addSeparator(); popup.add(saveItem); popup.add(infoItem); popup.add(durationItem); } catch (com.jniwrapper.win32.com.ComException e) { e.printStackTrace(); /* ?? if (isMpeg2Media) { JOptionPane.showMessageDialog(null, (ElanLocale.getString("NativeMediaPlayerWindows.Error2") + "\n" + ElanLocale.getString("NativeMediaPlayerWindows.Error3")), ElanLocale.getString("Message.Error"), JOptionPane.ERROR_MESSAGE); } */ throw new NoPlayerException( "Problem while creating directshow based media player"); } catch (Exception e) { e.printStackTrace(); throw new NoPlayerException( "Problem while creating directshow based media player"); } } /** * DOCUMENT ME! */ public void finalize() throws Throwable { System.out.println("Finalize media player..."); OleFunctions.oleUninitialize(); super.finalize(); } /** * Release resources to be ready for the garbage collector...? */ public void cleanUpOnClose() { System.out.println("Clean up media player..."); OleFunctions.oleUninitialize(); mediaControl = null; mediaPosition = null; basicAudio = null; basicVideo = null; videoWindow = null; } /** * Sets the global booleans isMpeg1Media and isWaveMedia Needs to be called * only once; */ private void detectMediaType() { if (mediaInfoDetected) { return; } mediaControl.stop(); IFilterInfoImpl filterInfo = new IFilterInfoImpl(); IPinInfoImpl pinInfo = new IPinInfoImpl(); IAMCollectionImpl filterColl = new IAMCollectionImpl(); IAMCollectionImpl pinColl = new IAMCollectionImpl(); IMediaTypeInfoImpl mediaInfo = new IMediaTypeInfoImpl(); mediaControl.stop(); mediaControl.getFilterCollection().queryInterface(filterColl.getIID(), filterColl); long nFilters = filterColl.getCount().getValue(); for (int i = 0; i < nFilters; i++) { filterColl.item(new Int32(i)).queryInterface(filterInfo.getIID(), filterInfo); // only the file source in the filter is needed to see what media we are dealing with if (filterInfo.getIsFileSource().getValue() == DIRECT_SHOW_TRUE) { filterInfo.getPins().queryInterface(pinColl.getIID(), pinColl); long nPins = pinColl.getCount().getValue(); for (int j = 0; j < nPins; j++) { pinColl.item(new Int32(j)).queryInterface(pinInfo.getIID(), pinInfo); // only one pin but just to be sure if (pinInfo.getName().getValue().equalsIgnoreCase("output")) { pinInfo.getConnectionMediaType().queryInterface(mediaInfo.getIID(), mediaInfo); //System.out.println("MI subtype: " + mediaInfo.getSubtype().getValue()); if (mediaInfo.getSubtype().getValue().equalsIgnoreCase(MEDIA_TYPE_WAVE)) { //System.out.println("Wave media data"); isWaveMedia = true; } else if (mediaInfo.getSubtype().getValue() .equalsIgnoreCase(MEDIA_TYPE_MPG1)) { //System.out.println("MPG1 media data"); isMpeg1Media = true; } else if (mediaInfo.getSubtype().getValue() .equalsIgnoreCase(MEDIA_TYPE_MPG2)) { isMpeg2Media = true; } } } } } mediaInfoDetected = true; printFilterInfo();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -