2010-10-28 35 views
13

Dự án hội nghị truyền hình tôi đang làm việc trên JMF đã sử dụng để quay video và âm thanh, và truyền nó đến điểm cuối khác. Một vấn đề là nhóm của tôi không muốn người dùng sản phẩm phải cài đặt JMF.Cách quay video bằng JMF, nhưng không cài đặt JMF

Tôi nghĩ có thể đáng để chia sẻ giải pháp của chúng tôi cho vấn đề này. Nó hoạt động. Nó hoạt động tốt. Câu hỏi của tôi đối với bạn là: có ai có cách nào tốt hơn để làm điều đó không?

Môi trường: Windows, XP trở lên

  1. Tải JMF cho Windows
  2. Cài đặt nó trên máy tính của bạn

  3. Xác định vị trí dll s sau trong thư mục system32 sau JMF cài đặt:

    jmacm.dll
    jmam.dll
    jmcvid.dll
    jmdaud.dll
    jmdaudc.dll
    jmddraw.dll
    jmfjawt.dll
    jmg723.dll
    jmgdi.dll
    jmgsm.dll
    jmh261.dll
    jmh263enc.dll
    jmjpeg.dll
    jmmci.dll
    jmmpa.dll
    jmmpegv.dll
    jmutil.dll
    jmvcm.dll
    jmvfw.dll
    jmvh263.dll
    jsound.dll

  4. Sao chép dll s vào một thư mục tạm thời

  5. Xác định vị trí các tập tin jmf.properties (Thực hiện tìm kiếm trên máy tính của bạn cho nó)
  6. Tải xuống mã nguồn JMF
    Trong mã nguồn, hãy tìm các tệp sau:

JMFinit.java
JMRPropertiesGen.java
Registry.java
RegistryGen.java

  1. Tạo gói; Tôi sẽ gọi nó JMFNoInstall
  2. Thêm các tập tin được liệt kê trong bước 6
  3. Thêm một lớp được gọi là Main để gói này như vậy:

 

package JMFNoInstall; 
// add your imports and whatnot here 
public class Main() 
{ 
    public Main() 
    { 
     JMFinit.main(null); 
     JMFPropertiesGen.main(null); 
     Registry.main(null); 
     RegistryGen.main(new String[] { 
      new File(".").getAbsolutePath(), 
      "registrylib" 
     }); 
    } 
} 

File jmf.properties cần phải đi trong cùng một thư mục với lớp có phương thức main hoặc cùng một thư mục với lưu trữ JAR chứa phương thức main.
Số dll cần phải đi vào thư mục win32. Bạn có thể kiểm tra chương trình của mình để xem chúng có nằm trong thư mục win32 hay không. Nếu không, bạn có thể sao chép chúng từ một số vị trí. Tệp jmf.properties được cập nhật bất cứ khi nào lớp học Main được liệt kê ở trên chạy. Bạn chỉ cần chạy ứng dụng này một lần, lần đầu tiên chương trình được chạy hoặc nếu người dùng muốn thêm thiết bị chụp mới. Cuối cùng, chỉ cần đảm bảo tệp jmf.jarjmfcom.jar đi kèm với bản tải xuống Windows JMF được bao gồm trong đường dẫn lớp. Bạn tốt để đi vào thời điểm này. Tất cả các chức năng của JMF mà không thực sự phải cài đặt nó.

Có thực sự không phải là rất nhiều công việc liên quan đến điều này, và bạn có thể kết hợp nó vào trình cài đặt tùy chỉnh của bạn khá dễ dàng.

Có ai tìm thấy cách tốt hơn để làm điều này không? Có một vài cạm bẫy khi làm theo cách này.

