Total Pageviews

Monday, 9 March 2026

如何把动态 canvas 转成视频

 

随着短视频的越来越流行,有时候需要把动态的 canvas 转换为视频然后发布到对应的平台上。当然最简单的办法就是利用录屏软件(如:QuickTime)直接将屏幕录制下来,然后通过一些视频编辑软件(如:imovie)加工处理下。

作为一名很懒的程序员,当然是希望能够自动转换为视频,一气呵成,不需要手工来处理。你还别说,现在的浏览器还真提供了对应的 API 来处理这个事情,本文就来简单介绍下。

captureStream API

通过 canvas 的 captureStream API,就可以把 canvas 变成一个 stream,然后结合 MediaRecorder API 就可以转换为 video。

  • const stream = canvas.captureStream();
  • const recorder = new MediaRecorder(stream, { mimeType: 'video/webm' });
  • const data = [];
  • recorder.ondataavailable = function (event) {
  • if (event.data && event.data.size) {
  • data.push(event.data);
  • }
  • };
  • recorder.onstop = () => {
  • const url = URL.createObjectURL(new Blob(data, { type: 'video/webm' }));
  • console.log('video url', url)
  • };

通过开始的时候调用 recorder.start() 和结束的时候调用 recorder.stop() 即可完成视频的录制工作。

注意:如果一个 canvas 操作完成后面不在变动的话,录制的时候会发现最终的视频并没有想要的长度。这是因为如果 canvas 不动的话后续就不再录制了。

解决办法也很简单,找到 canvas 中的一个元素,然后循环改变这个元素的透明度就可以(为了减少对视觉的影响,可以让透明度在 0.99 和 1 之间变化,这个目的就是让 canvas 一直在操作。当然用其他的方案也是可以)

MediaRecorder 支持的 mimeType

通过 MediaRecorder 来录制视频时,需要指定录制视频的编码格式,如:video/webmvide/mp4。 如果当前浏览器不支持的话则会报错。

可以先通过 MediaRecorder.isTypeSupported 方法检测浏览器是否支持,如:

  • MediaRecorder.isTypeSupported('video/webm');
  • MediaRecorder.isTypeSupported('video/mp4');

从目前的测试来看,video/webm 格式 chrome v81/firefox v76 都支持。但 video/mp4 目前都还不支持。

由于 webm 格式现在还没有那么流行,有些网站还不支持直接支持上传这个格式的视频,那么就需要把 webm 转换为 mp4 格式的视频。

通过测试发现,虽然 chrome v81 还不能直接支持 video/mp4 的格式,但已经支持了 video/webm;codecs=h264,也就是录制的视频是用 h264 格式来编码的。这样后续转码的时候视频部分可以直接拷贝,大大提升转码的速度。

视频转码和添加音频

通过这个方式录制的视频没有音频部分,而一般发布的视频都希望有音频作为 BGM。此时就可以通过 WebAssembly 版本的 ffmpeg 来完成了。

转换命令如下:

  • ffmpeg -i video.webm output.mp4; //转换格式
  • ffmpeg -i video.webm -i audio.mp3 -c:v copy -af apad -map 0:v -map 1:a -shortest out.mp4; // 添加音频

具体的可以通过 ffmpeg.wasm 库来完成,大致代码如下:

  • private async convertVideoUrl(url: string): Promise<string> {
  • const { audio, outVideoType, mimeType, workerOptions, transcodeOptions, concatDemuxerOptions } = this.config;
  • const { createFFmpeg } = window.FFmpeg;
  • const ffmpeg = createFFmpeg(workerOptions || {});
  • await ffmpeg.load();
  • const type = mimeType.split(';')[0].split('/')[1];
  • await ffmpeg.write(`video.${type}`, url);
  • if (audio) {
  • const audioType = audio.split('.').pop();
  • await ffmpeg.write(`1.${audioType}`, audio);
  • await ffmpeg.run(`-i video.${type} -i 1.${audioType} ${concatDemuxerOptions} out.${outVideoType}`);
  • } else {
  • if (type !== outVideoType) {
  • await ffmpeg.transcode(`video.${type} `, `out.${outVideoType}`, transcodeOptions);
  • }
  • }
  • const data = await ffmpeg.read(`out.${outVideoType}`);
  • const blob = new Blob([data.buffer], { type: `video/${outVideoType}` })
  • const mp4Url = URL.createObjectURL(blob);
  • return mp4Url;
  • }

