我这种人,一开始学习,就忍不住开始工欲善其事必先利其器。
最后菜刀倒是磨快了,但兴头也耗掉了,独孤求败得懒得再用它砍东西。
这大概就是现代的月夜访韩信……(不是

反正记一下最近用 Anki 做的事儿。
目的:市面上所有日文相关背诵 APP 都难用,所以重新用回 Anki 制作日语课文发音卡,TTS 发音不好听,也因此同时需求真人配音
解决步骤:参考 ankitube 的油管视频卡片制作流程——除了他们家的收费服务一定也有人做相关的自动化工作流——大量谷歌后成功找到根据字幕文件自动裁剪音频文件的软件——修改我很喜欢的 kindle 风格 Anki 模板卡片——思考怎么放置对话卡片——解决


step 1 课文文本和音频

先找到合适的课文文本,这方面通过 readfree 解决,有一个朋友发了很好的精简版 mobi 格式文档,通过 calibre 打开以后可以直接复制里面的内容

再找合适的音频文件,这里我没有用标日课文的音频,用了叶子老师的标日课文朗读,提取码 9lis
我感觉她的朗读要比标日的官方音频要好,每一句读之前会读中文释义,读基本课文前四句时还会慢快各读一遍,跟读很方便。


step 2 制作音频字幕文件

我找到的软件可以根据字幕文件的时间轴来实现自动剪裁音频的功能,所以第二步是给音频打轴。
打轴我必须要说 ARCTIME 真是太好用了。这个软件可以做到可视波形打轴,随意拖拽字幕时间块,自动双语 AB 字幕轨,并且官方文档有详细的视频教程,简直是科技拯救人类的绝佳范本!!(按下对此前用了五六年的一个打轴软件的三万字吐槽)

这里我自己对字幕做的一点改进是:

  1. 只对日文朗读部分打轴,这样卡片发音的时候比较不浪费时间。
  2. 在对话部分,每句对话结尾处预留一秒左右时间,Anki 对音频文件的顺序播放是没有间隔的,这样会让整篇对话听感不那么赶,更舒适。

step 3 自动切割音频

这里用了 anki 辅助工具 subs2srs 来实现课文单句音频的切割,这位简书大佬功德无量普救众生,我搜到的时候差点掉眼泪。

网址里的教程写得非常详细,就不重复来讲。不过我要实现的功能实际上和他不一样(而且我跟着教程也在导入 tsv 部分 失败了),因此切完音频以后还是要手工制卡。

不过好在最麻烦的部分已经被解决了(试了 AA 裁语音,差点没被烦死),剩下的也就是一篇课文二十句左右而已,边学边做并不需要多少时间。


step 4 Anki 制卡

这里用了网上广为流传的 kindle 风格模板。

先讲思路:

  1. 比起形式,内容更重要,因此不需要折腾太多的字段和格式,只需要最简单的背记卡功能——正面问题,背面回答,点开回答的时候卡片发音,并且可以按照章节课号来分类,单独抽出来或者合并
  2. 怎么实现比较好的课文背记卡?——我想到的是:正面显示汉语意思加强印象(很奇怪,学日语我根本不记得译文,也不知道好事还是坏事),反面显示课文原文和涉及到的相关文法,原文文法的部分加粗显示,利用章节和 tag 字段实现检索
  3. 如何对整篇课文实现切割?——目前的做法:每个单句做一张卡片,一段对话结束后再做一张对话卡片,太长的对话切割成四五句一张卡片,保证每张卡片的信息量都不太大,语音单句单句插入,方便随时跳进度。
  4. 最终人在每一张卡片上做的事情:先看译文回忆原文,点开反面听语音跟读,强化语法记忆。

最终卡片效果↓

最终卡片效果


Anki 模板存档

(特别长可以不用看只是存档)
最后存一下我改完以后的 kindle 风格模板,这个模板网上到处都能下到,我很喜欢,用废柴的 Html 技术改了一下,比较符合我的审美。

格式部分这样↓

格式部分这样

以及注意
<div class="title">正面</div>
以及
<div class="title">背面</div>
这两句不知道为什么插入多行代码时会在网页上有显示错误,于是我把正面 / 背面前后多加了一个空格,不清楚加了以后还能不能用,如果不能用的话记得删掉。


正面模板

<!-- 页眉区块 -->
<div class="head1"></div>
<div class="head2"></div>
<div class="head3"></div>

<!-- 正面区块 -->
<div class="section">
<div class="title"> 正面 </div>
<div id="front" class="items">{{ 正面 }}</div>

<!-- 本行为注释,如需使用额外字段,请删除本行与后面的注释行
<hr><div id="front-extra1" class="items"> 正面额外字段(如: 音标)</div>
本行为注释,如需使用额外字段,请删除本行与上面的注释行 -->

</div>

格式刷

</style>

<!--
Anki 基本模板 Kindle 样式
作者:你家老黄(ninja33)
网址:http://ninja33.github.io
QQ 群:25091023
-->

<style>

/* 卡片全局样式 */
.card {
font-family : helvetica, arial, sans-serif; /* 字体名称 */
font-size : 14px; /* 字体大小 - 14px*/
text-align : left; /* 对齐方式 - 左对齐 */
color : #3f3f41; /* 字体颜色 -#3f3f41*/
background : #f6f6f6; /* 背景颜色 -#f6f6f6*/
margin : 0px;
}

/* 页眉样式 */
.head1{
display : block; /* 改成 none 可以隐藏该条块 */
background : #3f3f41 url(_kindle_wifi.png) no-repeat center;
height : 21px; /* 条块高度 - 21px*/
}
.head2{
display : block; /* 改成 none 可以隐藏该条块 */
background : #f6f6f6 url(_kindle_menu.png) no-repeat center;
height : 40px; /* 条块高度 - 40px*/
}

.head3{
display : block; /* 改成 block 可以隐藏该条块 */
background : #f6f6f6 url(_kindle_info.png) no-repeat center;
height : 25px; /* 条块高度 - 25px*/
border-top : 2px solid #3f3f41;
}

/* 页脚样式 */
.foot{
display : none; /* 改成 none 可以隐藏该条块 */
background : #1d1e20 url(_kindle_logo_s.png) no-repeat center;
height : 22px; /* 条块高度 - 20px*/
}

/* 区块全局样式 */
.section {
background-color : #f6f6f6; /* 背景颜色 -#f6f6f6*/
border : 2px solid #3f3f41; /* 边缘样式 - 实线 2px*/
border-radius : 3px; /* 圆角幅度 - 3px*/
margin : 8px 8px; /* 上下间隔 - 8px*/
}

.title{
display : block; /* 改成 none 可以隐藏该条块 */
background-color : #f6f6f6; /* 背景颜色 -#f6f6f6*/
border-bottom : 1px solid #3f3f41; /* 边缘样式 - 实线 1px*/
padding : 5px 12px; /* 区块留白 */
}

/* 区块项全局样式 */
.items{
font-size : 12px; /* 字体大小 - 12px*/
margin : 0 12px; /* 区块间隔 */
padding : 10px 0 8px 0; /* 区块留白 */
}

hr{
border : 0; /* 分割线宽 */
margin : 0 12px; /* 区块间隔 */
border-top : 1px solid #3f3f41; /* 边缘样式 - 实线 1px*/
}

/* 正面背面全局样式 */
#front,
#back{
line-height : 1.5em; /* 段落行高 - 1.5em*/
}