EDIT: Tôi nghĩ có thể đáng giá để chia sẻ một số mã mà tôi đã tạo. Tất nhiên bạn sẽ cần phải sửa đổi nó để xử lý những gì bạn. Nó chắc chắn sẽ không biên dịch, nhưng những thứ bị thiếu sẽ dễ dàng đủ để tạo lại. Nhưng nghĩ rằng nó có thể là một điểm khởi đầu tốt để giúp mọi người. Hàm detectCaptureDevices có lẽ sẽ giúp ích cho hầu hết mọi người. Ill cập nhật lớp này khi tôi đi.

 

import GUI.Window; 
import GlobalUtilities.OS; 
import GlobalUtilities.ProgressBar; 
import GlobalUtilities.FileUtilities; 
import java.io.File; 
import java.util.ArrayList; 
import java.util.Vector; 
import javax.swing.text.Utilities; 


/** 
* This class providex easy access to the most needed info about JMF. You can test 
* a JMF install (Windows only currently) and also get info about the captrue 
* devices hooked up to JMF. 
* @author dvargo 
*/ 
public class JMFRunner 
{ 
    /** 
    * Show the status of operations 
    */ 
    final ProgressBar theBar = new ProgressBar(); 
    /** 
    * Location where the dll's JMF relies on need to be placed 
    */ 
    final String windowsDllFolder = "C:\\WINDOWS\\system32\\"; 

    final String linuxDllFolder = "/usr/lib/"; 

    /** 
    * Dll's that JMF uses 
    */ 
    final String[] windowsDllList = new String[]{ 
     "jmacm.dll", 
     "jmam.dll", 
     "jmcvid.dll", 
     "jmdaud.dll", 
     "jmdaudc.dll", 
     "jmddraw.dll", 
     "jmfjawt.dll", 
     "jmg723.dll", 
     "jmgdi.dll", 
     "jmgsm.dll", 
     "jmh261.dll", 
     "jmh263enc.dll", 
     "jmjpeg.dll", 
     "jmmci.dll", 
     "jmmpa.dll", 
     "jmmpegv.dll", 
     "jmutil.dll", 
     "jmvcm.dll", 
     "jmvfw.dll", 
     "jmvh263.dll", 
     "jsound.dll"}; 

    String[] linuxDllList = new String[]{ 
     "libjmcvid.so", 
     "libjmdaud.so", 
     "libjmfjawt.so", 
     "libjmg723.so", 
     "libjmgsm.so", 
     "libjmh261.so", 
     "libjmh263enc.so", 
     "libjmjpeg.so", 
     "libjmmpa.so", 
     "libjmmpegv.so", 
     "libjmmpx.so", 
     "libjmutil.so", 
     "libjmv4l.so", 
     "libjmxlib.so" 
    }; 

    String [] dlls= null; 
    String dir = null; 

    /** 
    * List of the video capture devices found by JMF 
    */ 
    Vector videoDevices = null; 
    /** 
    * List of the audio capture devices found by JMF 
    */ 
    Vector audioDevices = null; 

    public JMFRunner() 
    { 
     if(OS.isWindows()) 
     { 
      dlls = windowsDllList; 
      dir = windowsDllFolder; 
     } 
     else if(OS.isLinux()) 
     { 
      dlls = linuxDllList; 
      dir = linuxDllFolder; 
     } 
     else 
     { 
      Window.getLogger().severe("Operating system does not support JMF"); 
     } 

    } 

    /** 
    * Adds new capture devices 
    */ 
    public void detectCaptureDecives() 
    { 


     Thread theTread = new Thread(theBar); 
     theTread.start(); 
     theBar.repaint(); 

     JMFInit.main(new String[] {""}); 
     JMFPropertiesGen.main(new String[] {""}); 
     Registry.main(new String[] {""}); 
     RegistryGen.main(new String[] {"-d", 
      new File(".").getAbsolutePath(), 
      "registrylib" 
     }); 

     theBar.setMessage(""); 
     theBar.stop(); 
    } 

