📄 nativemediaplayerwindowsds.java
字号:
} /** * Prints info from the current filters in the filter tree Not needed but * can be handy for debugging purposes */ private void printFilterInfo() { try { mediaControl.stop(); System.out.println("Filters in the filter chain: "); IFilterInfoImpl filterInfo = new IFilterInfoImpl(); IPinInfoImpl pinInfo = new IPinInfoImpl(); IAMCollectionImpl filterColl = new IAMCollectionImpl(); IAMCollectionImpl pinColl = new IAMCollectionImpl(); 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); System.out.println("index: " + i + " name: " + filterInfo.getName().getValue()); 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); System.out.println(" pin: " + j + " name: " + pinInfo.getName().getValue()); } } } catch (Exception e) { System.out.println("Could not print the filter chain..."); System.out.println(e.getMessage()); } } /** * Print the names of the filters in the registry, only once per jvm. */ private void printRegisteredFilters() { if (regFiltersPrinted) { return; } System.out.println("Filters listed in the registry..."); try { IAMCollectionImpl filterColl = new IAMCollectionImpl(); IRegFilterInfoImpl filterInfo = new IRegFilterInfoImpl(); mediaControl.getRegFilterCollection().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); System.out.println("Filter: " + i + ": " + filterInfo.getName().getValue()); } } catch (Exception ex) { // catch any exception... System.out.println( "Could not get complete information on registered media filters"); System.out.println(ex.getMessage()); regFiltersPrinted = true; // try only once } regFiltersPrinted = true; } /** * At this moment mpeg2 splitters can mess up mpeg1 rendering behaviour * Make sure that mpg1 data gets rendered with the default mpg1 splitter * in the filter graph * * @throws NoPlayerException DOCUMENT ME! */ private void adjustFiltersIfNeeded() throws NoPlayerException, ComException { mediaControl.stop(); detectMediaType(); IFilterInfoImpl filterInfo = new IFilterInfoImpl(); IFilterInfoImpl currentSplitterFilterInfo = new IFilterInfoImpl(); IFilterInfoImpl defaultSplitterFilterInfo = new IFilterInfoImpl(); IAMCollectionImpl splitterPinColl = new IAMCollectionImpl(); IPinInfoImpl pinInfo = new IPinInfoImpl(); IPinInfoImpl fileSourceOutputPinInfo = new IPinInfoImpl(); IPinInfoImpl audioDecoderInputPinInfo = new IPinInfoImpl(); IPinInfoImpl videoDecoderInputPinInfo = new IPinInfoImpl(); IMediaTypeInfoImpl mediaInfo = new IMediaTypeInfoImpl(); IAMCollectionImpl filterColl = new IAMCollectionImpl(); IAMCollectionImpl pinColl = new IAMCollectionImpl(); 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")) { // we have got the file source output pin pinColl.item(new Int32(j)).queryInterface(fileSourceOutputPinInfo.getIID(), fileSourceOutputPinInfo); // get the pin collection of the current splitter fileSourceOutputPinInfo.getConnectedTo().queryInterface(pinInfo.getIID(), pinInfo); pinInfo.getFilterInfo().queryInterface(currentSplitterFilterInfo.getIID(), currentSplitterFilterInfo); currentSplitterFilterInfo.getPins().queryInterface(splitterPinColl.getIID(), splitterPinColl); System.out.println("Media splitter filter name: " + currentSplitterFilterInfo.getName().getValue()); } } } } if ((currentSplitterFilterInfo != null) && "MPEG-I Stream Splitter".equals(currentSplitterFilterInfo.getName() .getValue())) { // don't change the filter graph return; } // Jan 2007: If the new Elecard decoder is in the chain, don't remove it // although this codec prevents playback of mpeg-1 with a rate < 1 if ((currentSplitterFilterInfo != null) && "Elecard MPEG Demultiplexer".equals(currentSplitterFilterInfo.getName() .getValue())) { System.out.println( "Current splitter: Elecard MPEG Demultiplexer. Not removed from the chain"); return; } // if it is mpg1 we need to make sure that the mpeg splitter is the default directshow mpeg1 splitter // because the cheepo mpeg2 splitters introduce stop accuracy problems if (isMpeg1Media) { /*// attempt to create a default filter graph, causes the app. to hang try { createDefaultGrapgh(); printFilterInfo(); return; } catch (Exception anyEx) { // if anything went wrong recreate the mediacontrol System.out.println("Could not create default mpeg-1 filter graph"); } */ // build a list of known problematic splitters Vector problemSplitters = new Vector(); problemSplitters.add("Moonlight-Elecard MPEG2 Demultiplexer"); problemSplitters.add("Elecard MPEG2 Demultiplexer"); // warn the user for a splitter that can not be removed by ELAN String currentSplitter = currentSplitterFilterInfo.getName() .getValue(); //System.out.println("Splitter name: " + currentSplitter); if (problemSplitters.contains(currentSplitter)) { JOptionPane.showMessageDialog(null, ElanLocale.getString("NativeMediaPlayerWindows.Warning1") + "\"" + currentSplitter + "\"", ElanLocale.getString("Message.Warning"), JOptionPane.WARNING_MESSAGE); return; } // gather the pins the current splitter is connected to long nPins = splitterPinColl.getCount().getValue(); for (int i = 0; i < nPins; i++) { splitterPinColl.item(new Int32(i)).queryInterface(pinInfo.getIID(), pinInfo); String pinName = pinInfo.getName().getValue().toLowerCase(); if (pinName.indexOf("input") >= 0) { pinInfo.getConnectedTo().queryInterface(fileSourceOutputPinInfo.getIID(), fileSourceOutputPinInfo); } else if (pinName.indexOf("audio") >= 0) { pinInfo.getConnectedTo().queryInterface(audioDecoderInputPinInfo.getIID(), audioDecoderInputPinInfo); } else if (pinName.indexOf("video") >= 0) { pinInfo.getConnectedTo().queryInterface(videoDecoderInputPinInfo.getIID(), videoDecoderInputPinInfo); } } // find the default splitter among the registered filters boolean defaultSplitterAvailable = false; IRegFilterInfoImpl regFilterInfo = new IRegFilterInfoImpl(); mediaControl.getRegFilterCollection().queryInterface(filterColl.getIID(), filterColl); nFilters = filterColl.getCount().getValue(); for (int i = 0; i < nFilters; i++) { filterColl.item(new Int32(i)).queryInterface(regFilterInfo.getIID(), regFilterInfo); if (regFilterInfo.getName().getValue().equalsIgnoreCase("MPEG-I Stream Splitter")) { regFilterInfo.filter().queryInterface(defaultSplitterFilterInfo.getIID(), defaultSplitterFilterInfo); defaultSplitterAvailable = true; break; } } // only proceed when the default splitter was found // there is no check if the current splitter already is the default splitter, who cares if (defaultSplitterAvailable) { try { // printFilterInfo(); // disconnect current splitter. by disconnecting the file source all pins are disconnected fileSourceOutputPinInfo.disconnect(); System.out.println( "== Removed MPEG-2 splitter from chain: " + currentSplitter); // connect the file source to the default splitter // this must be done to make the audio and video output pins available defaultSplitterFilterInfo.getPins().queryInterface(splitterPinColl.getIID(), splitterPinColl); nPins = splitterPinColl.getCount().getValue(); splitterPinColl.item(new Int32(0)).queryInterface(pinInfo.getIID(), pinInfo); fileSourceOutputPinInfo.connect(pinInfo); System.out.println("== Connected default splitter: " + defaultSplitterFilterInfo.getName().getValue()); // let windows build the rest of the filter graph by calling render on the video and audio pins defaultSplitterFilterInfo.getPins().queryInterface(splitterPinColl.getIID(), splitterPinColl); nPins = splitterPinColl.getCount().getValue(); for (int i = 0; i < nPins; i++) { splitterPinColl.item(new Int32(i)).queryInterface(pinInfo.getIID(), pinInfo); String pinName = pinInfo.getName().getValue() .toLowerCase(); if (pinName.indexOf("audio") >= 0) { pinInfo.render(); } else if (pinName.indexOf("video") >= 0) { pinInfo.render(); } } /* // connect the audio and video pins defaultSplitterFilterInfo.getPins().queryInterface(splitterPinColl.getIID(), splitterPinColl); nPins = splitterPinColl.getCount().getValue(); for (int i = 0; i < nPins; i++) { splitterPinColl.item(new Int32(i)).queryInterface(pinInfo.getIID(), pinInfo); String pinName = pinInfo.getName().getValue().toLowerCase(); if (pinName.indexOf("audio") >= 0) { pinInfo.connect(audioDecoderInputPinInfo); } else if (pinName.indexOf("video") >= 0) { pinInfo.connect(videoDecoderInputPinInfo); } } */ printFilterInfo(); } catch (com.jniwrapper.win32.com.ComException e) { e.printStackTrace(); JOptionPane.showMessageDialog(null, ElanLocale.getString("NativeMediaPlayerWindows.Error1"), ElanLocale.getString("Message.Error"), JOptionPane.ERROR_MESSAGE); throw new NoPlayerException( "Problem while creating directshow based media player"); } } } } /** * Tries to create the default windows mpeg-1 filter grapgh. * * @throws ComException any com exception */ private void createDefaultGrapgh() throws ComException { // create a new mediaControl // jniwrapper 2.x //mediaControl = FilgraphManager.create(new ClsCtx( // ClsCtx.CLSCTX_INPROC_SERVER)); // jniwrapper/comfyj 3.x mediaControl = FilgraphManager.create(ClsCtx.INPROC_SERVER); String URLString = mediaDescriptor.mediaURL; if (URLString.startsWith("file:") && !URLString.startsWith("file:///")) { URLString = URLString.substring(5); } IDispatch sourceDispatch = mediaControl.addSourceFilter(new BStr( URLString)); // remove code above if a new media control is not to be made IFilterInfoImpl filterInfo = new IFilterInfoImpl(); // the default filters IFilterInfoImpl fileSourceFI = new IFilterInfoImpl(); IFilterInfoImpl defaultSplitterFI = new IFilterInfoImpl(); IFilterInfoImpl videoDecoderFI = new IFilterInfoImpl(); IFilterInfoImpl audioDecoderFI = new IFilterInfoImpl(); IFilterInfoImpl videoRendererFI = new IFilterInfoImpl(); IFilterInfoImpl audioRendererFI = new IFilterInfoImpl(); IAMCollectionImpl splitterPinColl = new IAMCollectionImpl(); IPinInfoImpl pinInfo = new IPinInfoImpl(); IPinInfoImpl fileSourceOutputPinInfo = new IPinInfoImpl(); IAMCollectionImpl filterColl = new IAMCollectionImpl(); IAMCollectionImpl pinColl = new IAMCollectionImpl(); try { long nFilters; // get the default filters from the collection IRegFilterInfoImpl regFilterInfo = new IRegFilterInfoImpl(); mediaControl.getRegFilterCollection().queryInterface(filterColl.getIID(), filterColl); nFilters = filterColl.getCount().getValue(); for (int i = 0; i < nFilters; i++) { filterColl.item(new Int32(i)).queryInterface(regFilterInfo.getIID(), regFilterInfo); if (regFilterInfo.getName().getValue().equalsIgnoreCase("MPEG-I Stream Splitter")) { regFilterInfo.filter().queryInterface(defaultSplitterFI.getIID(), defaultSplitterFI); } else if (regFilterInfo.getName().getValue().equalsIgnoreCase("MPEG Video Decoder")) { regFilterInfo.filter().queryInterface(videoDecoderFI.getIID(), videoDecoderFI); } else if (regFilterInfo.getName().getValue().equalsIgnoreCase("MPEG Audio Decoder")) { regFilterInfo.filter().queryInterface(audioDecoderFI.getIID(), audioDecoderFI); } else if (regFilterInfo.getName().getValue().equalsIgnoreCase("Video Renderer")) { regFilterInfo.filter().queryInterface(videoRendererFI.getIID(), videoRendererFI); } else if (regFilterInfo.getName().getValue().equalsIgnoreCase("Default DirectSound Device")) { regFilterInfo.filter().queryInterface(audioRendererFI.getIID(), audioRendererFI); } } // get the sourcefile filter, with new mediaControl sourceDispatch.queryInterface(fileSourceFI.getIID(), fileSourceFI); System.out.println("New source filter: " + fileSourceFI.getName().getValue()); fileSourceFI.getPins().queryInterface(pinColl.getIID(), pinColl); pinColl.item(new Int32(0)).queryInterface(fileSourceOutputPinInfo.getIID(), fileSourceOutputPinInfo); /*// otherwise use this code mediaControl.getFilterCollection().queryInterface(filterColl.getIID(), filterColl); nFilters = filterColl.getCount().getValue(); System.out.println("Num filters: " + nFilters); 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 if (filterInfo.getIsFileSource().getValue() == DIRECT_SHOW_TRUE) { fileSourceFI = filterInfo; 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")) { // we have got the file source output pin pinColl.item(new Int32(j)).queryInterface(fileSourceOutputPinInfo.getIID(), fileSourceOutputPinInfo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -