TA的每日心情 | 慵懒 2021-9-1 08:46 |
---|
签到天数: 61 天 [LV.6]常住居民II
|
本帖最后由 zhangchaont 于 2021-2-20 10:53 编辑 & {7 h; M) \ c2 [: s; `- ~/ e, _
# c3 `1 a0 v4 w# B1 Y
为了给孩子学习英语,我把单词做成了卡片放在Anki里,但是课文却一直没有什么好的方法,在电脑上用一个复读机软件给孩子们练习,但是Mac上没有什么好用的复读机软件,所以学来学去还在最开始的几课里面打转。我本来想自己写一个复读机APP的,但是考虑到水平有限,估计得花很多时间,而且最大的问题不能利用Anki里schedule安排学习。
# C* M% i& K. S1 V/ y8 n+ O' [& e& K7 Z2 Q- q3 R
春节在家,我突然灵光一闪,Anki是基于PyQt5开发,而这个模块是支持一部分html、css和javascript的,如果用javascript读取字幕里面的时间戳,然后根据时间段来播放MP3,不就实现了一个简单的复读机了嘛。说干就干,因为没有javascript语言基础,都是需要什么就搜索,一步步的拼凑起来的,目前已经基本能用,成品在iOS上显示如下:# Q% t7 d1 y) ?
# ~$ T- m3 v$ M/ Q6 b# Y+ JmacOS上的效果% k# o, C$ \5 P
3 s, e. e: ~* C7 \8 l" m! [, { x
% s" l. C- [! ]" [! C+ s1 \% |js代码如下:
6 h6 L P( e H) R3 N" i- const lesson = document.getElementsByClassName("items")[0].innerText;) O' ^% b# G7 r& `; p9 a2 E* |
- const button_next = document.createElement("button");
/ {6 Y) S7 D- a$ M! D - button_next.innerHTML = '下一句';. n) M3 Z" n9 b7 @+ k: c* ^
- button_next.setAttribute('row_count', "4");
3 h6 g8 O$ T7 t* B! | - let section = document.getElementsByClassName("section")[0];3 j% J6 `6 I3 a! M( i \
- + D6 U3 C: O1 S9 Z9 a" f
- const button_repeat = document.createElement("button");
4 {3 l' W' H4 L7 k1 Y& d' \ - button_repeat.innerHTML = '重复此句'; n( Z+ s6 I( H+ [
% H; X& e& s, v+ ?- const button_previous = document.createElement("button");
! M. H) W) H5 @ ~' t! g9 g - button_previous.innerHTML = '上一句';
& G( s$ K$ o# j- g. [4 h: m# d
/ e9 T' G; \) i' ^$ g- F- ! e/ w! y% e9 y) B# B
- let div = document.createElement('div');
- V; `3 [* i3 E7 Z W' ]9 v# s - div.setAttribute('class', 'text');
! ^' h2 \) ?9 B' l& T) L. G. C* p - section.appendChild(div);, i( r; z: w# s9 W: @ |
- let p = document.createElement('p');
% R8 ?, f$ V- ]( v+ ]2 x' d& Z - div.appendChild(p);
" I" F- a; f% e# E+ Z8 U* N
$ j& Q8 ^; T/ j# e! E7 R- buttons_div = document.createElement('div');
1 d/ @4 T f- X* h; R% d( C5 m - buttons_div.setAttribute('class', 'buttons');
' y0 O/ F" x) Z3 i# s - . Y* V* I% F% j7 j Q0 D
- section.appendChild(buttons_div); l) S3 R; H' j. S
& X4 D" \' p0 F C- buttons_div.appendChild(button_previous);8 t/ H( O7 S' D& s* j
- buttons_div.appendChild(button_repeat);, u5 u$ E$ K8 Z9 d6 D
- buttons_div.appendChild(button_next);
- p+ r1 ~# S5 {- K; q$ f$ b. [ - ; Z* V' M, z9 M8 R
T! n7 {$ u" F! Z& c$ y! z- button_next.onclick = next;
: |+ x$ @; S- h: a* X5 B: r1 Q- Q - button_repeat.onclick = repeat;
2 t% y* [2 j% o; ] - button_previous.onclick = previous;1 k# E3 N# P6 v7 \- ?$ X
- section.onload = play;- s; O! E6 z7 e2 R0 c# g
- & o. g" H! X' u/ O8 m, D- @
- function next() {
- Z: l; C4 ~% O - let index = parseInt(button_next.getAttribute('row_count'));
~/ N2 Z+ B5 o - index += 1;- i: W. v" B0 H: h
- button_next.setAttribute('row_count', index.toString())
8 r+ ?" c8 r; k9 i/ ^6 z - play().then(r => '');
7 @% I9 k/ x2 ]" ]: Y - }
7 q- e4 C- Z& B0 h9 k
, R5 ^' i$ P1 h- function previous() {' [' @5 H9 p5 g/ e5 `
- let index = parseInt(button_next.getAttribute('row_count'));
6 A5 m# b# ^3 k! @+ x% X1 N - index -= 1;1 g( |1 w5 }5 C# \6 n! ^) O
- button_next.setAttribute('row_count', index.toString())
5 A6 m2 L: }5 F3 e5 R - play().then(r => '');
! `4 M/ b) V2 J" U% e/ t - }
6 A: R+ O" U3 I# b! L/ u. y) f( }! s
# O( \) h5 G/ i0 z. v4 t+ S) W9 p- function repeat() {
" {9 S4 b# t* J7 `+ ?& c - play().then(r => '');
; M w2 q" M0 ?) _ - }
" Z3 j [4 A( x
3 A; P% k1 h" ?2 o1 q: V1 n7 l" D- async function play() {+ C! _+ m8 Z$ R- c" \8 M v
- const file = "NCE1-" + lesson + ".lrc";
( I; c5 S6 W% `$ U& Z# a( Q - let myObject = await fetch(file);( K+ J7 a# u! w
- let myText = (await myObject.text()).trim();
: b( {0 v% ?) J9 @, K6 X; f - let lines = myText.split('\n');% e( L2 o6 t( L8 z
- let index = parseInt(button_next.getAttribute('row_count'));$ }! C3 i6 M$ L& {
- 8 I9 F8 d" @6 ?+ L
- if (index < 4) {
$ V4 i2 w5 W5 }2 Y/ D! g1 \ - index = lines.length - 1;
! S7 ^, R" J) M* n6 i( |5 y - button_next.setAttribute('row_count', index.toString());
* |8 {; \- m3 e4 J% U - }
8 F7 Z4 X m1 k) ` - if (index > lines.length - 1) {
: y9 L/ k8 ?" z! a1 t) B. V7 c% w - index = 4;
, f* R* z( @8 |- H% [4 i* y - button_next.setAttribute('row_count', index.toString());. L3 d: A, e0 u; \ _ a8 G" K
- }! P9 O. z! r/ x. J* a7 D
- let current_line = lines[index];
! v0 j% z3 t9 ~' j - let text = current_line.slice(10, current_line.length - 1);* A1 r9 _ S3 p( W4 v" |
- p.innerText = text;
& m0 w' s; v: c' V1 i - if (index < (lines.length - 1)) {
4 W u3 {% Z7 G2 }- z, ^0 c7 t1 P! v - let next_index = index + 1;
* \0 t$ `+ I5 ^' G/ }* m& h - let next_line = lines[next_index];
4 U: ~+ p, s+ ~8 x4 @+ l - let current_time = current_line.slice(1, 9);
]% `0 Z0 e/ s; Q. G - let current_time_min_sec = current_time.split(':');1 {5 P: a% k' k6 J! Y) S2 ]+ l0 V
- let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);9 V# n( [2 E' O
- let next_time = next_line.slice(1, 9);
8 k6 b5 P; j J# M3 s5 G - let next_time_min_sec = next_time.split(':');3 \$ u0 _: l+ F8 |$ |$ b
- let end = parseFloat(next_time_min_sec[0]) * 60 + parseFloat(next_time_min_sec[1]) - 0.25;
@$ T- f x k( w: z$ A - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start + "," + end);
2 F0 a8 T% m8 r/ Q$ m1 y! Y - const play1 = audio.play();
' `4 v% X$ w8 s" [( b2 d - } else {) s a: q3 N3 ^* r) z( R, S, t
- let current_time = current_line.slice(1, 9);- H6 ^4 ]2 U J9 e
- let current_time_min_sec = current_time.split(':');
" Y# Y/ Y' @/ h9 p; l: z - let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);
f* y, y, W4 D - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start);
8 h/ B0 A/ L" ], n7 q$ B - const play2 = audio.play();
2 _- Y) y: y- _ - }
/ p6 t; b l' D ^: s - }
复制代码 7 G( T0 e% t% |4 ?
8 R9 R6 |- _ k" U7 @使用的时候,把下面网盘链接里面的Anki卡片导入,然后把新概念的音频和字幕文件拷贝到Anki的collection.media文件夹里面,如果不知道media文件夹的位置在网上搜索一下。
4 f" o: B' l, e- `- Z
* _' |4 K @$ p4 v2 `- s- /*区块全局样式*/3 C6 f( d2 l- i4 {
- .section {0 c7 K+ X# s1 f+ a' x; f. H# G
- background-color : #f6f6f6; /*背景颜色-#f6f6f6*/6 N+ T0 E3 U7 H3 W) o$ n
- border : 2px solid #3f3f41; /*边缘样式-实线2px*/' T+ o2 P# z4 b$ y
- border-radius : 3px; /*圆角幅度-3px*/1 t' }. C# M n# m
- margin : 8px 8px; /*上下间隔-8px*/
+ Y$ o" i7 X" t. b" `0 x - display : flex;4 V4 I1 g# L3 [4 `; [/ K! _
- flex-direction : column;
0 z2 ?0 M, _1 P: m% d2 ? - height: 95vh;7 t) J; o7 \; C6 ]
- }7 B3 h, b. m; P/ \
- ) E( b) J# ^+ `, D" [
- /*区块全局样式*/
# @& ~' C) M c9 n# Z5 y+ Y - .mobile .section {, o+ \. {3 l" M: e- [9 A' f
- background-color : #f6f6f6; /*背景颜色-#f6f6f6*/8 K$ ]) J& X9 Y0 ]" \+ z( ?
- border : 2px solid #3f3f41; /*边缘样式-实线2px*/$ J5 y( a* O; O7 N: q" F
- border-radius : 3px; /*圆角幅度-3px*/ E; L6 c- |' x5 H3 Q9 v
- margin : 8px 8px; /*上下间隔-8px*/2 Y/ p3 x9 h' C3 J* f+ U' c2 g. Z
- display : flex;
& B: |, U2 R1 s - flex-direction : column;
\1 Q' i. [# i& ]# m - height: 77vh;8 z7 L( ?, @9 e- A0 m
- }
复制代码
# h4 e& Q2 u: j2 s' B在模板里面的css部分,可以调节整个区块的大小,修改height后面的数值来调节。前面有.mobile的是对移动设备的设置。
9 |6 z; o& W% s, y
1 F$ r" i2 G" w2 k# c x你也可以把这个模板稍加修改就可以添加新概念后面的几本书。4 c% m& {* Q ^
# e3 w. j. o8 n6 j
8 S8 V5 M) R# P1 A2 c
1 c- e* ~" p6 q2 o) i* |: a注意,因为iOS版本的Anki不会自动重新加载js,所以到第二张卡片的时候就会按钮显示不出来,退到deck界面再进去就可以了。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?免费注册
x
评分
-
2
查看全部评分
-
|