    /** 
    * Verifies that all the dll's that JMF needs are in their correct spot 
    * @return True if all dlls are in their correct spot, false otherwise 
    */ 
    public boolean detectDlls() 
    { 
     boolean retVal = true; 
     String currFile; 
     for(String currDll : dlls) 
     { 
      currFile = dir + currDll; 
      if(! new File(currFile).exists()) 
      { 
       Window.getLogger().severe("Can not find dll " + currFile + " for JMF"); 
       retVal = false; 
      } 
     } 
     return retVal; 
    } 

    //Doesnt work quite yet 
    public boolean installLibraryFiles() 
    { 
     boolean retVal = true; 
     String currFile; 
     for(String currDll : dlls) 
     { 
      currFile = dir + currDll; 
      File newDll = new File(currFile); 
      //see if this dll is already there 
      if(!newDll.exists()) 
      { 
       //its not there so lets copy it 
       try 
       { 
        FileUtilities.copy(newDll,FileUtilities.getResourceFile("/JMFManager/Resources/"+currDll,currDll)); 
       } 
       catch(Exception e) 
       { 
        retVal = false; 
       } 
      } 
     } 
     return retVal; 
    } 

    /** 
    * Returns the location of the jmf.properties file that STix is using 
    * @return THe locaiton of the JMF properties 
    */ 
    public String getJMFPropertiesFileLocation() 
    { 
     return Registry.getJMFPropertiesFileLocation(); 
    } 

    /** 
    * Returns a list of the audio devices found by JMF 
    * @return Returns an Arraylist containing info about the audio capture devices 
    */ 
    public ArrayList getAudioDevices() 
    { 
     DeviceFinder df = new DeviceFinder(); 
     audioDevices = df.getSoundCaptureDevices(); 
     return new ArrayList(audioDevices); 
    } 

    /** 
    * Returns a list of the video decives deteced by JMF 
    * @return returns an arraylist with info of the video capture devices 
    */ 
    public ArrayList getVideoDevices() 
    { 
     DeviceFinder df = new DeviceFinder(); 
     videoDevices = df.getVideoCaptureDevices(); 
     return new ArrayList(videoDevices); 
    } 


    public static void main(String [] args) 
    { 
     JMFRunner x = new JMFRunner(); 
     //x.detectCaptureDecives(); 
     x.installLibraryFiles(); 
     System.out.println(x.detectDlls()); 
     System.out.println(x.getJMFPropertiesFileLocation()); 
     System.out.println(x.getAudioDevices()); 
     System.out.println(x.getVideoDevices()); 
    } 
} 
 

DeviceFinder.java

 

import java.util.Vector; 
import javax.media.*; 
import javax.media.format.*; 

/** 
* this class gets information about capture devices (mics and cameras) 
*/ 
public class DeviceFinder { 

    Vector videoDevices = new Vector(); 
    Vector audioDevices = new Vector(); 

    /** 
    * Constructor 
    * Creates a new DeviceFinder 
    */ 
    public DeviceFinder() 
    { 
     /*retrieve ALL video and audio devices*/ 
     videoDevices = CaptureDeviceManager.getDeviceList(new VideoFormat(null)); 
     audioDevices = CaptureDeviceManager.getDeviceList(new AudioFormat(null)); 
    } 

