TA的每日心情 | 慵懒 2021-9-1 08:46 |
---|
签到天数: 61 天 [LV.6]常住居民II
|
本帖最后由 zhangchaont 于 2021-2-20 10:53 编辑 % U2 n" a3 T3 P4 n4 x' f* @
9 H& m9 t" k* i1 Q6 u6 \" ~. H: P6 A为了给孩子学习英语,我把单词做成了卡片放在Anki里,但是课文却一直没有什么好的方法,在电脑上用一个复读机软件给孩子们练习,但是Mac上没有什么好用的复读机软件,所以学来学去还在最开始的几课里面打转。我本来想自己写一个复读机APP的,但是考虑到水平有限,估计得花很多时间,而且最大的问题不能利用Anki里schedule安排学习。
* b# M; _8 d4 k+ i2 N
7 t6 L* t; H5 i6 E1 j* x; e春节在家,我突然灵光一闪,Anki是基于PyQt5开发,而这个模块是支持一部分html、css和javascript的,如果用javascript读取字幕里面的时间戳,然后根据时间段来播放MP3,不就实现了一个简单的复读机了嘛。说干就干,因为没有javascript语言基础,都是需要什么就搜索,一步步的拼凑起来的,目前已经基本能用,成品在iOS上显示如下:, L3 H+ `0 I3 f/ J n* K( o
$ P+ D! j: j* j6 x' d
macOS上的效果
) I8 x$ p5 {' B9 F/ h' g! ~3 ?: X5 A" E& D' L! _3 l
/ x0 J+ |- W; \$ x
js代码如下:
- U4 O# a' d4 b: E( p! [% J9 i2 d- const lesson = document.getElementsByClassName("items")[0].innerText;
7 o# \' ^/ m. ?- J - const button_next = document.createElement("button");
w7 R4 M1 b/ P3 R3 @ - button_next.innerHTML = '下一句';
* S* v6 C" `; {! Y - button_next.setAttribute('row_count', "4");
0 k6 U+ S$ z: V - let section = document.getElementsByClassName("section")[0];, J; a, S$ m% ^8 m, L
2 B2 n: T$ W( p) Q2 k- const button_repeat = document.createElement("button");
2 \7 U, H. x, Z0 B - button_repeat.innerHTML = '重复此句';
1 Q- g3 m9 q1 Y- p# ?# _- y
$ ]! A( s; K9 I- const button_previous = document.createElement("button");4 w. l$ m6 q* C
- button_previous.innerHTML = '上一句';
$ j5 I& w/ G# z M+ f
7 N# C2 Z& \8 R; A; S* V: d
* @( h3 l2 T* c+ k4 Z+ I- let div = document.createElement('div');$ p! I0 j1 ]/ D
- div.setAttribute('class', 'text');+ { G% `* x. s+ A
- section.appendChild(div);2 P S' h+ ^$ ]
- let p = document.createElement('p');& ]: E) S# N4 |7 j6 a* ~! B( }
- div.appendChild(p);) m1 y% p/ d* I- w& Q4 Y |
: S! C1 X& @4 v# p+ i2 t! W4 H- buttons_div = document.createElement('div');7 U: k# \- j, M
- buttons_div.setAttribute('class', 'buttons');5 H- q" Y, y# t9 T6 r
! x6 u4 a) M, q$ n. I- section.appendChild(buttons_div);8 v9 K& X% W& d' p) B+ a% }, E
# I& C4 C" T% J+ M# e- buttons_div.appendChild(button_previous);
5 K" ?, k" q y - buttons_div.appendChild(button_repeat);
6 c: X; d* \$ p) D1 ~ - buttons_div.appendChild(button_next);
" f0 [1 h4 m' K
6 p9 t* I/ j# P, H- ! ?0 Y' T& Q9 j4 r" ~9 X7 R
- button_next.onclick = next;7 A6 B% o4 q0 B( }2 d
- button_repeat.onclick = repeat;% a( `2 _& S" L
- button_previous.onclick = previous;. q d2 Z: a }
- section.onload = play;
1 J1 ^: @: D) T7 z - , [6 X8 |4 w3 W# U
- function next() {& a4 ]8 E" I0 ?) e, G/ E- w$ F
- let index = parseInt(button_next.getAttribute('row_count'));
. h: p- z+ W4 s3 i# E - index += 1;
$ v: \" ^: N, _4 p5 o& R - button_next.setAttribute('row_count', index.toString())
o9 l- E1 f y. {) m4 t$ |6 {; T* E - play().then(r => '');
' O! C. l% k/ x9 L - }' E( b$ t# y$ B& T3 K
- + A# S- }; d6 N4 S" K0 e! e
- function previous() {. Z4 @$ r1 l1 V* b3 l7 V
- let index = parseInt(button_next.getAttribute('row_count'));* N) O, U/ G; {. V8 T! Z7 |/ I
- index -= 1;
7 l1 L' M7 A/ p4 R" O - button_next.setAttribute('row_count', index.toString())8 f4 ^( Y" W6 K0 i/ Q7 j+ g7 {
- play().then(r => '');
" N1 o% N* Q: i! k - }$ k9 m0 t& I" b! l" e
3 Q1 V5 S7 F. T- J2 U4 y- function repeat() {. S1 t$ h% B$ @9 X% z- G9 v, F
- play().then(r => '');
; D9 W0 }7 B' n: k5 u( k. p - }
$ s" c9 ~) Y. C9 |
2 d: W# ~: B4 f! ]+ X& Q" ^- async function play() {: L$ F6 r/ E: B2 B; O
- const file = "NCE1-" + lesson + ".lrc";
# c: ?/ R( L7 m: G+ | - let myObject = await fetch(file);
. ]+ q" }' ~0 X1 p8 E o" E% L - let myText = (await myObject.text()).trim();
# l0 x) r; w3 n5 m: o' Z - let lines = myText.split('\n');) u( X# @$ o. a, F, D
- let index = parseInt(button_next.getAttribute('row_count'));
# f$ ^" Z: N0 ]+ {
! K" A! T' B L$ ?' K- if (index < 4) {+ z) R2 e3 ?+ f ?$ `6 P) f' v
- index = lines.length - 1;- F3 p0 ^( M9 e3 }
- button_next.setAttribute('row_count', index.toString());* V- ~; J* f5 _- Y
- }& Y+ P/ ^( E. g) c( I" g& p u
- if (index > lines.length - 1) {8 U2 G* l+ Y. }- I& c
- index = 4;! q9 J& d; w7 `& J& Y& a9 E* f6 H
- button_next.setAttribute('row_count', index.toString());
* S4 R- `- s6 k; \* h2 M5 e - }
6 W! Q2 v- `5 O/ t, ~0 O, }+ C - let current_line = lines[index];
1 @; f0 w8 P. C8 _* d - let text = current_line.slice(10, current_line.length - 1);; A9 D6 G6 E( ~. p# r
- p.innerText = text;
7 q9 |$ J! g/ H: f! V0 k: R - if (index < (lines.length - 1)) {
) f4 W% n" T1 K$ Z5 C/ ~ - let next_index = index + 1;. }- ?& V; ?* n4 s
- let next_line = lines[next_index];
* l5 A" {) e" ]+ |$ y: { - let current_time = current_line.slice(1, 9);; P9 G! V5 \% l5 b
- let current_time_min_sec = current_time.split(':');
: C9 M* N8 b+ F9 V! _4 _7 L% [ - let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);0 @7 n% o/ ~! o2 J: B
- let next_time = next_line.slice(1, 9);
% w! o0 `& m: ^ - let next_time_min_sec = next_time.split(':');
1 W4 R. @* l/ A8 j }& C8 R - let end = parseFloat(next_time_min_sec[0]) * 60 + parseFloat(next_time_min_sec[1]) - 0.25;
$ Z, s9 z& r* z, F - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start + "," + end);) k2 I& @# [6 Q2 I- u5 m- j; V
- const play1 = audio.play();; n3 A7 Y( c; F
- } else {
7 i7 R, h3 O6 T; ^! [' D. q0 x$ _2 d - let current_time = current_line.slice(1, 9);) {+ Q) K+ `0 i9 k9 [9 T
- let current_time_min_sec = current_time.split(':');! G4 G" Y5 T9 |2 g" X+ K
- let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);
. }5 a3 H. N X9 x5 ]$ u. I - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start);
0 O: c* `# m. @7 L' f - const play2 = audio.play();
& G0 _: F: y( Z% f4 \ - }
" W5 b) T9 s2 k - }
复制代码 ! f, x+ W9 O7 C$ @9 C* q
" T9 w) _/ s9 Z3 w6 N9 A
使用的时候,把下面网盘链接里面的Anki卡片导入,然后把新概念的音频和字幕文件拷贝到Anki的collection.media文件夹里面,如果不知道media文件夹的位置在网上搜索一下。$ E+ g3 ~+ A& _( ^
K0 u; L/ i" A- /*区块全局样式*/3 n' S3 O7 C0 j0 ?: s
- .section { }: r/ G: J* v* \2 y) h3 v' e
- background-color : #f6f6f6; /*背景颜色-#f6f6f6*/
9 _* t/ g+ f$ I$ B' U/ p- v8 A - border : 2px solid #3f3f41; /*边缘样式-实线2px*/6 a; v. M* [& m8 L
- border-radius : 3px; /*圆角幅度-3px*/. m6 q9 {6 w* e; _$ S3 p2 V6 _ ?
- margin : 8px 8px; /*上下间隔-8px*/4 S$ e4 h2 P& x J$ W! U) y
- display : flex;, \9 \3 p9 J; P- {
- flex-direction : column;
, y% D* W' c; M# _9 I7 _+ E3 [ - height: 95vh;& `1 G; }% r! |- E2 S( b/ E
- }
" a! V9 T* h6 ~+ L+ q: r: o# i$ v7 f
% |3 p1 H0 C% F+ N+ U8 W+ D0 u- /*区块全局样式*/
6 p# A( ]* C. l+ Z/ H - .mobile .section {
{& r, Z% \- B( N" a( D - background-color : #f6f6f6; /*背景颜色-#f6f6f6*/
( h4 b9 I( S; r1 {& ? - border : 2px solid #3f3f41; /*边缘样式-实线2px*/
C( v! o" C- D. v- i0 A, T - border-radius : 3px; /*圆角幅度-3px*/( E: v4 G" F) ^1 d
- margin : 8px 8px; /*上下间隔-8px*/
+ p- L5 n# x" s; ?9 l - display : flex;
0 i/ K. M+ Q/ y# B6 I0 d - flex-direction : column;
. r$ F7 K) b- z: B3 `8 ~ - height: 77vh;" c6 q! K2 i F0 c& o
- }
复制代码
. R; Z9 H' b7 s2 f在模板里面的css部分,可以调节整个区块的大小,修改height后面的数值来调节。前面有.mobile的是对移动设备的设置。
2 B0 Y0 h5 J+ M) X* f( W. A
( O& ^' P$ Z5 w! S你也可以把这个模板稍加修改就可以添加新概念后面的几本书。
9 D& n; Q+ [, R0 g4 E& \
+ X2 D( o& K7 M% D( L+ s+ a5 w# V6 F. B7 X
2 P4 ], K+ H# ^4 E% k
注意,因为iOS版本的Anki不会自动重新加载js,所以到第二张卡片的时候就会按钮显示不出来,退到deck界面再进去就可以了。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?免费注册
x
评分
-
2
查看全部评分
-
|