问题:Swing程序VideoCatch直接运行可以获得视频设备列表,在WEB工程浏览器运行得到的视频列表却是空的?为什么啊?
输出信息:找不到视频采集设备
      没有符合要求的设备以下为代码:import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Panel;
import java.io.IOException;
import java.util.Vector;
import javax.media.*;
import javax.media.format.VideoFormat;
import javax.media.protocol.DataSource;
import javax.media.protocol.FileTypeDescriptor;
import javax.media.protocol.SourceCloneable;
import javax.swing.JButton;
import java.awt.*;
import java.applet.Applet;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class VideoCatch extends Applet implements ControllerListener,ActionListener
{
private CaptureDeviceInfo videoCapDevInfo = null;// 获取的摄像头信息
private MediaLocator videoCapDevLoc = null; // 从获取的摄像头信息中提取的摄像头地址
private DataSource datasource = null;// 原始的数据源
private Vector videoCapDevList = null; //捕获到的设备集合
private DataSource cloneabledatasource = null;// 由原始数据源转变成的,可以被克隆的数据源
private DataSource cloneddatasource = null;// 由可以克隆的数据源cloneabledatasource克隆出来的cloneddatasource
public  Player player = null;// 用来播放的player
private Processor processor = null;// 处理录制的视频的Processor
private DataSink dataSink = null;// 保存录制数据的数据池
private StateHelper sh = null;
private JButton Rec = null;// 录像按钮
private JButton stopRec = null;// 停止录像按钮
private JButton rePlay = null;// 重新播放
private JButton exit = null;// 退出
private JLabel tishi=null;
private String url=null;//视频文件地址
 private Component visualMedia=null; // 视频显示组件   
 private Component mediaControl=null; // 视频播放控制组件   
    public VideoCatch()
    {
     this.setLayout(new BorderLayout());
     Panel editor = new Panel();
     editor.setPreferredSize(new Dimension());
     editor.setLayout(null);
     Rec = new JButton("开始录像");
     Rec.addActionListener(this);
     stopRec = new JButton("停止录像");
     stopRec.addActionListener(this);
     rePlay = new JButton("播放录像");
     rePlay.addActionListener(this);
     exit=new JButton("退出");
     tishi=new JLabel("");
     tishi.setForeground(Color.red);
     exit.addActionListener(this);
     //调用initVideoCapDevLoc方法获得videoCapDevLoc(摄像头地址)
     videoCapDevLoc=initVideoCapDevLoc();
     //找不到设备,退出系统
     if(videoCapDevLoc==null)
     {
     System.out.println("没有符合要求的设备");
     System.exit(0);
     }
     try
     {
     datasource = Manager.createDataSource(videoCapDevLoc);
     cloneabledatasource = Manager.createCloneableDataSource(datasource);
     cloneddatasource = ((SourceCloneable) cloneabledatasource).createClone();
     player = Manager.createRealizedPlayer(cloneabledatasource);
     player.start();
     Component comp;
     if ((comp = player.getVisualComponent()) != null)
     {
     add("Center",comp);
     }
     Panel panel = new Panel(new GridLayout(5,1));
     panel.add(Rec);
     panel.add(stopRec);
     panel.add(rePlay);
     panel.add(exit);
     panel.add(tishi);
     add("East",panel);
     System.out.println(this);
    
     }
     catch (Exception e)
     {
     e.printStackTrace();
     }
    }
    
  //以下为捕获视频设备    public  MediaLocator initVideoCapDevLoc() {
        //这里可以填写其它的编码视频格式,具体请看VideoFormat类
        videoCapDevList = CaptureDeviceManager.getDeviceList(new VideoFormat(VideoFormat.RGB));        if ((videoCapDevList.size() > 0))
        {
            //或许有几个CaptureDevice,这里取第一个
            videoCapDevInfo = (CaptureDeviceInfo) videoCapDevList.elementAt(0);
            videoCapDevLoc = videoCapDevInfo.getLocator();
            return videoCapDevLoc;
        }
        else
        {
            System.out.println("找不到视频采集设备");
            return null;
        }
    } @Override
public void controllerUpdate(ControllerEvent arg0)
{
} @Override
public void actionPerformed(ActionEvent e)
{
// 区分按钮事件
JComponent c = (JComponent) e.getSource();
System.out.println(c);

// 如果单击了“开始录像”按钮,但是processor不为空,那么就弹出提示表明正在录像
if (c == Rec && processor != null)
{
JOptionPane.showMessageDialog(this, "正在录像!");
}
// 如果单击了“开始录像”按钮,且processor为空,那么就开始录像
else if (c == Rec && processor == null)
{

Frame saveRecframe = new Frame("保存视频文件");
FileDialog saveshipin = new FileDialog(saveRecframe, "保存视频文件",FileDialog.SAVE);
saveshipin.setFile("");
saveshipin.setVisible(true);
String savePath = saveshipin.getDirectory();
String saveName = saveshipin.getFile();
// 如果输入了保存名字(没有点取消)的话,才可运行
if (saveName != null) 
{
// 录像源代码
try 
{
// player用cloneabledatasource数据源,processor用cloneddatasource的数据源
processor = Manager.createProcessor(cloneddatasource);
sh = new StateHelper(processor);
} catch (IOException ez5) {
ez5.printStackTrace();
System.exit(-1);
} catch (NoProcessorException ez6) {
ez6.printStackTrace();
System.exit(-1);
}

// Configure the processor,让processor进入configured状态
if (!sh.configure(10000))
{
System.out.println("configure wrong!");
System.exit(-1);
}
/*
* if ( processor instanceof Processor) processor.configure();
*/
// 设置视频输出格式
processor.setContentDescriptor(new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME));
// realize the processor,让processor进入realized状态
if (!sh.realize(10000)) 
{
System.out.println("realize wrong!");
System.exit(-1);
}
// get the output of the processor,并且启动processor
DataSource outsource = processor.getDataOutput();
url=new java.lang.String("file:///" + savePath + saveName+".mov");
MediaLocator dest = new MediaLocator(url);
processor.start();

try
{
dataSink = Manager.createDataSink(outsource, dest);
dataSink.open();

catch (NoDataSinkException ez1) 
    {
ez1.printStackTrace();
System.exit(-1);

catch (IOException ez2)
{
ez2.printStackTrace();
System.exit(-1);
}
catch (SecurityException ez3) 
{
ez3.printStackTrace();
System.exit(-1);
}
try
{
dataSink.start();
tishi.setText("正在录像中...");
}
catch (IOException ez4) 
{
ez4.printStackTrace();
System.exit(-1);
}
}
}  
else if (c == stopRec && processor == null) 
{
JOptionPane.showMessageDialog(this, "你还没有开始录像!");
} else if (c == stopRec && processor != null) 
{
/*
* 如果要是能够连续录像,关键在于两点: 1 、重新设置cloneddatasource ,
* 我认为在cloneddatasource被调用后 , cloneddatasource被改变了 2、清空processor
*/
int choice=JOptionPane.showConfirmDialog(this, "确定要中断录像吗?");
if(choice==0)
{
tishi.setText("录像已停止!");
if(player.getVisualComponent()!=null)
{
this.remove(player.getVisualComponent());
}
player.close();
processor.close();
processor.deallocate();
dataSink.close();
cloneddatasource = ((SourceCloneable) cloneabledatasource).createClone();
processor = null;
}

}
else if(c==rePlay && processor!=null)
{
JOptionPane.showMessageDialog(this, "没有录像!");
}
else if(c==rePlay && processor==null)
{
try {

MediaLocator dest1 = new MediaLocator(url);
System.out.println(url);
player=Manager.createPlayer(dest1);
player.addControllerListener(new PlayerEventHandler()); //增加播放控制器   
   player.realize(); 
} catch (NoPlayerException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
player.start();

}
else if(c== exit && processor!=null)
{
JOptionPane.showMessageDialog(this, "正在录像中...");
}
else if(c== exit && processor==null)
{
System.exit(0);
}
}

 //取得媒体组件   
 public void getMediaComponents() {   
  visualMedia = player.getVisualComponent(); //取得视频显示组件   
  System.out.println(this+"1234");
  //如果对象visualMedia非空则加入到窗口内容窗格   
  if (visualMedia != null) {   
   this.add(visualMedia, BorderLayout.CENTER);   
   
  }   
  
  mediaControl = player.getControlPanelComponent(); //取得播放控制组件   
  
  //如果对象visualMedia非空则加入到窗口内容窗格   
  if (mediaControl != null)   
   this.add(mediaControl, BorderLayout.SOUTH);   
  
 }   

 //播放器事件处理   
 private class PlayerEventHandler extends ControllerAdapter
 {   
  
      public void realizeComplete(RealizeCompleteEvent realizeDoneEvent) {   
       player.prefetch(); //预取媒体数据   
      }   
      
      //完成预取媒体数据后,开始播放媒体   
      public void prefetchComplete(PrefetchCompleteEvent prefetchDoneEvent)
      {   
       getMediaComponents();   
       validate(); 
       System.out.println(123);
       player.start(); //开始播放媒体   
      }   
      
      //如果媒体播放完毕,重新设置媒体时间并停止媒体播放器   
      public void endOfMedia(EndOfMediaEvent mediaEndEvent) {   
       player.setMediaTime(new Time(0)); //重新设置媒体时间   
       player.stop(); // 停止媒体播放   
      }   
 }   }

解决方案 »

  1.   

    所有的包都放入了。。可是只要在WEB中启动这个程序,就获得不了设备!
      

  2.   

    楼主,你可以用ImageCapOnWeb解决这个问题。
    代码:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script language="javascript" type="text/javascript" src="../js/jquery-1.4.2.min.js" ></script>
    <script language="javascript" type="text/javascript" src="./ajax.js" ></script>
    </head><body>
    <form action="">
    <p>请选择服务器端技术:
      <label>
        <input type="radio" name="radio" id="jsp" value="jsp" />
      jsp</label>&nbsp;&nbsp;&nbsp;&nbsp;
      <label>
        <input type="radio" name="radio" id="aspnet" value="asp.net" />
      asp.net</label>&nbsp;&nbsp;&nbsp;&nbsp;
    </p>
    <p>
      <input type="button" value="启动摄像头" onclick="javascript:document.getElementById('cap1').start();"  /> 
      <input type="button" value="拍照" onclick="javascript:document.getElementById('cap1').cap();"  /> 
      <input type="button" value="ajax方式上传"  id="btnUpload1"/> 
    </p>
      <object classid="clsid:34681DB3-58E6-4512-86F2-9477F1A9F3D8" id="cap1" width="100%" height="600" codebase="../cabs/ImageCapOnWeb.cab#version=2,0,0,0">
        <param name="Visible" value="0">
        <param name="AutoScroll" value="0">
        <param name="AutoSize" value="0">
        <param name="AxBorderStyle" value="1">
        <param name="Caption" value="scaner">
        <param name="Color" value="4278190095">
        <param name="Font" value="宋体">
        <param name="KeyPreview" value="0">
        <param name="PixelsPerInch" value="96">
        <param name="PrintScale" value="1">
        <param name="Scaled" value="-1">
        <param name="DropTarget" value="0">
        <param name="HelpFile" value>
        <param name="PopupMode" value="0">
        <param name="ScreenSnap" value="0">
        <param name="SnapBuffer" value="10">
        <param name="DockSite" value="0">
        <param name="DoubleBuffered" value="0">
        <param name="ParentDoubleBuffered" value="0">
        <param name="UseDockManager" value="0">
        <param name="Enabled" value="-1">
        <param name="AlignWithMargins" value="0">
        <param name="ParentCustomHint" value="-1">
        <param name="key1" value="">
        <param name="key2" value="">   
      </object>
    </form>
    </body>
    </html>
    javascript代码:$(function() {
    $('#btnUpload1').click(function() {
    ajax_post_1();
    })
    });function getServerUrl(){
      if ($('#asp').attr("checked")==true) {
      return "./ajax.asp";
      }else if ($('#jsp').attr("checked")==true) {
      return "http://localhost:8080/pages/ajax.jsp";
      }else if ($('#php').attr("checked")==true) {
        return "./ajax.php";
     }else if ($('#aspnet').attr("checked")==true) {
     return "./ajax.aspx";
      } else{
          alert('请选择服务器端技术类型!');
      return null;
       }
    }
    function ajax_post_1() {
    var base64_data = document.getElementById('cap1').jpegBase64Data;
    alert("data length:"+base64_data.length);
    // var s=getServerUrl();
    // alert(s);
    $.ajax({
    url : getServerUrl(),
    type : 'POST',
    dataType : 'jason',
    data : {
    picData : "'" + base64_data + "'",
    picExt:".jpg"
    },
    timeout : 1000,
    success : callbackfun1
    });
    }
    function callbackfun1(data) {
    var obj = eval('(' + data + ')'); if ('ok' == obj.savestatus) {
    alert('success!');
    }}
    <%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*,java.io.*" errorPage="" %><%
      //注意一行html内容也不要出现,防止被编译为serlvet以后有写html到客户端的行为
    String savePath=config.getServletContext().getRealPath("/")+"//"; File tmp_path=new File(savePath);
    tmp_path.mkdirs();
    System.out.println("照片数据保存路径:"+savePath);String pic_base_64_data=request.getParameter("picData");
    //System.out.println("图片数据:"+pic_base_64_data);//如果下面的代码输出true则说明需要调整服务器软件工作参数,解决接受post数据的大小限制问题,例如
    //tomcat的话需要在server.xml中配置maxPostSize="0"来解除上传数据的大小限制   <Connector port="8080" protocol="HTTP/1.1" 
    //               connectionTimeout="20000" 
    //               redirectPort="8443" maxPostSize="0"/>
    // 
    System.out.println(null==pic_base_64_data);
    System.out.println("base64 string length:"+pic_base_64_data.length());
    String fileFormat=request.getParameter("picExt");
    sun.misc.BASE64Decoder decode=new sun.misc.BASE64Decoder();byte[] datas=decode.decodeBuffer(pic_base_64_data.substring(1, pic_base_64_data.length()-2));
    String filename=String.valueOf(System.currentTimeMillis())+fileFormat;
    File file=new File(savePath+filename);
    OutputStream fos=new FileOutputStream(file);
    System.out.println("照片文件名称:"+filename);
    fos.write(datas);
    fos.close();response.setContentType("application/x-json");
    response.setCharacterEncoding("utf-8");
    out.print("{'savestatus':'ok'}");
    out.flush();
    out.close();
    %>
    jsp摄像头拍照源码下载
      

  3.   

    6楼的朋友 谢谢 你了 。不知道ImageCapOnWeb可以实现摄像头录像不?