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.awt.TextArea; 021import java.awt.Toolkit; 022import java.util.Vector; 023import java.util.logging.Logger; 024 025import javax.media.Format; 026import javax.media.PlugInManager; 027import javax.media.Renderer; 028import javax.media.format.AudioFormat; 029 030import com.sun.media.ExclusiveUse; 031import com.sun.media.util.Registry; 032 033public class JMFInit extends Frame implements Runnable { 034 035 private static final long serialVersionUID = 6476412003260641680L; 036 037 private static final Logger LOGGER = Logger.getLogger(JMFInit.class.getName()); 038 039 private String tempDir = "/tmp"; 040 041 private boolean done = false; 042 043 private String userHome; 044 045 private boolean visible = false; 046 047 public JMFInit(String[] args, boolean visible) { 048 super("Initializing JMF..."); 049 050 this.visible = visible; 051 052 Registry.set("secure.allowCaptureFromApplets", true); 053 Registry.set("secure.allowSaveFileFromApplets", true); 054 055 updateTemp(args); 056 057 try { 058 Registry.commit(); 059 } 060 catch (Exception e) { 061 062 message("Failed to commit to JMFRegistry!"); 063 } 064 065 Thread detectThread = new Thread(this); 066 detectThread.run(); 067 068 /* 069 * int slept = 0; while (!done && slept < 60 * 1000 * 2) { try { 070 * Thread.currentThread().sleep(500); } catch (InterruptedException ie) { } 071 * slept += 500; } 072 * 073 * if (!done) { console.error("Detection is taking too long! 074 * Aborting!"); message("Detection is taking too long! Aborting!"); } 075 * 076 * try { Thread.currentThread().sleep(2000); } catch 077 * (InterruptedException ie) { } 078 */ 079 } 080 081 @Override 082 public void run() { 083 detectDirectAudio(); 084 detectS8DirectAudio(); 085 detectCaptureDevices(); 086 done = true; 087 } 088 089 private void updateTemp(String[] args) { 090 if (args != null && args.length > 0) { 091 tempDir = args[0]; 092 093 message("Setting cache directory to " + tempDir); 094 try { 095 Registry.set("secure.cacheDir", tempDir); 096 Registry.commit(); 097 098 message("Updated registry"); 099 } 100 catch (Exception e) { 101 message("Couldn't update registry!"); 102 } 103 } 104 } 105 106 @SuppressWarnings("LiteralClassName") 107 private void detectCaptureDevices() { 108 // check if JavaSound capture is available 109 message("Looking for Audio capturer"); 110 Class<?> dsauto; 111 try { 112 dsauto = Class.forName("DirectSoundAuto"); 113 dsauto.getConstructor().newInstance(); 114 message("Finished detecting DirectSound capturer"); 115 } 116 catch (ThreadDeath td) { 117 throw td; 118 } 119 catch (Throwable t) { 120 // Do nothing. 121 } 122 123 Class<?> jsauto; 124 try { 125 jsauto = Class.forName("JavaSoundAuto"); 126 jsauto.getConstructor().newInstance(); 127 message("Finished detecting javasound capturer"); 128 } 129 catch (ThreadDeath td) { 130 throw td; 131 } 132 catch (Throwable t) { 133 message("JavaSound capturer detection failed!"); 134 } 135 136 /* 137 // Check if VFWAuto or SunVideoAuto is available 138 message("Looking for video capture devices"); 139 Class auto = null; 140 Class autoPlus = null; 141 try { 142 auto = Class.forName("VFWAuto"); 143 } 144 catch (Exception e) { 145 } 146 if (auto == null) { 147 try { 148 auto = Class.forName("SunVideoAuto"); 149 } 150 catch (Exception ee) { 151 152 } 153 try { 154 autoPlus = Class.forName("SunVideoPlusAuto"); 155 } 156 catch (Exception ee) { 157 158 } 159 } 160 if (auto == null) { 161 try { 162 auto = Class.forName("V4LAuto"); 163 } 164 catch (Exception ee) { 165 166 } 167 } 168 try { 169 Object instance = auto.newInstance(); 170 if (autoPlus != null) { 171 Object instancePlus = autoPlus.newInstance(); 172 } 173 174 message("Finished detecting video capture devices"); 175 } 176 catch (ThreadDeath td) { 177 throw td; 178 } 179 catch (Throwable t) { 180 181 message("Capture device detection failed!"); 182 } 183 */ 184 } 185 186 private void detectDirectAudio() { 187 Class<?> cls; 188 int plType = PlugInManager.RENDERER; 189 String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; 190 try { 191 // Check if this is the Windows Performance Pack - hack 192 cls = Class.forName("VFWAuto"); 193 // Check if DS capture is supported, otherwise fail DS renderer 194 // since NT doesn't have capture 195 cls = Class.forName("com.sun.media.protocol.dsound.DSound"); 196 // Find the renderer class and instantiate it. 197 cls = Class.forName(dar); 198 199 Renderer rend = (Renderer) cls.getConstructor().newInstance(); 200 try { 201 // Set the format and open the device 202 AudioFormat af = new AudioFormat(AudioFormat.LINEAR, 44100, 16, 203 2); 204 rend.setInputFormat(af); 205 rend.open(); 206 Format[] inputFormats = rend.getSupportedInputFormats(); 207 // Register the device 208 PlugInManager.addPlugIn(dar, inputFormats, new Format[0], 209 plType); 210 // Move it to the top of the list 211 @SuppressWarnings("unchecked") 212 Vector<String> rendList = PlugInManager.getPlugInList(null, null, 213 plType); 214 int listSize = rendList.size(); 215 if (rendList.elementAt(listSize - 1).equals(dar)) { 216 rendList.removeElementAt(listSize - 1); 217 rendList.insertElementAt(dar, 0); 218 PlugInManager.setPlugInList(rendList, plType); 219 PlugInManager.commit(); 220 // Log.debug("registered"); 221 } 222 rend.close(); 223 } 224 catch (Throwable t) { 225 // Log.debug("Error " + t); 226 } 227 } 228 catch (Throwable tt) { 229 // Do nothing. 230 } 231 } 232 233 private void detectS8DirectAudio() { 234 Class<?> cls; 235 int plType = PlugInManager.RENDERER; 236 String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; 237 try { 238 // Check if this is the solaris Performance Pack - hack 239 cls = Class.forName("SunVideoAuto"); 240 241 // Find the renderer class and instantiate it. 242 cls = Class.forName(dar); 243 244 Renderer rend = (Renderer) cls.getConstructor().newInstance(); 245 246 if (rend instanceof ExclusiveUse 247 && !((ExclusiveUse) rend).isExclusive()) { 248 // sol8+, DAR supports mixing 249 @SuppressWarnings("unchecked") 250 Vector<String> rendList = PlugInManager.getPlugInList(null, null, 251 plType); 252 int listSize = rendList.size(); 253 boolean found = false; 254 String rname; 255 256 for (int i = 0; i < listSize; i++) { 257 rname = rendList.elementAt(i); 258 if (rname.equals(dar)) { // DAR is in the registry 259 found = true; 260 rendList.removeElementAt(i); 261 break; 262 } 263 } 264 265 if (found) { 266 rendList.insertElementAt(dar, 0); 267 PlugInManager.setPlugInList(rendList, plType); 268 PlugInManager.commit(); 269 } 270 } 271 } 272 catch (Throwable tt) { 273 // Do nothing. 274 } 275 } 276 277 private void message(String mesg) { 278 LOGGER.fine(mesg); 279 } 280 281 private void createGUI() { 282 TextArea textBox = new TextArea(5, 50); 283 add("Center", textBox); 284 textBox.setEditable(false); 285 addNotify(); 286 pack(); 287 288 int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize() 289 .getWidth(); 290 int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize() 291 .getHeight(); 292 293 setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2); 294 295 setVisible(visible); 296 297 } 298 299 public static void start(boolean visible) { 300 new JMFInit(null, visible); 301 } 302}