一个在编程时“玲姐”语音各种称赞你的 IDEA 扩展插件,萝莉音带耳机!IDEA 彩虹屁插件!
是否听说过程序员鼓励师,不久前出了一款vscode的插件rainbow-fart,可以在写代码的时候,匹配到特定关键词就疯狂的拍你马屁。
vscode的下载尝试过,但是作为日常将IDEA作为主力生产工具的同学来说,如何体验呢? 于是假期花了一点时间,写了一个idea版本的插件idea-rainbow-fart。
安装方法
先到下载最新的插件。关注公众号Java精选,扫描下方二维码,回复彩虹屁,即可获取下载文件。直接放到对应目录即可应用,试一试被疯狂拍你马屁的插件吧!!!
下载rainbow-fart-1.0-SNAPSHOT.zip,然后打开Idea的插件目录,比如笔者的目录是C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.4\plugins
将rainbow-fart-1.0-SNAPSHOT.zip解压到plugins目录,如图所示:
解压
然后重启IDEA即可。
使用内置语音包
打开设置:
将voice package type设置为builtin
可以选择内置语音包,共三个,一个官方的中文和英文,一个tts合成的(玲姐姐)
使用第三方语音包
将voice package type设置为custom
可以到 https://github.com/topics/vscode-rainbow-fart 查找语音包。
点击确定生效。
使用TTS(推荐)
本插件特色功能,支持自定义关键词和文本,鼠标点击表格可以修改关键词和回复语,修改时enter回车换行,一行代表一个
TTS 使用科大讯飞提供的流式API。
原理
没啥原理,就是一款简单的idea插件,对没写过插件的我来说,需要先看下官方文档,基本上看下面这一篇就OK:
https://www.jetbrains.org/intellij/sdk/docs/basics/getting_started.html
读取语音包
先来看下语音包的设计:
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
|
{ "name" : "KugimiyaRie" , "display-name" : "KugimiyaRie 钉宫理惠 (Japanese)" , "avatar" : "louise.png" , "avatar-dark" : "shana.png" , "version" : "0.0.1" , "description" : "傲娇钉宫,鞭写鞭骂" , "languages" : [ "javascript" ], "author" : "zthxxx" , "gender" : "female" , "locale" : "jp" , "contributes" : [ { "keywords" : [ "function" , "=>" ], "voices" : [ "function_01.mp3" , "function_02.mp3" , "function_03.mp3" ] }, ... ] } |
对Java来说,定义两个bean类,解析json即可:
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
|
/** * 加载配置 */ public static void loadConfig() { try { // FartSettings settings = FartSettings.getInstance(); if (!settings.isEnable()) { return ; } String json = readVoicePackageJson( "manifest.json" ); Gson gson = new Gson(); Manifest manifest = gson.fromJson(json, Manifest. class ); // load contributes.json if (manifest.getContributes() == null ) { String contributesText = readVoicePackageJson( "contributes.json" ); Manifest contributes = gson.fromJson(contributesText, Manifest. class ); if (contributes.getContributes() != null ) { manifest.setContributes(contributes.getContributes()); } } Context.init(manifest); } catch (IOException e) { } } |
监控用户输入
自定义一个Handler类继承TypedActionHandlerBase即可,需要实现的方法原型是:
1
|
public void execute( @NotNull Editor editor, char charTyped, @NotNull DataContext dataContext) |
chartTyped就是输入的字符,我们可以简单粗暴的将这些组合到一起即可,用一个list缓存,然后将拼接后的字符串匹配关键词。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
private List<String> candidates = new ArrayList<>(); @Override public void execute( @NotNull Editor editor, char charTyped, @NotNull DataContext dataContext) { candidates.add(String.valueOf(charTyped)); String str = StringUtils.join(candidates, "" ); try { List<String> voices = Context.getCandidate(str); if (!voices.isEmpty()) { Context.play(voices); candidates.clear(); } } catch (Exception e){ // TODO candidates.clear(); } if ( this .myOriginalHandler != null ) { this .myOriginalHandler.execute(editor, charTyped, dataContext); } } |
匹配关键词更简单,将读取出来的json,放到hashmap中,然后遍历map,如果包含关键词就作为语音候选:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public static List<String> getCandidate(String inputHistory) { final List<String> candidate = new ArrayList<>(); FartSettings settings = FartSettings.getInstance(); if (!settings.isEnable()) { return candidate; } if (keyword2Voices != null ) { keyword2Voices.forEach((keyword, voices) -> { if (inputHistory.contains(keyword)) { candidate.addAll(voices); } }); } if (candidate.isEmpty()) { candidate.addAll(findSpecialKeyword(inputHistory)); } return candidate; } |
如果找到候选,就播放。
播放
为了防止同时播放多个语音,我们用一个单线程线程池来搞定。播放器使用javazoom.jl.player.Player
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
|
/** * play in a single thread pool */ static ExecutorService playerTheadPool; static { ThreadFactory playerFactory = new ThreadFactoryBuilder() .setNameFormat( "player-pool-%d" ).build(); playerTheadPool = new ThreadPoolExecutor( 1 , 1 , 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>( 1024 ), playerFactory, new ThreadPoolExecutor.AbortPolicy()); } public static void play(List<String> voices) { FartSettings settings = FartSettings.getInstance(); if (!settings.isEnable()) { return ; } // play in single thread playerTheadPool.submit(() -> { String file = voices.get( new Random().nextInt() % voices.size()); try { InputStream inputStream = null ; if (StringUtils.isEmpty(settings.getCustomVoicePackage())) { inputStream = Context. class .getResourceAsStream( "/build-in-voice-chinese/" + file); } else { File mp3File = Paths.get(settings.getCustomVoicePackage(), file).toFile(); if (mp3File.exists()) { try { inputStream = new FileInputStream(mp3File); } catch (FileNotFoundException e) { } } else { return ; } } if (inputStream != null ) { Player player = new Player(inputStream); player.play(); player.close(); } } catch (JavaLayerException e) { } }); } |
开源地址: https://github.com/jadepeng/idea-rainbow-fart,欢迎fork代码,贡献代码。
插件参考,感谢原作者的贡献
插件开发参考 https://github.com/izhangzhihao/intellij-rainbow-fart
语音包和插件icon源于 https://github.com/SaekiRaku/vscode-rainbow-fart
作者:jqpeng的技术记事本
来源:https://www.cnblogs.com/xiaoqi/p/idea-rainbow-fart.html
欢迎扫码关注公众号:“Java精选”(w_z90110),回复关键字领取资料:如Mysql,Hadoop,Dubbo,CAS源码等等,免费领取视频教程、资料文档和项目源码。
欢迎扫码小程序:“Java精选面试题”,内涵3000+道面试题及6000+道选择题,免费在线刷题,选择题带有答案解析,支持随时随地刷题!
公众号涵盖:各大流行框架(Mybatis、Spring、Spring Boot等)、大数据技术(Storm、Hadoop、MapReduce、Spark等)、数据库(Mysql、Oracle、NoSQL等)、职业规划、算法与数据结构、面试专题、面试技巧经验、职业规划以及优质开源项目等。