需求 使用Java编写GUI程序完成简单的屏幕录制操作,支持开始录屏、结束录屏、销毁本次录制等操作。
解决 添加主要依赖 1 2 3 4 5 <dependency >  	<groupId > uk.co.caprica</groupId >   	<artifactId > vlcj</artifactId >   	<version > 4.2.0</version >  </dependency > 
 
关键代码 1、Application.java(项目的入口)
1 2 3 4 5 6 public  class  Application   {  public  static  void  main (String[] args)   {          SwingUtilities.invokeLater(() -> new  ScreenRecorder(destination));   } } 
 
2、ScreenRecorder.java(GUI 及 录屏 主要逻辑)
程序 包含3个按钮,开始、停止、销毁;2个操作目录,录制完成后视频文件存放的目录A(vlcj使用) 及 待处理业务目录B(自身业务使用)。
一般流程是 先点击 开始,此时 目录A下会 多一个视频文件,录制一段视频,点击停止,程序会将目录A下的视频移至 目录B下,此时可进行后续业务处理。因为 开始录制时目录A就会创建文件,导致目录A下文件可能不是最终文件(录制未完成),所以目录B就有存在的意义,程序关闭再启动后也可遍历 目录B下的文件 处理未完成的业务。
销毁按钮用于 开始录制但未停止时想放弃本次录制,注意停止后再销毁无效。
录制中关闭程序,则保存本次录制。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 public  class  ScreenRecorder   {    private  static  final  String[] OPTIONS = {             "--quiet" ,             "--quiet-synchro" ,             "--intf" ,             "dummy"      };     private  static  String filePath = "" ;     private  static  final  String MRL     = "screen://" ;     private  static  final  String SOUT    = ":sout=#transcode{vcodec=mp4v,acodec=mpga,vb=4096,ab=512}:duplicate{dst=file{dst=%s}}" ;     private  static  final  String FPS     = ":screen-fps=20" ;     private  static  final  String CACHING = ":screen-caching=500" ;     private  final  MediaPlayerFactory mediaPlayerFactory;     private  final  MediaPlayer mediaPlayer;     private  JFrame frame;     private  static  JLabel countLabel;     private  static  JTextField nameField;          public  ScreenRecorder (final  String destination)   {         mediaPlayerFactory = new  MediaPlayerFactory(OPTIONS);         mediaPlayer = mediaPlayerFactory.mediaPlayers().newMediaPlayer();         JPanel cp = new  JPanel();         nameField = new  JTextField(5 );         JButton recordButton = new  JButton("开始" );         JButton stopButton = new  JButton("停止" );         JButton delButton = new  JButton("销毁" );         cp.add(recordButton);         cp.add(stopButton);         cp.add(delButton);         frame = new  JFrame("录屏程序" );                           frame.setContentPane(cp);         frame.setLocation(10 , 10 );         frame.pack();         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);         frame.addWindowListener(new  WindowAdapter() {             @Override              public  void  windowClosing (WindowEvent e)   {                 release();             }         });         recordButton.addActionListener(e -> go(destination));         stopButton.addActionListener(e -> stop());         delButton.addActionListener(e -> delete());         frame.setVisible(true );     }          private  void  go (String destination)   {         State state = mediaPlayer.status().state();         filePath = destination + getUUID() + ".mp4" ;         mediaPlayer.media().play(MRL, getMediaOptions(filePath));         updateTitle("录屏中" );     }     private  void  stop ()   {         State state = mediaPlayer.status().state();         mediaPlayer.controls().stop();         if  (!state.equals(State.STOPPED) && !state.equals(State.NOTHING_SPECIAL)) {                          FileUtil.moveFile(filePath, waitSendPath);             filePath = "" ;         }         updateTitle("停止" );     }     private  void  delete ()   {         mediaPlayer.controls().stop();         if  (!"" .equals(filePath)) {             FileUtil.delFile(filePath);         }         updateTitle("停止" );     }     private  void  release ()   {         State state = mediaPlayer.status().state();         if  (state.equals(State.PLAYING)) {                          stop();         }         log.info("status:"  + state);         mediaPlayer.release();         mediaPlayerFactory.release();     }          private  void  updateTitle (String title)   {         frame.setTitle("录屏程序:"  + title);     } 		private  String[] getMediaOptions(String destination) {         String result = String.format(SOUT, destination);         return  new  String[] {           result,           FPS,           CACHING         };     } } 
 
注意 
vlcj好像不能处理好windows下的中文文件名乱码的问题(创建的中文文件名乱码),mac下没问题,可以定义map存放 目录A下的随机非中文文件名 及 想要的中文文件名,在将文件从目录A移动到目录B后使用中文文件名。 
虽然视频文件是以.mp4结尾,且视频文件能用一般的播放器打开,但文件应该不是标准的mp4,使用浏览器无法直接播放。我对视频编码这里不了解,因此也没有进行后续研究(有更好的解决办法欢迎留言交流),后续业务采用阿里云进行视频转码,转换后的mp4可在浏览器中直接打开。 
暂不支持声音录制。 
可使用Java监听 目录B 文件变化来实现后续业务 Java监听文件变化  
 
界面效果