001/** 002 * 003 * Copyright the original author or authors 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.jivesoftware.smackx.jingleold.mediaimpl; 018 019import java.awt.Frame; 020import java.util.Vector; 021import java.util.logging.Logger; 022 023import javax.media.Format; 024import javax.media.PlugInManager; 025import javax.media.Renderer; 026import javax.media.format.AudioFormat; 027 028import com.sun.media.ExclusiveUse; 029import com.sun.media.util.Registry; 030 031@SuppressWarnings("UnusedVariable") 032public class JMFInit extends Frame implements Runnable { 033 034 private static final long serialVersionUID = 6476412003260641680L; 035 036 private static final Logger LOGGER = Logger.getLogger(JMFInit.class.getName()); 037 038 private String tempDir = "/tmp"; 039 040 private boolean done = false; 041 042 private String userHome; 043 044 private boolean visible = false; 045 046 public JMFInit(String[] args, boolean visible) { 047 super("Initializing JMF..."); 048 049 this.visible = visible; 050 051 Registry.set("secure.allowCaptureFromApplets", true); 052 Registry.set("secure.allowSaveFileFromApplets", true); 053 054 updateTemp(args); 055 056 try { 057 Registry.commit(); 058 } 059 catch (Exception e) { 060 061 LOGGER.fine("Failed to commit to JMFRegistry!"); 062 } 063 064 Thread detectThread = new Thread(this); 065 detectThread.run(); 066 067 /* 068 * int slept = 0; while (!done && slept < 60 * 1000 * 2) { try { 069 * Thread.currentThread().sleep(500); } catch (InterruptedException ie) { } 070 * slept += 500; } 071 * 072 * if (!done) { console.error("Detection is taking too long! 073 * Aborting!"); message("Detection is taking too long! Aborting!"); } 074 * 075 * try { Thread.currentThread().sleep(2000); } catch 076 * (InterruptedException ie) { } 077 */ 078 } 079 080 @Override 081 public void run() { 082 detectDirectAudio(); 083 detectS8DirectAudio(); 084 detectCaptureDevices(); 085 done = true; 086 } 087 088 private void updateTemp(String[] args) { 089 if (args != null && args.length > 0) { 090 tempDir = args[0]; 091 092 LOGGER.fine("Setting cache directory to " + tempDir); 093 try { 094 Registry.set("secure.cacheDir", tempDir); 095 Registry.commit(); 096 097 LOGGER.fine("Updated registry"); 098 } 099 catch (Exception e) { 100 LOGGER.fine("Couldn't update registry!"); 101 } 102 } 103 } 104 105 @SuppressWarnings("LiteralClassName") 106 private static void detectCaptureDevices() { 107 // check if JavaSound capture is available 108 LOGGER.fine("Looking for Audio capturer"); 109 Class<?> dsauto; 110 try { 111 dsauto = Class.forName("DirectSoundAuto"); 112 dsauto.getConstructor().newInstance(); 113 LOGGER.fine("Finished detecting DirectSound capturer"); 114 } 115 catch (ThreadDeath td) { 116 throw td; 117 } 118 catch (Throwable t) { 119 // Do nothing. 120 } 121 122 Class<?> jsauto; 123 try { 124 jsauto = Class.forName("JavaSoundAuto"); 125 jsauto.getConstructor().newInstance(); 126 LOGGER.fine("Finished detecting javasound capturer"); 127 } 128 catch (ThreadDeath td) { 129 throw td; 130 } 131 catch (Throwable t) { 132 LOGGER.fine("JavaSound capturer detection failed!"); 133 } 134 135 /* 136 // Check if VFWAuto or SunVideoAuto is available 137 message("Looking for video capture devices"); 138 Class auto = null; 139 Class autoPlus = null; 140 try { 141 auto = Class.forName("VFWAuto"); 142 } 143 catch (Exception e) { 144 } 145 if (auto == null) { 146 try { 147 auto = Class.forName("SunVideoAuto"); 148 } 149 catch (Exception ee) { 150 151 } 152 try { 153 autoPlus = Class.forName("SunVideoPlusAuto"); 154 } 155 catch (Exception ee) { 156 157 } 158 } 159 if (auto == null) { 160 try { 161 auto = Class.forName("V4LAuto"); 162 } 163 catch (Exception ee) { 164 165 } 166 } 167 try { 168 Object instance = auto.newInstance(); 169 if (autoPlus != null) { 170 Object instancePlus = autoPlus.newInstance(); 171 } 172 173 message("Finished detecting video capture devices"); 174 } 175 catch (ThreadDeath td) { 176 throw td; 177 } 178 catch (Throwable t) { 179 180 message("Capture device detection failed!"); 181 } 182 */ 183 } 184 185 private static void detectDirectAudio() { 186 Class<?> cls; 187 int plType = PlugInManager.RENDERER; 188 String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; 189 try { 190 // Check if this is the Windows Performance Pack - hack 191 cls = Class.forName("VFWAuto"); 192 // Check if DS capture is supported, otherwise fail DS renderer 193 // since NT doesn't have capture 194 cls = Class.forName("com.sun.media.protocol.dsound.DSound"); 195 // Find the renderer class and instantiate it. 196 cls = Class.forName(dar); 197 198 Renderer rend = (Renderer) cls.getConstructor().newInstance(); 199 try { 200 // Set the format and open the device 201 AudioFormat af = new AudioFormat(AudioFormat.LINEAR, 44100, 16, 202 2); 203 rend.setInputFormat(af); 204 rend.open(); 205 Format[] inputFormats = rend.getSupportedInputFormats(); 206 // Register the device 207 PlugInManager.addPlugIn(dar, inputFormats, new Format[0], 208 plType); 209 // Move it to the top of the list 210 @SuppressWarnings("unchecked") 211 Vector<String> rendList = PlugInManager.getPlugInList(null, null, 212 plType); 213 int listSize = rendList.size(); 214 if (rendList.elementAt(listSize - 1).equals(dar)) { 215 rendList.removeElementAt(listSize - 1); 216 rendList.insertElementAt(dar, 0); 217 PlugInManager.setPlugInList(rendList, plType); 218 PlugInManager.commit(); 219 // Log.debug("registered"); 220 } 221 rend.close(); 222 } 223 catch (Throwable t) { 224 // Log.debug("Error " + t); 225 } 226 } 227 catch (Throwable tt) { 228 // Do nothing. 229 } 230 } 231 232 private static void detectS8DirectAudio() { 233 Class<?> cls; 234 int plType = PlugInManager.RENDERER; 235 String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; 236 try { 237 // Check if this is the solaris Performance Pack - hack 238 cls = Class.forName("SunVideoAuto"); 239 240 // Find the renderer class and instantiate it. 241 cls = Class.forName(dar); 242 243 Renderer rend = (Renderer) cls.getConstructor().newInstance(); 244 245 if (rend instanceof ExclusiveUse 246 && !((ExclusiveUse) rend).isExclusive()) { 247 // sol8+, DAR supports mixing 248 @SuppressWarnings("unchecked") 249 Vector<String> rendList = PlugInManager.getPlugInList(null, null, 250 plType); 251 int listSize = rendList.size(); 252 boolean found = false; 253 String rname; 254 255 for (int i = 0; i < listSize; i++) { 256 rname = rendList.elementAt(i); 257 if (rname.equals(dar)) { // DAR is in the registry 258 found = true; 259 rendList.removeElementAt(i); 260 break; 261 } 262 } 263 264 if (found) { 265 rendList.insertElementAt(dar, 0); 266 PlugInManager.setPlugInList(rendList, plType); 267 PlugInManager.commit(); 268 } 269 } 270 } 271 catch (Throwable tt) { 272 // Do nothing. 273 } 274 } 275 276 public static void start(boolean visible) { 277 new JMFInit(null, visible); 278 } 279}