canvas2video 库

为了方面使用,已经将录制视频和转换视频等操作封装成了一个库 canvas2video (https://github.com/welefen/canvas2video) 。代码不多,功能也比较聚焦,可以直接使用。

firekylin,一个基于Nodejs+mysql的博客程序

 A Simple & Fast Node.js Blogging Platform Base On ThinkJS3 & React.

安装

普通用户安装参见 普通安装,推荐使用腾讯云实验室体验详细的安装流程。如需对 Firekylin 进行开发,可参考 仓库版安装

如何使用

常见问题

如果您在使用过程中遇到问题,请查看 问题解答 中的解答,或者在 GitHubGitter 上提问。

用户列表

奇舞团博客 / 奇虎360-addops / 十年踪迹的博客 / welefen的博客 / 大官人的博客 / 魔术师的帽子

如果你的博客也是用 FireKylin 构建的,请到 #34 提交网址。

主题分享

开发者文档

from  https://github.com/firekylin/firekylin

( https://github.com/firekylin/firekylin/wiki)

 ----------------------------------------------------

 

安装

注意:

Firekylin 需要 Node 8.9.4+ 和 MySQL 环境的支持,请确保服务器上安装了相关环境。

本安装方法适用于安装包安装,仓库克隆安装请参见仓库版安装

  1. 在服务器上下载安装包

    请访问 https://firekylin.org/release/v1/latest.tar.gz 或者 Github Releases 下载最新的安装包。

  2. 解压缩安装包

    解压缩后你会看到如下的目录结构

    /app/
    /view/
    /www/
    /nginx_default.conf
    /pm2_default.json
    /package.json
    /production.js
    
  3. 安装程序依赖

    在程序目录中执行 npm install 安装对应的依赖。

    注意:

    执行之前请确认已有 Node.js 8.9.4+ 环境。如果国内 npm install 太慢可选择添加淘宝源代理 npm install --registry=https://registry.npm.taobao.org

  4. 配置 PM2

    将项目下的 pm2_default.json 文件改为 pm2.json,修改文件中的 cwd 配置值为项目的当前路径。
    然后通过 pm2 startOrReload pm2.json 来启动项目。

    注意:

    在服务器上推荐使用 PM2 来管理 Node.js 服务,可以通过 sudo npm install -g pm2 来安装 PM2。当然 Firekylin 也支持使用其它的进程守护工具。

  5. 配置 Nginx

    将项目下的 nginx_default.conf 改为 nginx.conf,修改文件中的 server_namerootset $node_port 等配置值,然后将该文件软链到 nginx 的配置目录下。

    假设 nginx 的配置目录为 /usr/local/nginx/conf/include,那么可以通过下面的命令设置软链:

    sudo ln -s path/to/nginx.conf /usr/local/nginx/conf/include/www.example.com.conf

    需要将 path/to 改为当前的项目路径, www.example.com 改为对应的域名。

    注意:

    server_name 的值为你的域名。root 为你的项目所在路径,需要制定到项目根目录的 www 目录下。$node_port 的值为 Firekylin 启动端口,默认为 8360。如若想要修改启动端口,可以在项目目录下新建 port 文件,并在文件中写入想要修改的端口号。 修改完后记得重启 Nginx 服务才能让配置生效。

  6. 访问你的Blog地址填写配置信息

    使用浏览器直接访问你的Blog地址即可看到 Firekylin 的安装程序。填入你的 MySQL 信息并设置好管理员账号后点击完成。

  7. 完成安装

    提示安装成功后会重新进入博客首页,访问 www.example.com/admin 即可跳转到后台。

    from  https://github.com/firekylin/firekylin/wiki/%E5%AE%89%E8%A3%85

    (  https://github.com/firekylin/firekylin/wiki/%E4%BB%93%E5%BA%93%E7%89%88%E5%AE%89%E8%A3%85)

    ---------------------------------------------------

     https://github.com/firekylin/firekylin/issues/34

Sunday, 8 March 2026

搭建基于nuxtjs和github api的静态博客程序:nuxt3-blog

 首先fork此项目https://github.com/yunyuyuan/nuxt3-blog,我fork后的项目地址是

 https://github.com/ymbrite/nuxt3-blog,访问https://github.com/ymbrite/nuxt3-blog/blob/master/config.ts ,编辑config.ts文件。然后导入项目 

https://github.com/ymbrite/nuxt3-blog到vercel.com/new ,点击Deploy按钮,等待部署完成。

部署完成后,我得到网址 https://nuxt3-blog-phi.vercel.app/

 新建 token:访问Github.com,点击右上方的下拉菜单,进入Settings, 左侧菜单选择Developer settings-点击左侧的personal access tokens-点击tokens(classic)-点击右上角的

generate new token-点击generate new token(classic), 

输入三个地方的值:

  • Note 填上nuxt3-blog,代表这个 token 是由 nuxt3-blog 使用的。
  • Expiration 建议选择No expiration,代表这个 token 永不过期,当然你也不要泄露给别人,自己最好找个地方保存,万一弄丢了就得重新生成一个。
  • 下方把repo勾上。 

 然后滚动网页到下方,点击Generate token按钮,此时 token 创建完成,注意⚠:这个 token 的使用者有权限修改你 Github 上的所有仓库,请勿泄露!它只会展示这一次,务必妥善保存。 

 访问博客网址https://nuxt3-blog-phi.vercel.app/,点击右上方小火箭🚀,进入编辑界面,把刚刚保存的 token 填上。点击右上角的‘新建’,即可新建源帖。内容写好后,点击右上角的“发布”按钮,在弹出的窗口,点击“确定”,即可发布文章。发布新帖后,需等2分钟,博客网站才会更新。

 项目地址:

 https://github.com/yunyuyuan/nuxt3-blog

  https://github.com/ymbrite/nuxt3-blog

演示博客地址: https://nuxt3-blog-phi.vercel.app/

 源帖其实都保存在这里:

https://github.com/ymbrite/nuxt3-blog/tree/master/public/rebuild/articles

参考:

https://blog.yunyuyuan.net/articles/6562

https://github.com/yunyuyuan/nuxt3-blog/wiki/

https://github.com/yunyuyuan/nuxt3-blog/wiki/1.3-%E6%96%B0%E5%BB%BAToken%E7%94%A8%E4%BA%8E%E7%AE%A1%E7%90%86%E5%8D%9A%E5%AE%A2

 

 

Saturday, 7 March 2026

情人的关怀

 

forwardemail.net/en

 https://forwardemail.net/en

伊朗动用大家伙了!一吨半弹头有多恐怖?以色列拦不住,也躲不掉

-这个视频分析得很有深度

川普失策「美伊战争」烧到9月?

 

-川普就是个神经病,想一出是一出,他想到某个点子,却从来不顾实施后,可能发生的负面后果,以为发生的事情一定会按他设想的剧本走,比如去年对中国发起的高额关税战,以为中国会屈服,没想到却踢到中国这块铁板。这次对伊朗的入侵也是这样,他又以为发生的事情一定会按他设想的剧本走,没想到美/以遭到了伊朗的高超音速导弹的痛击,而美/以的防空系统却形同虚设,完全无法拦截伊朗的高超音速导弹而被打得屁滚尿流。