B/S架构的摄像头控制是完全可以的,小弟做过这个工作。附上源代码,有很多地方没有修改,不过绝对可以运行的,如果需要保存可以使用数字证书打包,

/**
  *
  */
 package com.etong.util.webVideo;

 import javax.swing.*;
 import java.io.*;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;

 import javax.media.*;
 import javax.media.format.*;
 import javax.media.util.*;
 import javax.media.control.*;

 import java.applet.Applet;
 import java.awt.*;
 import java.awt.image.*;
 import java.awt.event.*;

 import jmapps.util.*;

 import com.sun.image.codec.jpeg.*;
 import javax.media.protocol.DataSource;
 import java.applet.AppletContext;

 public class WebCang extends JApplet implements ActionListener {
     public static Player player = null;

     private CaptureDeviceInfo di = null;

     private MediaLocator ml = null;

     String insid = null;

     String taxpayerid = null;

     String affID = null;

     String affname = null;

     String wfid = null;

     String username = null;

     String host = null;

     String aid = null;

     String tid = null;

     int xx = 0;

     /**
      * 按钮
      */
     private JButton capture = null;

     /**
      * 按钮
      */
     private JButton save = null;

     private JButton open = null;

     private JButton close = null;

     private JTextField num = null;

     private Buffer buf = null;

     private Image img = null;

      private Image img2 = null;

     // private VideoFormat vf = null;
     private BufferToImage btoi = null;

     private ImagePanel imgpanel = null;

     /**
      * 选取x,y,width,height默值
      */
     private int rectX;

     private int rectY;

     private int rectWidth = 320;

     private int rectHeight = 240;

     private int imgWidth = 320;

     private int imgHeight = 240;


     /**
      * 默媳募
      */
     private String fname = "工作流附件程序";

     public void init() {
         insid = this.getParameter("insid");
         taxpayerid = this.getParameter("taxpayerid");
         affID = this.getParameter("affID");
         affname = this.getParameter("affname");
         wfid = this.getParameter("wfid");
         username = this.getParameter("username");
         host = this.getParameter("host");
         aid = this.getParameter("aid");
         tid = this.getParameter("tid");


         setLayout(new BorderLayout());
         setSize(320, 240);

         imgpanel = new ImagePanel();
         imgpanel.addMouseMotionListener(imgpanel);
         capture = new JButton("拍照");
         capture.addActionListener(this);
         save = new JButton("上传该附件");
         save.addActionListener(this);
         open = new JButton("打开拍照");
         open.addActionListener(this);
         close = new JButton("关闭拍照");
         close.addActionListener(this);
         //num = new JTextField();

         String str1 = "vfw:Logitech USB Video Camera:0";
         String str2 = "vfw:Microsoft WDM Image Capture (Win32):0";
         //从驱动管理器中获取驱动,一般使用MicroOS默认的驱动,str1为罗技的摄像头驱动
         di = CaptureDeviceManager.getDevice(str2);
         //获得本地媒体源
         ml = di.getLocator();
         try {
             //通过获取的本地源建立播放者对象
             DataSource dataSource;
             //player对象可以使用Manager.createRealizedPlayer(di.getLocator())直接构造,
             //player = Manager.createRealizedPlayer(di.getLocator());
             dataSource = JMFUtils.createCaptureDataSource(null, null, str2,
                     di.getFormats()[4]);
             //如果自行设置格式应当使用DataSource对象构建,其中DataSource对象位置为javax.media.protocol.DataSource;
             player = Manager.createRealizedPlayer(dataSource);
             //播放者开始播放
             player.start();
             Panel panelx2 = new Panel(new GridLayout(1, 2));
             Component comp;
             if ((comp = player.getVisualComponent()) != null) {
                 //增加播放源在窗口上
                 panelx2.add(comp);
                 comp.setSize(new Dimension(640, 480));
             }
             Panel panelx = new Panel(new GridLayout(1, 7));
             Panel panel1 = new Panel(new BorderLayout());
             panelx.add(new Panel());
             panelx.add(capture);
             panelx.add(new Panel());
             panelx.add(save);
             panelx.add(new Panel());
             panel1.add(new Label(), BorderLayout.WEST);
             //panel1.add(num, BorderLayout.CENTER);
             //panelx.add(open);
             panelx.add(close);
             panelx.add(new Panel());
             panel1.add(panelx2, BorderLayout.NORTH);
             panel1.add(panelx, BorderLayout.SOUTH);
             add(panel1, BorderLayout.CENTER);
             panelx2.add(imgpanel);
             //add(panelx2,BorderLayout.NORTH);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }

     public static void main(String[] args) throws ClassNotFoundException {

         try {
             URL url = new URL(
                     "http://webserver:7001/Workflow/servlet/WebCang");

             URLConnection urlConn = url.openConnection();
             urlConn.setUseCaches(false);
             urlConn.setDefaultUseCaches(false);

         } catch (MalformedURLException e1) {

             e1.printStackTrace();
         } catch (IOException e) {

             e.printStackTrace();
         }

     }
     /**
      * 乇头
      *
      */
     public static void playerclose() {
         player.close();
         player.deallocate();
     }

     /**
      *
      */
     public void actionPerformed(ActionEvent e) {
         JComponent c = (JComponent) e.getSource();
         if (c == capture) { // 抓取当前frame
             FrameGrabbingControl fgc = (FrameGrabbingControl) player
                                        .getControl(
                     "javax.media.control.FrameGrabbingControl");
             //public Control getControl(java.lang.String forName)获得由forName类型的control或接口interface
             
             
             buf = fgc.grabFrame();
             //public Buffer grabFrame(),获取当前祯
             
             
             btoi = new BufferToImage((VideoFormat) buf.getFormat());//转化流格式
             //public BufferToImage(VideoFormat format),为指定格式的图象变换对象实例化一个缓冲区
             
             img = btoi.createImage(buf); // 显示抓取图片
             //public java.awt.Image createImage(Buffer buffer),
             //将输入流转换成一个标准的AWT格式的图象,并且返回这个图象。
             
             imgpanel.setImage(img); // 设置imgpanel图片属性
             img2 = img;
             //new File("c:/load/WorkflowPhoto/temp.jpg").delete();
             JOptionPane.showMessageDialog(this,"拍照成功","操作提示",0);
         } else if (c == save) {
             if (img != null) {
                 //fname = !num.getText().equals("") ? num.getText() : "temp";
                 fname = "temp";
                 xx++;
                 saveJPG(img2, "c:/WorkflowPhoto/" , fname+ xx + ".jpg");
                 //WebCangFile.saveJPG(img,"f:/"+ fname + ".jpg");
             }
         }else if (c == close){
             player.close();
             JOptionPane.showMessageDialog(this,"拍照程序已经关闭,如需再次使用请关闭窗口,重新开启!","操作提示",0);
         }
     }
/**
      * 照片处理
      * @param imagePath
      * @param userName
      */
     public void creatMark(String imagePath, String userName) {
         ImageIcon imgIcon = new ImageIcon(imagePath);
         Image theImg = imgIcon.getImage();
         int width = theImg.getWidth(null);
         int height = theImg.getHeight(null) + 30;

         try {
             BufferedImage bimage = new BufferedImage(width, height,
                     BufferedImage.TYPE_INT_BGR);
             Graphics2D g = bimage.createGraphics();
             // 设置填充背景为白色
             g.setBackground(Color.DARK_GRAY);
             g.clearRect(0, 0, width, height);
             // 设置字体颜色
             g.setColor(Color.white);
             // 绘制指定图像的当前可用部分
             g.drawImage(theImg, 0, 15, null);

             SimpleDateFormat formatter_time = new SimpleDateFormat(
                     "yyyy-MM-dd hh:mm:ss");
             String up_time = formatter_time.format(new java.util.Date());

             // 使用该图形上下文的当前字体和颜色,绘制由指定的字符串给出的文本
             g.drawString(("本电子图片由" + userName + "于:" + up_time +
                           "上传,版权归属芜湖市国家税务局所有."), 10, 15); // 添加文字
             // 撤消该图形的上下文并释放它所使用的任何系统资源。在 dispose 方法被调用后, Graphics 对象将不能被使用
             g.dispose();

             // 图片输出
             FileOutputStream image_out = new FileOutputStream(imagePath); // "f:/deploy/Workflow/aa.jpg"
             JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(image_out);
             JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bimage);
             param.setQuality(50f, true);
             encoder.encode(bimage, param);
             image_out.close();
         } catch (Exception e) {
             e.printStackTrace();
         }
     }

     /**
       * 将byte数组转换为表示16进制值的字符串
       * 和public static String hexStr2ByteArr(String strIn)
       * 互为可逆的转换过程
       * @param bytes 需要转换的byte数组
       * @return 转换后的字符串
       * @throws Exception 本方法不处理任何异常,所有异常全部抛出
       * @author <a href="mailto:c_r_zhu@hotmail.com">PeterZhu</a>
       */
      public static final String encodeHex(byte[] bytes) {
                  StringBuffer buf = new StringBuffer(bytes.length * 2);
                  int i;

                  for (i = 0; i < bytes.length; i++) {
                          if (((int) bytes[i] & 0xff) < 0x10) {
                                  buf.append("0");
                          }
                          buf.append(Long.toString((int) bytes[i] & 0xff, 16));
                  }
                  return buf.toString();
          }
      
      /**
       * 将表示16进制值的字符串转换为byte数组,
       * 和public static String encodeHex(byte[] arrB)
       * 互为可逆的转换过程
       * @param strIn 需要转换的字符串
       * @return 转换后的byte数组
       * @throws Exception 本方法不处理任何异常,所有异常全部抛出
       * @author <a href="mailto:c_r_zhu@hotmail.com">PeterZhu</a>
       */
      public static byte[] hexStr2ByteArr(String strIn)
          throws Exception
      {
          byte[] arrB = strIn.getBytes();
          int iLen = arrB.length;

    //两个字符表示一个字节,所以字节数组长度是字符串长度除以2
          byte[] arrOut = new byte[iLen / 2];
          for (int i = 0; i < iLen; i = i + 2)
          {
              String strTmp = new String(arrB, i, 2);
              arrOut[i / 2] = (byte) Integer.parseInt(strTmp, 16);
          }
          return arrOut;
      }


/**
      * 图
      * @param img
      * @param s:filePath
      */
     public void saveJPG(Image img, String s,String filename) {
        
 //    img=getImage(null,"1.jpg");
        final int INTWIDTH=800;
        final int INTHEIGHT=600;
        BufferedImage bi = (BufferedImage) createImage(INTWIDTH,
                 INTHEIGHT);
        
 //       BufferedImage bi=(BufferedImage)createImage(img.getWidth(null),
 //        img.getHeight(null));
        
        File filedir = new File(s);
         if (!filedir.exists()) {
                  filedir.mkdirs(); //新建目录
         }
         System.out.println("ghf----" + img.getWidth(null) + "    hgf----" +
                            img.getHeight(null));
         Graphics g = bi.createGraphics();
         g.drawImage(img,0,0,INTWIDTH,INTHEIGHT,null);
 //        Graphics2D g2 = bi.createGraphics();
 //        g2.drawImage(img, null, null);

         //图像输出,保存部分
         //File f = new File(s+filename);
         //if (f.exists()){
         //new File(s+filename).delete();
         //}
         FileOutputStream out = null;
         try {
             System.out.println("filename----------------"+s+filename);
             out = new FileOutputStream(new File(s+filename));
         } catch (java.io.FileNotFoundException io) {
             System.out.println("File Not Found");
         }
         JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
         JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(bi);
         param.setQuality(1f, false);
         encoder.setJPEGEncodeParam(param);
         try {
             encoder.encode(bi);
             out.close();
             creatMark(s+filename, username);
         } catch (java.io.IOException io) {
             System.out.println("IOException");
         }
         /*AppletContext ac = getAppletContext();
         try {
             ac.showDocument(new URL(
                     "http://webserver:7001/Workflow/custom/public/affiliatedInfo_upload_main.jsp?"
                     + "ls_workflow_type=affupload&"
                     + "ls_wfid=b120&"
                     + "li_insid=134020000006559&"
                     + "ls_taxpayerID=340211790123101&"
                     + "ls_affID=FB-0001&"
                     + "ls_affName=aaaaaaaaaaaaa&"
                     + "path=" + s));
         } catch (MalformedURLException ex) {
             ex.printStackTrace();
         }*/

     String filestr ="" ;
     File file = new File(s+filename);
     FileInputStream fin = null;
     try {
         fin = new FileInputStream(file);
     } catch (FileNotFoundException ex) {
     }
     byte[] byt = new byte[4096];
     int bb;
     try {
         while ((bb = fin.read(byt, 0, 4096)) != -1) {
             filestr = filestr + encodeHex(byt);
         }
     } catch (IOException ex1) {
     }

     //"http://webserver:7001/Workflow
    System.out.println("host---------------------"+host);
         try {
             java.net.URL url = new java.net.URL(host+"/servlet/WebCang_servlet?insid="
                     + insid +"&affID="
                     + affID +"&affName="
                     + affname +"&filestr="
                     +filestr);
             java.net.URLConnection con = url.openConnection();
             con.setUseCaches(true);
             con.setDoOutput(true);
             con.setDoInput(true);
             //con.setRequestProperty("Content-type", "application/octest-stream");
             /*FileInputStream fin = null;
             File file = new File(s);
             fin = new FileInputStream(file);
             System.out.println("fin.available()------------"+fin.available());
             DataOutputStream dataout = new DataOutputStream(con.getOutputStream());
             int bytesRead = 0;
             byte[] buffer = new byte[8192];
             while ((bytesRead = fin.read(buffer, 0, 8192)) != -1) { 
                 dataout.write(buffer, 0, bytesRead); //将文件写入Stream
             }*/
             DataOutputStream dataout = new DataOutputStream(con.getOutputStream());
             dataout.flush();
             dataout.close();
             System.out.println(dataout.size());
             DataInputStream in = new DataInputStream(con.getInputStream());
             in.close();
             filedir.delete();
             JOptionPane.showMessageDialog(this,"照片上传成功","操作提示",0);
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
 }/以上来自网络论坛

五一回来了,呵呵。好久不上Blog,居然有排名了^_^.
      下面是一段利用JMF从摄像头捕获视频的代码,也是从其它地方当下来的,我修改了一些地方,测试时效果还可以,可以显示捕获的视频(与JMF Studio的部分功能类似,但是很简单),但是还没有实现导出数据的功能。
       正常运行程序,需要保证摄像头的驱动正常安装,并在JMF中注册过,具体的方法参见前面的一篇转贴。要注意一点:String类的url是摄像头的url,具体的名称可以在JMF Registry中看到。代码贴出如下:
import javax.media.*;
  import java.io.*;
  import java.awt.*; class CaptureVideo extends Frame implements ControllerListener {
       
        private CaptureDeviceInfo infor ;
        private MediaLocator mediaLocator ;
        private String url = "vfw:Microsoft WDM Image Capture (Win32):0";
        private Component com;
        private Panel panel ;
      
        Player player;        public CaptureVideo() {
               infor = CaptureDeviceManager.getDevice(url);
               mediaLocator = infor.getLocator();
              
        }       public void play() {
               try {
                      player = Manager.createPlayer(mediaLocator);//利用mediaLocator创建Player
                      player.addControllerListener(this);
                      player.realize();
                      
                     // System.out.println("infor:"+infor);
                     // System.out.println("mediaLocator:"+mediaLocator);
               } catch (NoPlayerException e) {
                      // TODO 自动生成 catch 块
                      e.printStackTrace();
               } catch (IOException e) {
                      // TODO 自动生成 catch 块
                      e.printStackTrace();
               }
        }       public void createComponent() {
               setTitle("视频信号");
       //        addWindowListener(new WinClose());              setBounds(100,100,200,200);
               panel = new Panel();
               
               if((com = player.getVisualComponent()) != null) {
                      panel.add(com);
               }
               add(panel);
               setVisible(true);
        }       public synchronized void controllerUpdate(ControllerEvent arg0) {
               // TODO 自动生成方法存根
               if(arg0 instanceof RealizeCompleteEvent) {
                      System.out.println("realized");
                      createComponent();                 //将播放器添加到Panel上
                      player.prefetch();              }
               if(arg0 instanceof PrefetchCompleteEvent) {
                      player.start();
                      System.out.println("prefetched");
               }
        }
        
        public static void main(String[] arg0) {
            CaptureVideo video = new CaptureVideo();
            video.play();
            
        }}