Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[语音播放实现设计讨论] 建议使用ffplay在后台启动子进程播放声音从而绕过浏览器限制 #34

Open
JavaCS3 opened this issue Jun 20, 2020 · 14 comments

Comments

@JavaCS3
Copy link

JavaCS3 commented Jun 20, 2020

用ffplay可以做跨平台音乐播放 ffplay -nodisp -autoexit docs/assets/showoff-1.mp4。可以在插件active的时候把预先静态编译好的ffplay下下来。目前在NPM上面只看到一个这个https://www.npmjs.com/package/ffbinaries 不过这个会把ff全家桶全下下来。目前来看只需要ffplay就可以了,可以参考https://github.com/eugeneware/ffmpeg-static 用Github Action把各个平台的ffplay静态编译出来。vscode的tabnine.tabnine-vscodeAI代码补全就是这么干的,把预编译好的binary下下来直接执行。

经过调查发现已经有现成的FFmpeg各个平台静态编译版本,可以直接下载:https://ffmpeg.zeranoe.com/builds/
不过静态编译的ffplay大约有60MB,进程启动速度会比动态编译的慢3%

目前调研发现vscode播放音乐的方案大致有以下几种:

  1. 调用命令行工具(afplay, mplayer, aplay...):缺点是不同平台支持的命令行工具不太一样
  2. 替换vscode的ffmpeg的动态链接库:nondanee.vsc-netease-music:缺点是每次升级vscode都需要手动修改动态链接库
  3. 调用其他音乐播放器客户端的API:缺点就是必须安装相应的客户端程序

解决方案:
在插件初始化的时候,把相应的ffplay静态编译程序(静态编译的程序不依赖动态库,所以只需要一个文件即可执行)下下来,在需要播放音乐的时候直接调用该命令行程序。

@SaekiRaku SaekiRaku pinned this issue Jun 20, 2020
@JavaCS3 JavaCS3 changed the title [语音播放实现设计讨论] 建议使用ffmpeg-static在后台启动子进程播放声音从而绕过浏览器限制 [语音播放实现设计讨论] 建议使用ffplay在后台启动子进程播放声音从而绕过浏览器限制 Jun 20, 2020
@JavaCS3
Copy link
Author

JavaCS3 commented Jun 21, 2020

@SaekiRaku Updated

@SaekiRaku
Copy link
Owner

SaekiRaku commented Jun 21, 2020

@JavaCS3 感谢!不过 60MB 对于一个插件来说确实不算小了。无论是整合进插件本身,还是启动后下载,个人感觉用户体验都没有很大的提升。因为在执行播放动作前,都需要用户进行操作或等待,并且为了稳定的网络访问,可能还需要镜像服务器。

BTW,我还发现了一个有趣的插件:https://github.com/auchenberg/vscode-browser-preview ,借助 Chrome Headless(本机仍需安装 Chrome,不过我感觉这几乎是大部分程序员的标配)在 VSCode 内嵌入一个全功能浏览器,这样也无需用户手动启动浏览器了,并且插件体积也比较容易接受(vscode-browser-preview 10MB)

@JavaCS3
Copy link
Author

JavaCS3 commented Jun 21, 2020

@SaekiRaku 其实不需要ffplay打包到插件里。第一次启动插件的时候下载一次即可,只有第一次使用的时候体验会差一点。这个体验跟vscode一些language server插件一样都是运行时下载依赖包。我觉得可以接受。另外由于目前只需要播放音频,启动一个Chrome Headless感觉没啥必要额

@SaekiRaku
Copy link
Owner

@JavaCS3 Chrome Headless 的优势是不需要所有人都下载前置依赖,劣势是内存占用70MB,远大于 ffplay 的 6MB 内存。我觉得这里的问题是在于权衡用户是更能忍受 60MB 前置依赖的下载时间,还是更能忍受 70MB 的内存占用。

@SaekiRaku
Copy link
Owner

SaekiRaku commented Jun 21, 2020

@JavaCS3 不知道还有没有更小一些的工具,ffplay 还内置了GUI/绘图等操作,而且还有一堆不太需要的解码器。实际情况下,我觉得只需要支持一小部分的音频格式就行了。


