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 private void detectCaptureDevices() { 107 // check if JavaSound capture is available 108 message("Looking for Audio capturer"); 109 Class<?> dsauto; 110 try { 111 dsauto = Class.forName("DirectSoundAuto"); 112 dsauto.getConstructor().newInstance(); 113 message("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 message("Finished detecting javasound capturer"); 127 } 128 catch (ThreadDeath td) { 129 throw td; 130 } 131 catch (Throwable t) { 132 message("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 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 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 private void message(String mesg) { 277 LOGGER.fine(mesg); 278 } 279 280 private void createGUI() { 281 TextArea textBox = new TextArea(5, 50); 282 add("Center", textBox); 283 textBox.setEditable(false); 284 addNotify(); 285 pack(); 286 287 int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize() 288 .getWidth(); 289 int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize() 290 .getHeight(); 291 292 setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2); 293 294 setVisible(visible); 295 296 } 297 298 public static void start(boolean visible) { 299 new JMFInit(null, visible); 300 } 301}