【🐟摸鱼专用】上班偷偷看视频📺而不会被老板打🔨的IDE插件,适配JetBrains全家桶

Overview

🐟 摸鱼专用】上班偷偷看视频 📺 而不会被老板打 🔨 的IDE插件,适配JetBrains全家桶


博客详情: 敬请期待。。。


插件起源:

去年在新电脑上看视频的时候,在触摸板上做了一个缩放的手势把程序列表Call出来了:

preview

我那时候是纯黑色的壁纸,再加上视频也刚好播放到白色衣服人物在黑夜中的画面,这就使得画面中的人物变得立体起来了!甚至有一种身临其境的感觉!

preview

我当时就觉得,哇这种效果好棒啊,就像在播放透明背景的视频一样。记得那时候还在鸿神的群里讨论了一下关于播放透明视频的话题,后面还说到Android Studio有个设置透明背景图的功能,但图片毕竟是静态的,肯定没有动态的好玩。

第二天我很随意的debug了一下Android Studio的设置背景图片的功能(完全不抱希望的),没想到居然发现了它是通过很简单的一句代码来指定图片:

PropertiesComponent.getInstance().setValue("idea.background.editor", "image path")

于是我就想:播放视频不也就是一张张图片快速切换嘛?如果我弄一个插件,里面用计时器周期性刷新这个图片,不就实现了动态的效果了?

第二天按照这个想法尝试了下,果然可以!接着我把一个视频每一帧图片都导出来,在插件中周期性调用上面的方法把每一帧图片路径都传进去。。。。

你应该也猜到了,没错,很卡,非常非常卡!比PPT还要卡,卡到不能正常使用!

认真看了下代码之后发现,原来这个设置背景图片是IDEA提供的,IDEA窗口的RootPane下面有个叫GlassPane的Child,那个含有透明度的背景图就是在GlassPane里面的PaintHelper中绘制的。更多细节会在即将到来的文章上面讲清楚,敬请期待。


大致原理:

解析视频的每一帧画面和声音,根据帧率分别刷新到背景板和写入到声卡里。这一步在有API提供的情况下都不难实现,主要难度在于优化绘制效率!!!

如果你熟悉Java GUI编程的话,你会知道swing是通过脏区(Dirty Area)来找到需要重新绘制的Components,但是这里偏偏又碰上了视频画面,视频画面通常都是占满了整个IDE窗口的。也就是说,当你刷新视频帧的时候,会连带着整个IDE窗口里的所有Component也重新绘制一遍!!!这是什么概念?如果你播放的是60帧的视频,就代表着视频帧的刷新周期是16ms,并且IDE窗口内Component的绘制总时长不能超过16ms(超过就有卡顿感了)。可现实是你电脑的cpu不可能一直偏心这个绘制线程的,平时编译项目的时候基本上都是90%使用率以上,如果不花点手段优化下这个绘制效率,那在IDE窗口里播放视频就跟播放PPT差不多了。。。

当前已使用的优化方案有:

  • 最大程度复用临时对象(这个不用说);

  • 开启硬件加速(网上搜到的);

  • 使用VolatileImage代替BufferedImage来绘制(这个是在IDEA源码里偷学到的);

  • 干掉了swing原来的RepaintManager,替换成自己实现的。自己实现的RepaintManager会过滤掉重复绘制的区域,也就是在同一时间段内,同一区域只会绘制一次(独家!根据源码总结出来的,网上绝对没有);

  • 重绘画面时绕过AWT的消息队列,不参与排队,直接交给RepaintManager处理(独家!根据源码总结出来的,网上绝对没有)。优化前每次重绘都要排2次队;

经过优化之后,现在已经可以轻松播放1080p的视频,4k25帧的也能hold住,不过4k60帧的就比较吃力了,配置高点的电脑应该可以。我已经尽力了。。。

还可能有同学想问,为什么能把视频画面放在所有组件的下面,并且能设置透明度?这是怎么做到的?

emmmm,在即将到来的文章里会带大家一起了解这个东西,一起从0开始做一个视频播放插件。


安装:

很快就好。 (现在暂时可以先手动下载项目根目录下的intellij-media-player.zip ,然后拖到IDE窗口中重启就行了)


温馨提示:

如果在播放视频中领导正在向你走来 😰 请不要犹豫,马上按下组合键CTRL + ALT + SHIFT + Z 视频会立即停止并隐藏相关控制按钮 😃


效果图:

preview

preview

preview

效果视频:

效果视频1效果视频2效果视频3


更新日志:

  • 1.0 完成基本功能。

感谢:

本插件依赖javacvFFmpeg提供的API作音视频处理,感谢这两个仓库的所有参与者。