我觉得用 Golang 处理这件事不错,编写简单、容易维护还跨平台,单纯只解码播放MP3也许可以做到足够小巧。目前的一些简单的检索结果:

@JavaCS3
Copy link
Author

JavaCS3 commented Jun 21, 2020

@SaekiRaku 如果你觉得目前的ffplay太大,可以在后续的版本自己重新编译去掉不必要的依赖。oto在不同的平台需要安装不同的依赖库。这种跟底层硬件打交道的东西必须是平台相关的,跟使用的语言无关,即使的语言本身是跨平台的。就像同样一个绘图指令在不同平台实现都是不一样的,需要分别编译,这个坑是绕不过去的。而且ffmpeg是个相对成熟的工具。

@SaekiRaku
Copy link
Owner

SaekiRaku commented Jun 21, 2020

@JavaCS3 这个我理解,不过我不太了解 ffplay 的源码实现,不知道其剔除依赖的工作量有多大。我想的是将平台相关的播放部分和音频解码剥离开,播放部分单独找个小型库,解码部分单独找库,由 Golang 串联起来进行编译,这样可以尽可能的小一些,实现也不复杂,还有一部分自行定制的能力和空间。

@zombie110year
Copy link

为什么不让用户提前下好 ffplay,然后在插件配置中指定可执行文件的路径呢?根本不需要把这么大一个依赖和扩展一起安装吧。

Linux、macOS 都有包管理器可以用,还有国内镜像。Windows 有点麻烦,官网下载速度太慢了,60MB 在我这里得下一天。

@fgheng
Copy link

fgheng commented Jun 22, 2020

@JavaCS3 感谢!不过 60MB 对于一个插件来说确实不算小了。无论是整合进插件本身,还是启动后下载,个人感觉用户体验都没有很大的提升。因为在执行播放动作前,都需要用户进行操作或等待,并且为了稳定的网络访问,可能还需要镜像服务器。

BTW,我还发现了一个有趣的插件:https://github.com/auchenberg/vscode-browser-preview ,借助 Chrome Headless(本机仍需安装 Chrome,不过我感觉这几乎是大部分程序员的标配)在 VSCode 内嵌入一个全功能浏览器,这样也无需用户手动启动浏览器了,并且插件体积也比较容易接受(vscode-browser-preview 10MB)

sdl2好像也可以播放音频吧?而且比较小?

@songzhi
Copy link

songzhi commented Jun 27, 2020

我觉得最好是像其他基于LSP的VSCode插件那样,用一个原生语言比如C++,Rust写一个服务器,插件和它通信控制它播放声音。插件在安装的时候下载预编译的可执行文件,启动的时候启动它作为一个后台进程。

@ouuan
Copy link
Contributor

ouuan commented Jun 28, 2020

可以让用户自己设定播放音频的命令,然后在使用说明中提供一些解决方案?

@muyichenfeng
Copy link

绕过浏览器限制播放音频处理的怎么样了?

@SaekiRaku
Copy link
Owner

@muyichenfeng 就之前的讨论来看,个人目前比较倾向于 @ouuan 的方式,默认仍然通过浏览器进行播放(或 Chrome Headless),由不介意等待依赖下载和安装的用户自行配置希望使用的音频播放工具。

@jadepeng
Copy link
Contributor

jadepeng commented Jul 12, 2020

@muyichenfeng 就之前的讨论来看,个人目前比较倾向于 @ouuan 的方式,默认仍然通过浏览器进行播放(或 Chrome Headless),由不介意等待依赖下载和安装的用户自行配置希望使用的音频播放工具。

https://github.com/jadepeng/mp3player

这里用golang写了个demo,启动一个websocket服务器,可以接收{"command":"play","arg":"DIRECTORY\\built-in-voice-chinese\\await_01.mp3"}播放mp3
rainbow-fart的配置里,可以增加播放器配置(使用浏览器、使用播放服务器),以及配置播放服务器地址
如果使用播放服务器播放,播放的时候,通过ws发送一条播放命令即可

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants