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 @SuppressWarnings({"this-escape", "DoNotCall"}) 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 LOGGER.fine("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 LOGGER.fine("Setting cache directory to " + tempDir); 094 try { 095 Registry.set("secure.cacheDir", tempDir); 096 Registry.commit(); 097 098 LOGGER.fine("Updated registry"); 099 } 100 catch (Exception e) { 101 LOGGER.fine("Couldn't update registry!"); 102 } 103 } 104 } 105 106 @SuppressWarnings("LiteralClassName") 107 private static void detectCaptureDevices() { 108 // check if JavaSound capture is available 109 LOGGER.fine("Looking for Audio capturer"); 110 Class<?> dsauto; 111 try { 112 dsauto = Class.forName("DirectSoundAuto"); 113 dsauto.getConstructor().newInstance(); 114 LOGGER.fine("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 LOGGER.fine("Finished detecting javasound capturer"); 128 } 129 catch (ThreadDeath td) { 130 throw td; 131 } 132 catch (Throwable t) { 133 LOGGER.fine("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 static 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 static 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 public static void start(boolean visible) { 278 new JMFInit(null, visible); 279 } 280}