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.jingle.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 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 message("Setting cache directory to " + tempDir); 093 Registry r = new Registry(); 094 try { 095 r.set("secure.cacheDir", tempDir); 096 r.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.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.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.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 Vector<String> rendList = PlugInManager.getPlugInList(null, null, 211 plType); 212 int listSize = rendList.size(); 213 if (rendList.elementAt(listSize - 1).equals(dar)) { 214 rendList.removeElementAt(listSize - 1); 215 rendList.insertElementAt(dar, 0); 216 PlugInManager.setPlugInList(rendList, plType); 217 PlugInManager.commit(); 218 // Log.debug("registered"); 219 } 220 rend.close(); 221 } 222 catch (Throwable t) { 223 // Log.debug("Error " + t); 224 } 225 } 226 catch (Throwable tt) { 227 //Do nothing 228 } 229 } 230 231 private void detectS8DirectAudio() { 232 Class<?> cls; 233 int plType = PlugInManager.RENDERER; 234 String dar = "com.sun.media.renderer.audio.DirectAudioRenderer"; 235 try { 236 // Check if this is the solaris Performance Pack - hack 237 cls = Class.forName("SunVideoAuto"); 238 239 // Find the renderer class and instantiate it. 240 cls = Class.forName(dar); 241 242 Renderer rend = (Renderer) cls.newInstance(); 243 244 if (rend instanceof ExclusiveUse 245 && !((ExclusiveUse) rend).isExclusive()) { 246 // sol8+, DAR supports mixing 247 Vector<String> rendList = PlugInManager.getPlugInList(null, null, 248 plType); 249 int listSize = rendList.size(); 250 boolean found = false; 251 String rname = null; 252 253 for (int i = 0; i < listSize; i++) { 254 rname = (String) (rendList.elementAt(i)); 255 if (rname.equals(dar)) { // DAR is in the registry 256 found = true; 257 rendList.removeElementAt(i); 258 break; 259 } 260 } 261 262 if (found) { 263 rendList.insertElementAt(dar, 0); 264 PlugInManager.setPlugInList(rendList, plType); 265 PlugInManager.commit(); 266 } 267 } 268 } 269 catch (Throwable tt) { 270 //Do nothing 271 } 272 } 273 274 private void message(String mesg) { 275 LOGGER.fine(mesg); 276 } 277 278 private void createGUI() { 279 TextArea textBox = new TextArea(5, 50); 280 add("Center", textBox); 281 textBox.setEditable(false); 282 addNotify(); 283 pack(); 284 285 int scrWidth = (int) Toolkit.getDefaultToolkit().getScreenSize() 286 .getWidth(); 287 int scrHeight = (int) Toolkit.getDefaultToolkit().getScreenSize() 288 .getHeight(); 289 290 setLocation((scrWidth - getWidth()) / 2, (scrHeight - getHeight()) / 2); 291 292 setVisible(visible); 293 294 } 295 296 public static void start(boolean visible) { 297 new JMFInit(null, visible); 298 } 299}