JIGZEG.INFO
类目(8)
    标签(13)

      为博客添加MIDI播放功能

      发布


      此页面上传和播放本地的MIDI文件。

      最近花时间研究了MIDI这种文件格式,感觉发现了“新大陆”:和常见的音频文件(如.mp3/.flac等)不同,midi文件主要是记录事件(如各个音符的按压事件和控制器相关指令)而不是压缩后的音频数据,这也是为什么midi文件体积可以很小(数十KB)但是歌曲的播放时长却可以达到普通几MB的三、四分钟MP3文件的水平。MIDI文件最终播放时呈现的效果和加载的音色库相关,使用不同细腻度的音色库来播放MIDI文件,最终得到的歌曲听感会有差异。

      目前主流的操作系统都可以直接播放MIDI文件,如果要在浏览器内播放MIDI,需要依赖Web Audio API,解析MIDI文件并加载音色库,合成音频再播放。

      播放器设计

      博客目前已经支持发布MIDI音乐的文章了,文章的路径ID如果是[m]开头的,即表示是带音乐的发文。

      播放器的核心实现逻辑和代码参考了开源的在线MIDI编辑器signal-app:https://signal.vercel.app/edit,GitHub上仓库地址:https://github.com/ryohey/signal,这个编辑器实现基于TypeScript + React + Canvas。

      博客的MIDI播放器在signal-app原来代码的基础上,精简掉大部分关于MIDI编辑的内容,把它作为一个纯粹的音频文件播放器来进行开发,最终的打包gzip体积仅增加了几十KB。目前播放器支持如下功能(后续播放器的功能会有所调整):

      • 自适应布局,跟随博客切换主题
      • 后退5秒
      • 单曲循环
      • 跳转开头
      • 播放/继续播放/暂停/停止
      • 静音/取消静音
      • 节拍器功能
      • 滑动进度条定位
      • Track 静音
      • 键盘模式(88/76/61/49键)切换
      • 音符瀑布流可视化
      • 固定播放自定义选择的小节
      • 其他功能敬请探索...

      博客播放器新的功能在开发中,当然也有一些BUG等待被发现和解决。以及,播放器在移动端上的性能问题,播放时会有一点卡顿,不过在我的开发机器Chrome上测试播放还是很流畅。

      播放器初次加载时,因为要下载音色库文件,会比较缓慢,下载完毕后会将前置资源放至indexedDB进行缓存,之后就无需再次等待下载音色库了,点击即可直接播放MIDI。

      最后

      在博客内第一首发布的MIDI音乐是由德国乐队Fool's Garden带来的Lemon Tree,欢迎聆听。MIDI文件下载自:https://bitmidi.com/lemon-tree-mid

      为什么把它作为博客第一首要分享的音乐?一是因为博客是基于Deno Fresh来开发搭建的,而这个Web框架的Logo就是一个柠檬!我觉得十分有意义;而每每听到这首熟悉的旋律,总能让自己回忆起高一开学前夏令营的时光:高中的英语老师在第一堂课上给我们放的就是这首英文歌。


      此文被收纳在#MIDI#类目下,被贴上了#博客#标签

      Lemon Tree

      Fool's Garden

      点击播放按钮开始演奏

      点击播放按钮开始演奏

      00:0000:00

      给博客加入游戏控制器操作功能

      发布


      大概在3年前得到了人生中第一个Xbox游戏手柄,随后它就一路陪伴了自己多年来的游戏时光。最近,自己花了几天时间研究了浏览器W3C关于 Gamepad (游戏控制器)的API规范文档,希望博客能够实现像游戏一样支持手柄操作,达到手柄基本替代键盘鼠标操作来浏览页面的效果。目前为止,已经对手头设备上安装的浏览器博客页面的手柄操作的兼容情况做了测试,暂时没发现什么问题。

      如果想要测试你的浏览器是否支持Gamepad的API,可以到博客“关于”页面,在页面底部点击“此客户端”选项查看。

      如果点击没有反应、或者没有显示 控制器:支持 等字样的话,说明你所使用的浏览器已经太过时,是时候该升级WebView内核或者更新你的浏览器了!(远在十多年前——2012年Gamepad API在Chrome21被支持 [1])。

      热键设计

      # 操作 控制器热键
      1 上滑 左摇杆向上翘起
      2 下滑 左摇杆向下翘起
      3 模拟按下Tab键 十字键右/左按下
      4 模拟点击目前聚焦的元素 右扳机键按下
      5 打开导航 右肩键按下
      6 回到页面顶部 左肩键+十字键左按下
      7 滑到页面底部 左肩键+十字键右按下
      8 上滑一页 十字键上按下
      9 下滑一页 十字键下按下
      10 打开控制器测试工具窗口 右菜单按钮按下
      11 收起热键提示 左菜单按钮按下

      这些按键组合在所有页面基本都适用,部分页面和功能弹窗的热键布局可能会有差异,目前的热键布局未来可能有所调整。当前场景热键提示可以通过按下左菜单键查看。

      控制器测试

      设备在连接手柄后,打开博客的任意界面,按下右菜单键,即可打开控制器测试弹窗,测试控制器的按钮:

      鼠标滚动切换手柄,在Chrome上navigator.getGamepads()会返回一个长度为4的数组,故最多支持4个控制器的连接和测试。测试窗口下,支持测试手柄的震动功能(扳机震动/手柄震动),如果手柄带有振动模块,但是点击“测试震动”无反应,很有可能是浏览器不支持,升级浏览器到最新版本即可。

      功能设计

      博客适配手柄操作是以替代键盘功能键方向去设计的:

      • 例如在浏览界面时可以将十字键的右方向键当作键盘的“Tab键”来使用,切换聚焦的元素,然后按下右扳机键相当于键盘按下“回车”或者“空格”触发元素的点击事件;
      • 左摇杆上下抬起,相当于按下键盘的上下方向键,滚动页面,根据摇杆翘起程度,分级加速滚动;
      • 十字键上下方向键,相当于键盘的PageUp/PageDown按钮,上滑/下滑一页;
      • 左扳机键+十字键左右方向键,相当于按下Home/End键,回到当前页面顶部/底部;
      • 按下右肩键可以快捷呼出菜单,选择切换跳转博客板块子页

      目前还不能在文本框键入文字,未来将考虑加入虚拟键盘输入文字功能。

      继续阅读…


      此文被收纳在#星碎札#类目下,被贴上了#Gamepad##博客#标签

      网络设备间带宽测试

      发布


      如果想要测试网络带宽性能,可以使用iperf这个工具。Iperf在使用时,分为服务端和客户端两部分,通过运行iperf命令,可以得到两个终端设备之间的网络带宽性能数据 [1]

      安装和使用

      Iperf3 是从头重写的 iperf,目的是创建一个更小、更简洁的代码库 [2],不同操作系统下都可以比较方便安装它:

      • Termux: pkg install iperf3
      • Ubuntu: apt install iperf3
      • MacOS: brew install iperf3
      • Windows: 在 https://files.budman.pw/ 下载解压iperf3二进制可执行文件

      完整的官网使用说明文档见此:https://iperf.fr/iperf-doc.php

      启动服务端

      1
      iperf3 -s
      SH

      将会启动iperf3服务,默认监听端口5201

      开始测试

      1
      iperf3 -c < 服务端IP地址 > -t 30
      SH

      在客户端运行上面的命令,终端命令行将显示从客户端到服务器的网络带宽,包括吞吐量、丢包等信息,测试时间30s。服务端的终端也会同时相应输出测试数据。

      如果想要将带宽速率单位展示为 MB/s 可以加上参数 -f M,例如:

      1
      iperf3 -c 10.7.0.1 -t 30 -f M
      SH

      结果解读

      🟢 服务端 iperf3 -s -f M 输出:

      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
      -----------------------------------------------------------
      Server listening on 5201 (test #1)
      -----------------------------------------------------------
      Accepted connection from 192.168.128.3, port 58816
      [  5] local 192.168.128.1 port 5201 connected to 192.168.128.3 port 58828
      [ ID] Interval           Transfer     Bitrate
      [  5]   0.00-1.00   sec   643 MBytes   641 MBytes/sec                  
      [  5]   1.00-2.00   sec   676 MBytes   677 MBytes/sec                  
      [  5]   2.00-3.00   sec   682 MBytes   682 MBytes/sec                  
      [  5]   3.00-4.00   sec   682 MBytes   683 MBytes/sec                  
      [  5]   4.00-5.00   sec   688 MBytes   686 MBytes/sec                  
      [  5]   5.00-6.00   sec   684 MBytes   684 MBytes/sec                  
      [  5]   6.00-7.00   sec   678 MBytes   679 MBytes/sec                  
      [  5]   7.00-8.00   sec   682 MBytes   682 MBytes/sec                  
      [  5]   8.00-9.00   sec   681 MBytes   681 MBytes/sec                  
      [  5]   9.00-10.00  sec   680 MBytes   681 MBytes/sec                  
      [  5]  10.00-11.00  sec   683 MBytes   683 MBytes/sec                  
      [  5]  11.00-12.00  sec   688 MBytes   687 MBytes/sec                  
      [  5]  12.00-13.00  sec   685 MBytes   686 MBytes/sec                  
      [  5]  13.00-14.00  sec   687 MBytes   684 MBytes/sec                  
      [  5]  14.00-15.00  sec   682 MBytes   684 MBytes/sec                  
      [  5]  15.00-16.00  sec   684 MBytes   683 MBytes/sec                  
      [  5]  16.00-17.00  sec   682 MBytes   682 MBytes/sec                  
      [  5]  17.00-18.00  sec   672 MBytes   671 MBytes/sec                  
      [  5]  18.00-19.00  sec   683 MBytes   682 MBytes/sec                  
      [  5]  19.00-20.00  sec   627 MBytes   629 MBytes/sec                  
      [  5]  20.00-21.00  sec   583 MBytes   581 MBytes/sec                  
      [  5]  21.00-22.00  sec   679 MBytes   679 MBytes/sec                  
      [  5]  22.00-23.00  sec   683 MBytes   684 MBytes/sec                  
      [  5]  23.00-24.00  sec   680 MBytes   682 MBytes/sec                  
      [  5]  24.00-25.00  sec   679 MBytes   679 MBytes/sec                  
      [  5]  25.00-26.00  sec   660 MBytes   661 MBytes/sec                  
      [  5]  26.00-27.00  sec   682 MBytes   680 MBytes/sec                  
      [  5]  27.00-28.00  sec   679 MBytes   680 MBytes/sec                  
      [  5]  28.00-29.00  sec   682 MBytes   681 MBytes/sec                  
      [  5]  29.00-30.00  sec   672 MBytes   671 MBytes/sec                  
      - - - - - - - - - - - - - - - - - - - - - - - - -
      [ ID] Interval           Transfer     Bitrate
      [  5]   0.00-30.00  sec  19.8 GBytes   674 MBytes/sec                  receiver
      -----------------------------------------------------------
      Server listening on 5201 (test #2)
      -----------------------------------------------------------
      LOG

      可以看到服务端收到了IP地址为 192.168.128.3 设备的连接请求,往下就是测试的结果数据:第一列 [ID] 表示连接的流ID,第二列 Interval 表示测试时间间隔,第三列 Transfer 表示该时间段(1s)内传输的数据量(单位MB),第四列 Bitrate 表示此时间段的传输速率。再往下,就是在以上整个测试期间内的总体性能。

      🔴 客户端 运行命令 iperf3 -c 192.168.128.1 -t 30 -f M 输出:

      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
      Connecting to host 192.168.128.1, port 5201
      [  5] local 192.168.128.3 port 58828 connected to 192.168.128.1 port 5201
      [ ID] Interval           Transfer     Bitrate         Retr  Cwnd
      [  5]   0.00-1.00   sec   653 MBytes   652 MBytes/sec  179   1.44 MBytes       
      [  5]   1.00-2.00   sec   674 MBytes   674 MBytes/sec    0   1.41 MBytes       
      [  5]   2.00-3.00   sec   682 MBytes   682 MBytes/sec    0   1.72 MBytes       
      [  5]   3.00-4.00   sec   676 MBytes   675 MBytes/sec   40   2.12 MBytes       
      [  5]   4.00-5.00   sec   690 MBytes   690 MBytes/sec  212   2.31 MBytes       
      [  5]   5.00-6.00   sec   681 MBytes   681 MBytes/sec    0   1.43 MBytes       
      [  5]   6.00-7.00   sec   677 MBytes   678 MBytes/sec   81   1.72 MBytes       
      [  5]   7.00-8.00   sec   681 MBytes   681 MBytes/sec   44   2.05 MBytes       
      [  5]   8.00-9.00   sec   674 MBytes   674 MBytes/sec    0   1.84 MBytes       
      [  5]   9.00-10.00  sec   678 MBytes   677 MBytes/sec    0   1.44 MBytes       
      [  5]  10.00-11.00  sec   687 MBytes   688 MBytes/sec    0   1.33 MBytes       
      [  5]  11.00-12.00  sec   680 MBytes   681 MBytes/sec    0   1.28 MBytes       
      [  5]  12.00-13.00  sec   686 MBytes   686 MBytes/sec    0   1.98 MBytes       
      [  5]  13.00-14.01  sec   679 MBytes   676 MBytes/sec    0   1.75 MBytes       
      [  5]  14.01-15.00  sec   679 MBytes   681 MBytes/sec   32   1.43 MBytes       
      [  5]  15.00-16.00  sec   684 MBytes   685 MBytes/sec    0   1.73 MBytes       
      [  5]  16.00-17.00  sec   684 MBytes   682 MBytes/sec   23   1.82 MBytes       
      [  5]  17.00-18.00  sec   672 MBytes   672 MBytes/sec    0   2.02 MBytes       
      [  5]  18.00-19.00  sec   679 MBytes   680 MBytes/sec    0   1.77 MBytes       
      [  5]  19.00-20.01  sec   629 MBytes   628 MBytes/sec    0   5.66 KBytes       
      [  5]  20.01-21.00  sec   578 MBytes   580 MBytes/sec   89   1.72 MBytes       
      [  5]  21.00-22.01  sec   681 MBytes   678 MBytes/sec    0   1.62 MBytes       
      [  5]  22.01-23.00  sec   675 MBytes   678 MBytes/sec    0   1.65 MBytes       
      [  5]  23.00-24.00  sec   681 MBytes   680 MBytes/sec    0   1.33 MBytes       
      [  5]  24.00-25.00  sec   672 MBytes   672 MBytes/sec    0   1.22 MBytes       
      [  5]  25.00-26.00  sec   646 MBytes   645 MBytes/sec    0   1.87 MBytes       
      [  5]  26.00-27.00  sec   689 MBytes   691 MBytes/sec   66   1.41 MBytes       
      [  5]  27.00-28.00  sec   681 MBytes   681 MBytes/sec   85   1.83 MBytes       
      [  5]  28.00-29.00  sec   681 MBytes   681 MBytes/sec    0   1.44 MBytes       
      [  5]  29.00-30.00  sec   672 MBytes   671 MBytes/sec   43   1.19 MBytes       
      - - - - - - - - - - - - - - - - - - - - - - - - -
      [ ID] Interval           Transfer     Bitrate         Retr
      [  5]   0.00-30.00  sec  19.8 GBytes   675 MBytes/sec  894             sender
      [  5]   0.00-30.00  sec  19.8 GBytes   674 MBytes/sec                  receiver
      
      iperf Done.
      LOG

      上方客户端输出的数据,前4列代表的意义和服务端的一致,只不过客户端这边是作为数据发送的角色;后面的 Retr 一列表示在此时间间隔内的TCP重传次数(或者出错次数);之后的 Cwnd(Congestion Window,拥塞窗口),表示当前的TCP拥塞窗口大小。


      1. Iperf - Wikipedia ↩︎

      2. Iperf: iperf3 - Wikipedia ↩︎


      此文被收纳在#操作系统#类目下,被贴上了#运维#标签

      MarkdownIt Emoji插件语法参考

      发布


      参考:Supported emoticons - Emoticon@GitHub

      # Emoji Name Emoticons
      1 😠 angry >:(; >:[; >:-(; >:-[; >=(; >=[; >=-(; >=-[
      2 😊 blush :"); :"]; :"D; :-"); :-"]; :-"D; ="); ="]; ="D; =-"); =-"]; =-"D
      3 💔 broken_heart </3
      4 😕 confused :/; :-/; =/; =-/
      5 😢 cry :,(; :,[; :,\|; :,-(; :,-[; :,-\|; :'(; :'[; :'\|; :'-(; :'-[; :'-\|; =,(; =,[; =,\|; =,-(; =,-[; =,-\|; ='(; ='[; ='\|; ='-(; ='-[; ='-\|; T-T
      6 😦 frowning :(; :[; :-(; :-[; =(; =[; =-(; =-[
      7 ❤️ heart <3
      8 👿 imp ]:(; ]:[; ]:-(; ]:-[; ]=(; ]=[; ]=-(; ]=-[
      9 😇 innocent o:); o:]; o:D; o:-); o:-]; o:-D; o=); o=]; o=D; o=-); o=-]; o=-D; O:); O:]; O:D; O:-); O:-]; O:-D; O=); O=]; O=D; O=-); O=-]; O=-D; 0:); 0:]; 0:D; 0:-); 0:-]; 0:-D; 0=); 0=]; 0=D; 0=-); 0=-]; 0=-D
      10 😂 joy :,); :,]; :,D; :,-); :,-]; :,-D; :'); :']; :'D; :'-); :'-]; :'-D; =,); =,]; =,D; =,-); =,-]; =,-D; ='); =']; ='D; ='-); ='-]; ='-D
      11 😗 kissing :*
      12 😆 laughing x); x]; xD; x-); x-]; x-D; X); X]; X-); X-]; X-D
      13 👨 man :3; :-3; =3; =-3; ;3; ;-3; x3; x-3; X3; X-3
      14 😐 neutral_face :\|; :-\|; =\|; =-\|
      15 😶 no_mouth :-
      16 😮 open_mouth :o; :O; :0; :-o; :-O; :-0; =o; =O; =0; =-o; =-O; =-0
      17 😡 rage :@; :-@; =@; =-@
      18 😄 smile :D; :-D; =D; =-D
      19 😃 smiley :); :]; :-); :-]; =); =]; =-); =-]
      20 😈 smiling_imp ]:); ]:]; ]:D; ]:-); ]:-]; ]:-D; ]=); ]=]; ]=D; ]=-); ]=-]; ]=-D
      21 😭 sob :,'(; :,'[; :,'-(; :,'-[; :',(; :',[; :',-(; :',-[; =,'(; =,'[; =,'-(; =,'-[; =',(; =',[; =',-(; =',-[
      22 😛 stuck_out_tongue :p; :P; :d; :-p; :-P; :-d; =p; =P; =d; =-p; =-P; =-d
      23 😝 stuck_out_tongue_closed_eyes xP; x-p; x-P; x-d; Xp; Xd; X-p; X-P; X-d
      24 😜 stuck_out_tongue_winking_eye ;p; ;P; ;d; ;-p; ;-P; ;-d
      25 😎 sunglasses 8); 8]; 8D; 8-); 8-]; 8-D; B); B]; B-); B-]; B-D
      26 😓 sweat ,:(; ,:[; ,:-(; ,:-[; ,=(; ,=[; ,=-(; ,=-[; ':(; ':[; ':-(; ':-[; '=(; '=[; '=-(; '=-[
      27 😅 sweat_smile ,:); ,:]; ,:D; ,:-); ,:-]; ,:-D; ,=); ,=]; ,=D; ,=-); ,=-]; ,=-D; ':); ':]; ':D; ':-); ':-]; ':-D; '=); '=]; '=D; '=-); '=-]; '=-D
      28 😒 unamused :s; :z; :S; :Z; :-s; :-z; :-S; :-Z; =s; =z; =S; =Z; =-s; =-z; =-S; =-Z
      29 😉 wink ;); ;]; ;D; ;-); ;-]; ;-D


      Emoji语法测试区

      继续阅读…


      此文被收纳在#参考表#类目下,被贴上了#Markdown#标签

      VLC播放器的圣诞彩蛋

      发布


      很久没用过VLC Player了,今天偶然打开一个midi文件时,发现VLC的“雪糕帽”图标变得有一点点不一样,很有趣,遂记录一下。

      “关于软件”里展示的应用图标也发生变化,戴上了一顶圣诞帽 😃:

      于是乎在网上查了一下,不出所料就是开发者留下的彩蛋:VLC在圣诞节的前后各一周(12月18日至翌年1月1日)会自动把软件图标设置为一个戴圣诞帽的交通锥 [1]

      如果想要关闭这个特性,可以在播放器的偏好设置中取消勾选“允许自动更改图标”,然后关闭窗口重启软件即可,配置项的大概位置在 “界面 - 主界面” 里。不同系统或者不同软件版本,可能会不一样。


      1. VLC多媒体播放器 彩蛋 - Wikipedia ↩︎


      此文被收纳在#星碎札#类目下,被贴上了#播放器#标签

      使用Python批量读取/修改ogg音频元数据

      发布


      第一次碰到Ogg文件是在安卓系统的/system/media/audio/目录下的一些文件夹(alarms/notifications/ringtones/ui等文件夹)里,尽管后缀名非常奇怪,但这种格式的文件已经被广泛传播和使用了。使用十六进制文件查看器任意打开一个OGG文件,可以看到它的文件头的Magic Number为:0x4F676753,转换为文本就是OggS,即这种文件的后缀名的全称:OggSquish [1]

      这种文件格式的优势在于开源,支持多种编码类型,且压缩率高。

      我们可以使用Python的一个库 mutagen,简单修改包括Ogg这种文件格式在内的音频文件的元数据(如,标题、作者等……)。

      安装mutagen

      1
      python -m pip install mutagen
      SH

      安装mutagen之后,即可借助这个库简单查看OGG文件的一些基础数据:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      import mutagen
      
      audio = mutagen.File('ping.ogg')
      
      print(audio.pprint())
      """输出:
      Ogg Vorbis, 0.27 seconds, 120000 bps (audio/vorbis)
      ANDROID_LOOP=false
      TITLE=android.resource://com.google.android.soundpicker/string/ping
      """
      PYTHON

      以及,修改文件的数据:

      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
      import mutagen
      
      audio = mutagen.File('ping.ogg')
      
      print(audio.pprint())
      
      audio['TITLE'] = "Ping" # 修改标题
      audio['ARTIST'] = "Google Pixel" # 修改作者
      
      audio.save() # 保存修改
      
      print()
      print("""--- AFTER MODIFIED ---""")
      print()
      
      modified = mutagen.File('ping.ogg')
      
      print(modified.pprint())
      
      
      """输出:
      Ogg Vorbis, 0.27 seconds, 120000 bps (audio/vorbis)
      ANDROID_LOOP=false
      TITLE=android.resource://com.google.android.soundpicker/string/ping
      
      --- AFTER MODIFIED ---
      
      Ogg Vorbis, 0.27 seconds, 120000 bps (audio/vorbis)
      ANDROID_LOOP=false
      TITLE=Ping
      ARTIST=Google Pixel
      """
      PYTHON

      假设目录都是后缀为ogg的文件,文件命名格式都是xxx_yyy.ogg之类,目标是修改其元数据信息的标题TITLEXxx Yyy,可以写出一个批量修改OGG文件标题和作者等元数据的脚本:

      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
      import os
      import re
      import sys
      import time
      import mutagen
      
      try:
      
          _path = input('Please input ogg files folder path: ')
      
          _path = _path.strip('\' ')
      
      except KeyboardInterrupt as e:
          print()
          print('Good bye.')
          sys.exit(0)
      
      if len(_path) <= 0:
          print('Param error.')
          sys.exit(1)
      
      print('Ogg files folder path is: [%s]' % (_path, ))
      
      print()
      print('---')
      print()
      
      t0 = time.time()
      
      def format_name_str(s: str):
          parts = s.split('_')
          capitalized_parts = [part.capitalize() for part in parts]
          return ' '.join(capitalized_parts)
      
      tasks = []
      successed_tasks = []
      
      def modify_metadata(file_path: str, title: str, artist: str):
          try:
              audio = mutagen.File(file_path)
              
              audio['TITLE'] = title
              audio['ARTIST'] = artist
              
              audio.save()
              print(f'Metadata updated for {file_path}')
              successed_tasks.append(file_path)
          except Exception as e:
              print(f'Error processing {file_path}: {e}')
      
      for root, _, files in os.walk(_path):
          for file in files:
              if file.lower().endswith('.ogg'):
                  file_path = os.path.join(root, file)
                  tasks.append(file_path)
                  modify_metadata(file_path, format_name_str(re.sub(r'\.ogg$', '', file)), 'Google Pixel')
      
      print()
      print('---')
      print()
      
      print('Processed %d /%d file(s).' % (len(successed_tasks), len(tasks)))
      
      print('Cost: %.4f s.' % (time.time()-t0, ))
      PYTHON

      脚本将会递归遍历指定文件夹下的所有OGG文件,并根据文件名称相应修改文件元数据的标题、修改作者为Google Pixel

      运行结果如下:

      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
      105
      106
      107
      108
      109
      110
      111
      112
      113
      114
      115
      116
      117
      118
      119
      120
      121
      122
      123
      124
      125
      126
      127
      128
      129
      130
      131
      132
      133
      134
      135
      136
      137
      138
      139
      140
      141
      142
      143
      144
      145
      146
      147
      148
      149
      150
      151
      152
      153
      154
      155
      156
      157
      158
      159
      160
      161
      162
      163
      164
      165
      166
      167
      168
      169
      170
      171
      172
      173
      174
      175
      176
      177
      178
      179
      180
      181
      Please input ogg files folder path: '/Users/azhza/Downloads/Ringtones'
      Ogg files folder path is: [/Users/azhza/Downloads/Ringtones]
      
      ---
      
      Metadata updated for /Users/azhza/Downloads/Ringtones/eureka.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/flick.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/scamper.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/party_favor.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/pipes.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/sleigh_bells.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/champagne_pop.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/moondrop.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/be_mine.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/twang.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/sweetheart.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/swoosh.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/tune_up.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/orbiter.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/coconuts.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/rainstick.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/flutter.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/glimpse.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/droplet.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/plonk.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/epiphany.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/popcorn.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/begining.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/sunflower.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/gradient.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/snowflake.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/chitter.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/winter_wind.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/twinkle.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/sticks_and_stones.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/bumble.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/mallet.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/shopkeeper.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/thumb.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/everblue.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/chime.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/teapot.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/gentle_gong.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/iota.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/ping.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/chord.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/holiday_magic.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/carbonate.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/mystique.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/cheers.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/knock.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/orders_up.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/tweeter.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/watery.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/discovery.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/shuffle.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/duet.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/approach.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/shimmering.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/tinsel.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/dish_hop.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/dragon_dreams.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/flitter.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/pivot.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/go_off_king.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/star_jump.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/snap_technique.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/departure.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/blue_harp.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/beats_and_bops.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Material Adventures/aqueous.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/construction_zone.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/dots.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/heaviest_metal.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/pots_and_pans.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/high_flying.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/glassy_ring.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/dubstep_drops.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/sharp_ring.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/beach_jam.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/radient_chimes.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/mystical_chimes.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Play It Loud/glass_bubbles.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/jingle_bells.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/lion_dance.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/cupids_arrow.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/holiday_bells.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/deck_the_halls.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/flower_waltz.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/spring_mist.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/spooky_organ.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/auld_lang_syne.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/dreidel_dreidel.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/autumn_rainstorm.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/hello_spring.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Seasonal Celebrations/haunted_house.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/milky_way.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/galaxy.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/falling_star.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/big_dipper.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/satellite.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/constellation.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/cosmic_dust.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/north_star.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/asteroid.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/MinimalMelodies/comet.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/the_hunt.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/presto.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/air.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/hungarian_dance.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/blue_lily.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/nutcracker.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/moonlight.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/minuet.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/butterflys_wings.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/mephistos_dance.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/nocturne.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Classical Harmonies/breeze.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/finish_line.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/flip_phone.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/back_in_time.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/game_on.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/glow_stick.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/high_score.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/gateway.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/power_up.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/bonus_points.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/light_crackle.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/tropical_beats.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Retro Riffs/the_small_adventure.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/shooting_star.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/copycat.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/your_new_adventure.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/monkey_around.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/lost_and_found.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/spaceship.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/hotline.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/futterby.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/early_bird.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/rrring.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/zen.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/crackle.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/summer_night.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/leaps_and_bounds.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/hey_hey.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/dance_party.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/beats.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/schools_out.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/romance.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/lolipop.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/zen_too.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/mash_up.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Pixel Sounds/the_big_adventure.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/dewdrop.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/log_drum.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/cloud_drift.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/busy_bee.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/woodpecker.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/garden_breeze.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/mingle.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/voyages.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/dusty_plain.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/songbird.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/awakening.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Natural Elements/night_song.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/little_red_trolley.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/band_practice.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/merry_go_round.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/hen_house.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/the_cats_meow.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/sealed_with_a_kiss.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/pinwheel.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/old_timey_phone.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/didgeridoo.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/fair_tale.ogg
      Metadata updated for /Users/azhza/Downloads/Ringtones/Reality Bytes/sweet_dreams.ogg
      
      ---
      
      Processed 171 /171 file(s).
      Cost: 0.4646 s.
      LOG

      1. Ogg - Wikipedia ↩︎


      此文被收纳在#写写代码#类目下,被贴上了#Python##OGG音频#标签

      给老笔记本再次更新黑苹果

      发布最后更新于


      EFI下载地址见此:ASUS-Zenbook-U4100U-OpenCore-EFI/releases


      2024-12-05更新:修复了Wi-Fi和蓝牙驱动问题,目前来看大部分硬件都驱动上了,算是比较完美的黑苹果。

      手柄尝试连接多次,貌似连不上,不知道什么原因,只能通过USB连接和识别 😦


      2024-12-06更新:



      将多年前的老笔记本的黑苹果系统macOS版本从12的Monterey升级到了15的Sequoia,使用OpenCore引导,目前系统的主要硬件驱动情况:

      • 电源/休眠
      • 键盘/键盘背灯
      • USB端口映射
      • 音频/耳机口/麦克风
      • 摄像头
      • 触摸板
      • Wi-Fi
      • 蓝牙
      • 多系统切换

      老设备再次焕发新生机~目前双系统支持切换Windows11:


      此文被收纳在#操作系统#类目下,被贴上了#Hackintosh#标签

      使用Webpack内联CSS JS

      发布


      有些场景下,希望能将引用的CSS文件内联至style标签中,将JS文件内联至script标签中,这样就可以减少网络请求数量,提升页面加载速度。尤其是在页面引用到了众多小型的资源文件时,嵌入到一个html文件中,页面首次加载速度会有明显提高。

      我们可以配置Webpack,借助插件:html-bundler-webpack-plugin,将这些小型文件都内联化,配置打包到一个html文件中就可以了。下面是一个简单用例:

      假如项目目录如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      .
      ├── package.json
      └── src
          ├── a.html
          ├── b.html
          ├── scripts
          │   ├── a1.js
          │   └── a2.js
          └── styles
              ├── a1.css
              └── a2.css
      

      其中,a.html引用了a1.jsa1.css

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Page a</title>
          <link rel="stylesheet" href="styles/a1.css">
      </head>
      <body>
          <script src="scripts/a1.js"></script>
      </body>
      </html>
      HTML

      b.html引用了a2.jsa2.css

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Page a</title>
          <link rel="stylesheet" href="styles/a2.css">
      </head>
      <body>
          <script src="scripts/a2.js"></script>
      </body>
      </html>
      HTML

      我们希望将两个html文件各自所引用到的文件,分别打包到各自所在的html文件中,最终得到dist/a.htmldist/b.html两个文件,那么,可以按如下步骤来进行配置操作:

      首先安装Webpack、html-bundler-webpack-plugin以及css-loader等依赖:

      1
      npm install html-bundler-webpack-plugin css-minimizer-webpack-plugin css-loader webpack webpack-cli -D
      SH

      然后创建webpack.config.js配置文件:

      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
      // webpack.config.js
      import path from 'path';
      import HtmlBundlerPlugin from 'html-bundler-webpack-plugin';
      import CssMinimizerPlugin from 'css-minimizer-webpack-plugin';
      import { fileURLToPath } from 'url';
      
      const __filename = fileURLToPath(import.meta.url); // 获取当前文件路径
      const __dirname = path.dirname(__filename);
      
      export default {
        mode: 'production',
      
        output: {
          path: path.join(__dirname, 'dist/'),
        },
      
        plugins: [
          new HtmlBundlerPlugin({
            entry: {
              'a': './src/a.html',
              'b': './src/b.html',
            },
            css: {
              inline: true,
            },
            js: {
              inline: true,
            },
            minify: true,
          }),
          new CssMinimizerPlugin(), // 压缩CSS
        ],
      
        module: {
          rules: [
            {
              test: /\.css$/,
              use: ['css-loader'],
            },
          ],
        },
      
        performance: false,
      };
      JS

      然后编辑package.json,加入一个打包指令:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      {
        "name": "_proj",
        "version": "1.0.0",
        "main": "index.js",
        "scripts": {
          "build": "webpack build --mode=production"
        },
        "keywords": [],
        "author": "",
        "license": "ISC",
        "description": "",
        "devDependencies": {
          "css-loader": "^7.1.2",
          "css-minimizer-webpack-plugin": "^7.0.0",
          "html-bundler-webpack-plugin": "^4.4.1",
          "webpack": "^5.96.1",
          "webpack-cli": "^5.1.4"
        },
        "type": "module"
      }
      JSON

      终端运行:

      1
      npm run build
      SH

      会在dist目录下生成两个内嵌了所引用的CSS/JS文件内容的HTML文件。


      此文被收纳在#Webpack#类目下,被贴上了#Webpack#标签

      有趣的“码神挑战”

      发布最后更新于


      昨天在B站刷到一位叫“鱼皮”的Up的视频,内容是介绍面向广大程序员发起的“码神挑战”答题活动。想要证明自己的“编程实力”的同学可以去看看,答题的同时巩固一下自己的编程知识,同时收获一份快乐~ 😆

      点击此处开始挑战。

      P.S.

      已通关,学无止境!(全程开发者控制台工具没关过~有几关没解出来,切到移动端视图跳过去的)


      此文被收纳在#写写代码#类目下,被贴上了#1024程序员节#标签
      ← 早期文第 1 页 / 共 2 页近期文 →