/* 正面字段样式 */
#front{
font-size : 18px; /* 字体大小 - 25px*/
color : #3f3f41; /* 字体颜色 -#3f3f41*/
text-align : left; /* 文本对齐 - 居左 */
}

/* 背面字段样式 */
#back{
font-size : 16px; /* 字体大小 - 16px*/
color : #3f3f41; /* 字体颜色 -#3f3f41*/
text-align : left; /* 文本对齐 - 居左 */
}

/* 额外字段预留样式 */
#front-extra1{
}
#front-extra2{
}
#back-extra1{
}
#back-extra1{
}

/* 词性高亮基本样式 */
.hightlight{
font-size : 12px; /* 字体大小 - 12px*/
border-radius : 4px; /* 圆角幅度 - 4px*/
color : #fff; /* 字体颜色 - 白色 */
padding : 0 3px; /* 左右留白 - 3px*/
margin-right : 5px; /* 右侧间隔 - 5px*/
}
</style>

<!--
JS 帮助函数
效果:折叠展开效果。点击特定的区块 / 图片后,使指定的某区块折叠或展开
用法:将函数 toggle 赋予区块或者图片的 onclick 事件,并将 e 命名为要折叠的区块 ID
举例:点击页眉,将正面区块折叠,可以按如下方式操作
在页眉的区块中加 onclick=toggle(e),其中将 e 命名为要折叠的区块 ID'front'
修改后的页眉区块如下
<div class="bar head" onclick="toggle('front')"> 牌组名称 : {{Deck}}</div>
-->
<script>
function toggle(e){
var box=document.getElementById(e);
if(box.style.display=='none'){
box.style.display='block';
}
else{
box.style.display='none';
}
}
</script>

<style>

背面模板

{{FrontSide}}

<!-- 背面区块 -->
<div class="section">
<div class="title"> 背面 </div>
<div id="back" class="items">{{ 背面 }}</div>


<!-- 本行为注释,如需使用额外字段,请删除本行与后面的注释行
<hr><div id="back-extra1" class="backlist items"> 背面额外字段名(如: 笔记)</div>
<hr><div id="back-extra2" class="backlist items"> 背面额外字段名(如: 例句)</div>
本行为注释,如需使用额外字段,请删除本行与上面的注释行 -->

</div>

<!-- 页脚区块 -->
<!-- 如有外部引用的网址,可以将下列 href="#" 改成 href={{ 网址字段 }}-->

<div class="foot"></div>


<!--
JS 帮助函数
效果:词性彩色高亮。在指定的区块中,若有英语词性符号,则高亮成预定义的彩色背景
用法:将下列函数 querySelectorAll('#back')中的 back,换成含有英语词性的区块 ID
举例:比如正面字段所在区块 & lt;div id="front"> 包含了形如 Test - 'n. 测试 & apos; 这样的英语单词解释,需要高亮词性 n. 那么只要把下列函数中相应地方改为 querySelectorAll('#front')就可以了
-->

<script type="text/javascript">
var colorMap = {
'n.':'#3f3f41',
'a.':'#3f3f41',
'adj.':'#3f3f41',
'ad.':'#3f3f41',
'adv.':'#3f3f41',
'v.':'#3f3f41',
'vi.':'#3f3f41',
'vt.':'#3f3f41',
'prep.':'#3f3f41',
'conj.':'#3f3f41',
'pron.':'#3f3f41',
'art.':'#3f3f41',
'num.':'#3f3f41',
'int.':'#3f3f41',
'interj.':'#3f3f41',
'modal.':'#3f3f41',
'aux.':'#3f3f41',
'pl.':'#3f3f41',
'abbr.':'#3f3f41',
};
[].forEach.call(document.querySelectorAll('#back'), function(div) {
div.innerHTML = div.innerHTML
.replace(/\b[a-z]+\./g, function(symbol) {
if(colorMap[symbol]) {
return '<a class="hightlight" style="background-color:'
+ colorMap[symbol] + ';" >' + symbol + '</a>';
}else{
return symbol;
}
});
});

</script>