    /** 
    * purpose: Get information on all Video capture devices on the system 
    * @return java.util.Vector 
a vector of attributes */ public Vector getVideoCaptureDevices() { return videoDevices; } /** * purpose: Get information on all audio capture devices on the system * @return java.util.Vector
a vector of attributes */ public Vector getSoundCaptureDevices() { return audioDevices; } /** * retrieve the first video capture device */ public CaptureDeviceInfo getPrimaryVideoCaptureDevice() { return (CaptureDeviceInfo)videoDevices.get(0); } /*retrieve the first audio capture device*/ public CaptureDeviceInfo getPrimaryAudioCaptureDevice() { return (CaptureDeviceInfo)audioDevices.get(0); } /** * get the first video device name * @return String
the name of the video device */ public String getVideoCaptureDeviceName() { return ((CaptureDeviceInfo)videoDevices.get(0)).getName(); } /** * get the first audio device name * @return String
the name of the audio device */ public String getAudioCaptureDeviceName() { return ((CaptureDeviceInfo)audioDevices.get(0)).getName(); } /** * get the first video device media locator * @return MediaLocator */ public MediaLocator getVideoMediaLocator() { return ((CaptureDeviceInfo)videoDevices.get(0)).getLocator(); } /** * get the first audio device media locator * @return MediaLocator */ public MediaLocator getAudioMediaLocator() { return ((CaptureDeviceInfo)audioDevices.get(0)).getLocator(); } /** * get the video device media locator at index idx * @param idx index of the media locator (0 is the first/default, * as ordered by *
the JMFRegistry) * @return MediaLocator */ public MediaLocator getVideoMediaLocator(int idx) { if(idx >= videoDevices.size()) { return null; } return ((CaptureDeviceInfo)videoDevices.get(idx)).getLocator(); } /** * get the audio device media locator at index idx * @param idx index of the audio device (as ordered by the JMFRegistry) * @return MediaLocator */ public MediaLocator getAudioMediaLocator(int idx) { return ((CaptureDeviceInfo)audioDevices.get(idx)).getLocator(); } /** * * @param args */ public static void main(String[] args) { DeviceFinder df = new DeviceFinder(); //DEBUG: System.out.println(df.getVideoMediaLocator()); System.out.println(df.getAudioMediaLocator()); } }
+0

Sẽ là một ý tưởng tốt hơn để chia sẻ một số thông tin thêm về ví dụ này/mã mẫu và vài bước, tôi cũng đã thử tương tự. Và đã suy nghĩ để chuyển sang JMF hoặc truy cập Native? – YumYumYum

+1

@Stackfan Tôi đã thêm một số mã của tôi nếu giúp bất cứ ai – user489041

+0

@ user489041 Bạn nói "Các dll cần phải đi vào thư mục win32" bạn có nghĩa là 'system32'? – MikeNereson

Trả lời

4

Tôi không nghĩ rằng có một cách tốt hơn. Trừ khi các DLL được tải một cách rõ ràng bằng tên đường dẫn, bạn chỉ cần đảm bảo chúng nằm trong đường dẫn hệ thống, vì vậy nếu chúng sống ngay bên cạnh các tệp thực thi JVM, nó cũng sẽ hoạt động. Windows hoàn toàn bao gồm thư mục chương trình được bắt đầu từ trong đường dẫn hệ thống, vì vậy đó là một vị trí tiềm năng khác.

Trình cài đặt là thanh kiếm hai lưỡi, chúng giúp dễ dàng thêm chức năng mới và xóa nó sau này, nhưng chúng cũng làm cho việc triển khai các giải pháp sử dụng sản phẩm trở nên khó khăn hơn.

Một trong những điều tốt đẹp về Java nói chung là bạn không phải cài đặt nó để nó hoạt động. Về cơ bản, khi bạn thực hiện cài đặt JRE trên một hệ thống, bạn có thể gói nó lên và sử dụng nó trên một hệ thống khác dưới dạng tệp nén. Java không cần đăng ký một cách rõ ràng các DLL vì nó tải chúng một cách tự động khi cần thiết.

+1

Điều đó rất đúng. Mặt khác, JMF yêu cầu cài đặt. Đó chính xác là lý do mà bạn đã nói, "Một trong những điều tốt đẹp về Java nói chung là bạn không phải cài đặt nó để nó hoạt động." "Chúng tôi không muốn người dùng cuối phải cài đặt bất cứ thứ gì khác để ứng dụng của chúng tôi hoạt động. Điều này cũng rất đúng nếu ứng dụng đang chạy như một applet. Chúng tôi muốn chỉ có thể sao chép các tập tin đằng sau hậu trường và có mọi thứ hoạt động. Nó không phải là dễ dàng để thử cài đặt của JMF. Có rất nhiều thuộc tính được đặt đằng sau hậu trường. – user489041

Các vấn đề liên quan