感谢wanandroid交流群里的 "小学生" 帮忙解答音视频同步问题。

You might also like...
Comments
  • 选择完视频后点击ok报错,试过mp4、 flv格式,url也是报错,都是NoClassDefFoundError

    选择完视频后点击ok报错,试过mp4、 flv格式,url也是报错,都是NoClassDefFoundError

    java.lang.NoClassDefFoundError: kotlin/Result at com.wuyr.intellijmediaplayer.media.MediaPlayer.notify(MediaPlayer.kt:545) at com.wuyr.intellijmediaplayer.media.MediaPlayer.release(MediaPlayer.kt:561) at com.wuyr.intellijmediaplayer.media.MediaPlayer.stop(MediaPlayer.kt:236) at com.wuyr.intellijmediaplayer.media.MediaPlayer.start(MediaPlayer.kt:133) at com.wuyr.intellijmediaplayer.actions.OpenAction$actionPerformed$$inlined$run$lambda$1.invoke(OpenAction.kt:31) at com.wuyr.intellijmediaplayer.actions.OpenAction$actionPerformed$$inlined$run$lambda$1.invoke(OpenAction.kt:18) at com.wuyr.intellijmediaplayer.dialogs.URLInputDialog$createActions$1.actionPerformed(URLInputDialog.kt:30) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348) at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402) at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259) at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) at java.awt.Component.processMouseEvent(Component.java:6548) at javax.swing.JComponent.processMouseEvent(JComponent.java:3325) at java.awt.Component.processEvent(Component.java:6313) at java.awt.Container.processEvent(Container.java:2237) at java.awt.Component.dispatchEventImpl(Component.java:4903) at java.awt.Container.dispatchEventImpl(Container.java:2295) at java.awt.Component.dispatchEvent(Component.java:4725) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4889) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4526) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4467) at java.awt.Container.dispatchEventImpl(Container.java:2281) at java.awt.Window.dispatchEventImpl(Window.java:2746) at java.awt.Component.dispatchEvent(Component.java:4725) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:764) at java.awt.EventQueue.access$500(EventQueue.java:98) at java.awt.EventQueue$3.run(EventQueue.java:715) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90) at java.awt.EventQueue$4.run(EventQueue.java:737) at java.awt.EventQueue$4.run(EventQueue.java:735) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at java.awt.EventQueue.dispatchEvent(EventQueue.java:734) at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:781) at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:718) at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:382) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:109) at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:190) at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:235) at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:233) at java.security.AccessController.doPrivileged(Native Method) at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:233) at java.awt.Dialog.show(Dialog.java:1077) at com.intellij.openapi.ui.impl.DialogWrapperPeerImpl$MyDialog.show(DialogWrapperPeerImpl.java:698) at com.intellij.openapi.ui.impl.DialogWrapperPeerImpl.show(DialogWrapperPeerImpl.java:430) at com.intellij.openapi.ui.DialogWrapper.invokeShow(DialogWrapper.java:1690) at com.intellij.openapi.ui.DialogWrapper.show(DialogWrapper.java:1639) at com.intellij.openapi.ui.messages.MessageDialog.show(MessageDialog.java:181) at com.wuyr.intellijmediaplayer.dialogs.URLInputDialog.(URLInputDialog.kt:82) at com.wuyr.intellijmediaplayer.actions.OpenAction.actionPerformed(OpenAction.kt:27) at com.intellij.openapi.actionSystem.ex.ActionUtil$1.run(ActionUtil.java:220) at com.intellij.openapi.actionSystem.ex.ActionUtil.performActionDumbAware(ActionUtil.java:237) at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.lambda$actionPerformed$0(ActionMenuItem.java:304) at com.intellij.openapi.wm.impl.FocusManagerImpl.runOnOwnContext(FocusManagerImpl.java:307) at com.intellij.openapi.wm.impl.IdeFocusManagerImpl.runOnOwnContext(IdeFocusManagerImpl.java:106) at com.intellij.openapi.actionSystem.impl.ActionMenuItem$ActionTransmitter.actionPerformed(ActionMenuItem.java:294) at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022) at com.intellij.openapi.actionSystem.impl.ActionMenuItem.lambda$fireActionPerformed$0(ActionMenuItem.java:114) at com.intellij.openapi.application.TransactionGuardImpl.runSyncTransaction(TransactionGuardImpl.java:88) at com.intellij.openapi.application.TransactionGuardImpl.lambda$submitTransaction$1(TransactionGuardImpl.java:111) at com.intellij.openapi.application.TransactionGuardImpl.submitTransaction(TransactionGuardImpl.java:120) at com.intellij.openapi.application.TransactionGuard.submitTransaction(TransactionGuard.java:122) at com.intellij.openapi.actionSystem.impl.ActionMenuItem.fireActionPerformed(ActionMenuItem.java:114) at com.intellij.ui.plaf.beg.BegMenuItemUI.doClick(BegMenuItemUI.java:529) at com.intellij.ui.plaf.beg.BegMenuItemUI.access$300(BegMenuItemUI.java:49) at com.intellij.ui.plaf.beg.BegMenuItemUI$MyMouseInputHandler.mouseReleased(BegMenuItemUI.java:549) at java.awt.Component.processMouseEvent(Component.java:6548) at javax.swing.JComponent.processMouseEvent(JComponent.java:3325) at java.awt.Component.processEvent(Component.java:6313) at java.awt.Container.processEvent(Container.java:2237) at java.awt.Component.dispatchEventImpl(Component.java:4903) at java.awt.Container.dispatchEventImpl(Container.java:2295) at java.awt.Component.dispatchEvent(Component.java:4725) at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4889) at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4526) at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4467) at java.awt.Container.dispatchEventImpl(Container.java:2281) at java.awt.Window.dispatchEventImpl(Window.java:2746) at java.awt.Component.dispatchEvent(Component.java:4725) at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:764) at java.awt.EventQueue.access$500(EventQueue.java:98) at java.awt.EventQueue$3.run(EventQueue.java:715) at java.awt.EventQueue$3.run(EventQueue.java:709) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90) at java.awt.EventQueue$4.run(EventQueue.java:737) at java.awt.EventQueue$4.run(EventQueue.java:735) at java.security.AccessController.doPrivileged(Native Method) at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) at java.awt.EventQueue.dispatchEvent(EventQueue.java:734) at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:781) at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:718) at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:382) at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201) at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116) at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

    opened by shangx335 4
  • 无法播放 选好点击ok直接无法任何反应

    无法播放 选好点击ok直接无法任何反应

    image

    IntelliJ IDEA 2021.1.3 (Ultimate Edition) Build #IU-211.7628.21, built on June 30, 2021

    Expiration date: July 31, 2021 Runtime version: 11.0.11+9-b1341.60 amd64 VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o. Windows 10 10.0 GC: G1 Young Generation, G1 Old Generation Memory: 1024M Cores: 8 Registry: compiler.automake.allow.when.app.running=true, ide.windowSystem.autoShowProcessPopup=true, ide.balloon.shadow.size=0, go.run.processes.with.pty=false, ide.images.show.chessboard=true Non-Bundled Plugins: Batch Scripts Support (1.0.12), CMD Support (1.0.5), com.biyusheng.plugins (1.3.3), com.github.b3er.idea.plugins.arc.browser (0.23), com.github.redfoos.logstash-intellij-plugin (0.63-EAP), com.jetbrains.ChooseRuntime (1.2), com.wuyr.intellijmediaplayer (1.0), de.netnexus.camelcaseplugin (3.0.8), dev.meanmail.plugin.nginx-intellij-plugin (2021.2-211), io.github.qeesung.component.HighlightBracketPair (1.1.2), io.zhile.research.ide-eval-resetter (2.1.14), net.vektah.codeglance (1.5.4), org.github.erikzielke.gotoproject (1.2), org.jetbrains.plugins.go-template (211.6693.44), com.intellij.kubernetes (211.7142.13), GrepConsole (11.10.211.6086.0), com.alibaba.p3c.smartfox (2.1.0), de.kontext_e.idea.plugins.autofill (1.0), org.intellij.gitee (2021.1.0), io.scheinecker.intellij.coco (1.4.1), MavenRunHelper (4.13.203.000.0), com.ytw88.weappsupport (0.1.0), com.zxy.ijplugin.wechat-miniprogram (3.5.5), com.codota.csp.intellij (4.2.8), org.jetbrains.plugins.node-remote-interpreter (211.6693.65), org.jetbrains.plugins.vue (211.7142.13), org.jetbrains.kotlin (211-1.5.10-release-891-IJ7142.45), com.bruce.intellijplugin.generatesetter (2.7), com.zhaow.restful.toolkit (2.0.9), cn.wuzhizhan.plugin.mybatis (2020.12.18), com.sjhy.plugin.easycode (1.2.4-RC4), com.baomidou.plugin.idea.mybatisx (1.4.16), com.jetbrains.php (211.7142.45), Pythonid (211.7142.45), org.jetbrains.plugins.go (211.7142.36), cn.yiiguxing.plugin.translate (3.1-201) Kotlin: 211-1.5.10-release-891-IJ7142.45

    opened by YYJavaGit 1
Releases(v1.0.4)
Owner
陈小缘
陈小缘