RecordVideo.java

package org.bruce.myown_product; import java.awt.BorderLayout; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.util.Vector; import javax.media.CaptureDeviceInfo; import javax.media.CaptureDeviceManager; import javax.media.DataSink; import javax.media.Format; import javax.media.Manager; import javax.media.MediaLocator; import javax.media.Player; import javax.media.Processor; import javax.media.ProcessorModel; import javax.media.control.FormatControl; 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 javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JOptionPane; import javax.swing.JPanel; // 这是我自己改写的一个示例,实现了简单的录制和再次录制功能! public class RecordVideo extends JFrame { private static final long serialVersionUID = -2570548473293856129L; private CaptureDeviceInfo captureDevice; private MediaLocator mediaLocator; private Component visualComponent; private Processor processor; private Player player; private DataSource source; private DataSource cloneableSource; private DataSource clonedDataSource; private DataSink dataSink; private JPanel videoPanel = new JPanel(new BorderLayout()); private JPanel controlPanel = new JPanel(); private JPanel contentPane; private JButton btnStart; private JButton btnStop; private JFileChooser fileChooser = new JFileChooser(); public RecordVideo() { this.setTitle("视频采集软件"); contentPane = (JPanel) this.getContentPane(); btnStart = new JButton("开始采集"); btnStart.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { start(); } }); btnStop = new JButton("停止采集"); btnStop.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { stop(); } }); btnStop.setEnabled(false); controlPanel.add(btnStart); controlPanel.add(btnStop); contentPane.add("South", controlPanel); this.captureDevice = this.getCaptureDeviceInfo(); try { mediaLocator = captureDevice.getLocator(); source = Manager.createDataSource(mediaLocator); // 在调用 createCloneableDataSource(source) 方法以后,上句代码中的 source 引用不再能被使用。 cloneableSource = Manager.createCloneableDataSource(source); player = Manager.createRealizedPlayer(cloneableSource); player.start(); } catch (Exception e) { this.processException(e); } visualComponent = player.getVisualComponent(); if (visualComponent != null) { videoPanel.add(visualComponent); } contentPane.add("North", videoPanel); // 打包使整个界面显得紧凑! this.pack(); // 注释掉这句代码的话,窗口就缩成一个小布丁儿了! this.setResizable(false); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setLocationRelativeTo(null); this.setVisible(true); } private void start() { // ①第一个参数 clonedDataSource = ((SourceCloneable)cloneableSource).createClone(); // ②第二个参数 FormatControl formatControl = (FormatControl) player.getControl("javax.media.control.FormatControl"); Format defaultFormat = formatControl.getFormat(); // defaultFormat的值为: MJPG, 640x480, FrameRate=15.0, Length=921600 0 extra bytes // ③第三个参数 FileTypeDescriptor outputFileType = new FileTypeDescriptor(FileTypeDescriptor.QUICKTIME); //.QUICKTIME ProcessorModel processorModel = new ProcessorModel(clonedDataSource, new Format[] { defaultFormat }, outputFileType); // DataSource 可能为 mixed, 故用数组 try { processor = Manager.createRealizedProcessor(processorModel); } catch (Exception e) { this.processException(e); } String locatorString = this.getLocatorString(); //locatorString 表示存储录像数据的文件的路径 if (locatorString == null) { return; } MediaLocator dest = new MediaLocator(locatorString); DataSource outputDataSource = processor.getDataOutput(); try { // 本地文件传输 dataSink = Manager.createDataSink(outputDataSource, dest); dataSink.open(); dataSink.start(); } catch (Exception e) { this.processException(e); } processor.start(); btnStart.setEnabled(false); btnStop.setEnabled(true); } private void stop() { processor.close(); processor.deallocate(); // 必须在processor 关闭并调用这个方法以后,录像文件才能保存下来 dataSink.close(); processor = null; // 清空 processor,回收无用的内存! btnStop.setEnabled(false); btnStart.setEnabled(true); } private void processException(Exception e) { e.printStackTrace(); JOptionPane.showMessageDialog(this, e.toString(), "错误", JOptionPane.ERROR_MESSAGE); System.exit(0); } private String getLocatorString() { if (JFileChooser.APPROVE_OPTION != fileChooser.showSaveDialog(this)) { return null; } File file = fileChooser.getSelectedFile(); if (file == null) { return null; } System.out.println(file); // C:/Documents and Settings/Administrator/桌面/123 String locatorString = file.getAbsolutePath(); System.out.println(locatorString); // C:/Documents and Settings/Administrator/桌面/123 if (!locatorString.endsWith(".QUICKTIME")) { // 没有后缀的话就程式化地加上 .QUICKTIME 的后缀! locatorString += ".QUICKTIME"; } locatorString = "file://" + locatorString; System.out.println(locatorString); // file://C:/Documents and Settings/Administrator/桌面/123.QUICKTIME return locatorString; } @SuppressWarnings("unchecked") private CaptureDeviceInfo getCaptureDeviceInfo() { // 以下是原来的代码,害惨我了,老是找不到我的摄像头,原来是因为我的摄像头输出不属于 RGB 格式! // Format videoFormat = new VideoFormat(VideoFormat.RGB); Format videoFormat = new VideoFormat(VideoFormat.MJPG); // 在改成 MJPG 后顺利找到我的视频设备 Vector<CaptureDeviceInfo> deviceList = CaptureDeviceManager.getDeviceList(videoFormat); if (deviceList.size() < 1) { JOptionPane.showMessageDialog(this, "未检测到视频输入设备!", "错误", JOptionPane.ERROR_MESSAGE); System.exit(0); } String[] deviceNames = new String[deviceList.size()]; for (int i = 0; i < deviceList.size(); i++) { deviceNames[i] = deviceList.get(i).getName(); } String deviceName = (String) JOptionPane.showInputDialog(this, "请选择视频输入设备", "请选择", JOptionPane.QUESTION_MESSAGE, null, deviceNames, deviceNames[0]); if (deviceName == null) { System.exit(0); } CaptureDeviceInfo captureDevice = null; for (int i = 0; i < deviceList.size(); i++) { captureDevice = deviceList.get(i); if (deviceName.equals(captureDevice.getName())) { return captureDevice; } } return null; } public static void main(String[] args) { new RecordVideo(); } }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值