TA的每日心情 | 慵懒 2021-9-1 08:46 |
---|
签到天数: 61 天 [LV.6]常住居民II
|
本帖最后由 zhangchaont 于 2021-2-20 10:53 编辑
2 {5 C( a9 o0 Q0 r2 C, W* a- {
9 }# @) H" S& E C1 o3 [, C) H( W b为了给孩子学习英语,我把单词做成了卡片放在Anki里,但是课文却一直没有什么好的方法,在电脑上用一个复读机软件给孩子们练习,但是Mac上没有什么好用的复读机软件,所以学来学去还在最开始的几课里面打转。我本来想自己写一个复读机APP的,但是考虑到水平有限,估计得花很多时间,而且最大的问题不能利用Anki里schedule安排学习。* L# G2 `* G4 ?+ Y7 O2 X1 }0 X
( w4 e2 ^' O4 U/ G% ?, V6 q& P
春节在家,我突然灵光一闪,Anki是基于PyQt5开发,而这个模块是支持一部分html、css和javascript的,如果用javascript读取字幕里面的时间戳,然后根据时间段来播放MP3,不就实现了一个简单的复读机了嘛。说干就干,因为没有javascript语言基础,都是需要什么就搜索,一步步的拼凑起来的,目前已经基本能用,成品在iOS上显示如下:
5 p& p" b/ B0 R* f! F. w- |5 R# h
; M: a3 u: D; L- jmacOS上的效果) C' X0 G8 T, O1 g, o3 F
5 V4 U5 `+ I/ I# i
' G; u1 [! D- T2 ] l) u5 _4 o0 Y
js代码如下:1 f2 r$ h; D. I. S9 L* o
- const lesson = document.getElementsByClassName("items")[0].innerText;( W ~) S1 u" D; U# G B
- const button_next = document.createElement("button");
3 Q* @ ]( q7 W; u" f - button_next.innerHTML = '下一句';
+ H0 R# q4 L3 r) x - button_next.setAttribute('row_count', "4");1 b, b4 }/ |" K( E; S" ?
- let section = document.getElementsByClassName("section")[0];- e8 k% q5 |$ @, q% ?
- & e+ l# _ r# E( f( l% D5 P
- const button_repeat = document.createElement("button");
8 {' s4 \2 P. P# f" D! x - button_repeat.innerHTML = '重复此句';
+ j9 x- `+ [. w m5 X# W6 v8 L
5 z4 a( S; p* _ ?1 f% Z1 o" ~- const button_previous = document.createElement("button");
1 d/ {1 F; d2 h# Y( X - button_previous.innerHTML = '上一句'; w+ n- W" w5 s3 r4 Y; k7 j/ E- H; s, V
- : T( V: V3 ? [
/ H$ s E- T% |4 ^. R& f, B- let div = document.createElement('div');5 G" {0 r& i. Y% L
- div.setAttribute('class', 'text');' R$ z- X6 P; T8 u# |
- section.appendChild(div);
. j7 p& x" J( S: Y$ }3 \4 s# Y0 Y - let p = document.createElement('p');* J5 S5 }, e( t: p: s% ]9 h! ]6 }
- div.appendChild(p);
1 z9 R! O8 P: e. W, _& |
; Z, M% O$ T/ s9 f! ]: B) n1 x- buttons_div = document.createElement('div');
: ^ A2 A# }% D1 P - buttons_div.setAttribute('class', 'buttons');
1 J9 S2 y v5 y* B2 L3 P/ G5 ?. M/ b0 R% e
5 P, f" y: R- ^4 G9 c3 O- section.appendChild(buttons_div);4 p8 O9 P, R/ l5 O3 t$ g
& O4 `* o0 b+ c# W5 s- buttons_div.appendChild(button_previous);1 N$ z p5 d0 ? N
- buttons_div.appendChild(button_repeat);7 |/ s h( x/ z: s% p' Q
- buttons_div.appendChild(button_next);
4 E* F, P/ W5 V9 c' K - ! m8 O' k6 b2 n
- 2 X; z. o* [- S2 Y
- button_next.onclick = next;0 \5 S; N3 z% d3 T: B( s1 g$ ^& K
- button_repeat.onclick = repeat;/ P$ i5 B+ w' ]) l5 Z; d
- button_previous.onclick = previous;
$ _9 p- S4 w* Q7 q - section.onload = play;9 ], X/ W4 g6 {( e' X) ]
- % L* }# w" \ S3 M% `5 A4 U; v
- function next() {
- h1 x$ _- y3 [6 y& h5 X - let index = parseInt(button_next.getAttribute('row_count'));; E: v! \- L) @& ?$ E
- index += 1;
: }( b0 o2 l. F& }9 \ - button_next.setAttribute('row_count', index.toString())
' o+ }# ]8 T/ q! n& W - play().then(r => ''); p. h% Q# c' h
- }
" |# {0 h% O$ R) T - ' Z* y( f/ B# C1 w9 m7 W; J& {
- function previous() {
' s8 J& V7 ]& y% Y. H3 V* ]7 s8 l - let index = parseInt(button_next.getAttribute('row_count'));
& U* v1 B \8 g3 C - index -= 1;( |; k. S7 P3 _' z+ v
- button_next.setAttribute('row_count', index.toString())
( l9 @# v: t% k - play().then(r => '');
2 _* z& ]' s5 s# m2 |/ Y0 { - }
$ `! q/ L9 Q" O* Z$ y2 \1 O6 H
6 K7 D* R8 j. L: h# w- function repeat() {& y! O2 |/ S1 @
- play().then(r => '');
0 r, M4 \4 z, s. R+ u - }) F( C: A+ I' t# R
- 4 N; X9 Q5 ~. U* }3 }
- async function play() {; |; U3 |4 [5 i4 O% M' d
- const file = "NCE1-" + lesson + ".lrc";
: s1 I" G$ A) j3 A% z: U - let myObject = await fetch(file);( m9 ?4 `$ L I- f% }- I: F5 s' W
- let myText = (await myObject.text()).trim();
) k7 P( E4 D: f3 u+ `! E+ t' p - let lines = myText.split('\n');/ f! Y; y2 ?4 R9 |
- let index = parseInt(button_next.getAttribute('row_count'));& c9 w w; i9 W% w2 ]( N+ P
% w _% O, z7 m$ s& C, [- if (index < 4) {
; a& L, a0 j% R9 k+ R# o; Q! @ - index = lines.length - 1;
5 T2 X4 t. q3 q - button_next.setAttribute('row_count', index.toString());; _, k, F0 D/ M; h3 v2 `
- }
. q* L$ C( O" |& N - if (index > lines.length - 1) {
, I! j$ g4 C7 o9 L - index = 4;) i9 I9 o5 ~# g
- button_next.setAttribute('row_count', index.toString());& {# s" C( m$ b1 y
- }
3 ~( u. `2 w% W - let current_line = lines[index];
0 Y, l/ ?; @ V i) e& M - let text = current_line.slice(10, current_line.length - 1);
( D4 G; n/ g9 ~7 |: a& G0 H# a - p.innerText = text;) ?! l6 @5 D1 ?! A) g
- if (index < (lines.length - 1)) {
5 Y# b% t: a' d - let next_index = index + 1;8 y2 A0 ]# v, M" d
- let next_line = lines[next_index];
) b7 a; Q8 m2 |$ o+ _ g - let current_time = current_line.slice(1, 9);
0 q0 \9 e* i! ]( ` - let current_time_min_sec = current_time.split(':');4 y$ W# k: s1 v4 B
- let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);& ?: l, y, K, f6 a4 y& g
- let next_time = next_line.slice(1, 9);' s$ b/ e9 h4 |2 u
- let next_time_min_sec = next_time.split(':');% O6 W N2 o9 E: V1 L
- let end = parseFloat(next_time_min_sec[0]) * 60 + parseFloat(next_time_min_sec[1]) - 0.25;
8 d# |, U& {# F8 s* b: o - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start + "," + end);
% A" V# c- l& O( G* S! }) s8 Z0 B! s - const play1 = audio.play();7 T* I5 g- f6 D( x
- } else {
$ b& U& q7 v" X1 z& D9 A1 [% k - let current_time = current_line.slice(1, 9);+ P7 T7 q" e3 m/ i. v; [& ?% M
- let current_time_min_sec = current_time.split(':');
' y3 }- L% _$ U: r" e# V& T - let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);
4 B! |/ L+ }& n, J! a - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start);1 A7 E0 G+ X$ v& p+ Q8 X
- const play2 = audio.play();2 P1 k9 u( v- B6 Q
- }
0 V( z8 {8 h5 _; q W6 r - }
复制代码
3 {: L* v* u, l: z4 {8 L. ~& v. v2 T
: G6 \6 y6 R/ P使用的时候,把下面网盘链接里面的Anki卡片导入,然后把新概念的音频和字幕文件拷贝到Anki的collection.media文件夹里面,如果不知道media文件夹的位置在网上搜索一下。
; y E, L& a q0 F
2 N7 h5 }+ {% s& P2 @. `+ A% ~4 I- /*区块全局样式*/
$ }7 [: c$ p" _0 [# o - .section {- `. o! j; @9 y( M" E
- background-color : #f6f6f6; /*背景颜色-#f6f6f6*/6 u; Q9 v6 M( c( t
- border : 2px solid #3f3f41; /*边缘样式-实线2px*/6 G5 R- m/ H9 Q# J6 c! \, _
- border-radius : 3px; /*圆角幅度-3px*/ c. @* V' o' W
- margin : 8px 8px; /*上下间隔-8px*/, F; B/ P7 z q% L
- display : flex;- V' z8 Z5 I* b, @$ l! }
- flex-direction : column;* y7 R3 i! x1 s' w. p) |
- height: 95vh;/ ?4 Y% {) ~6 L* T3 w- A; g
- }0 e+ f" D; [" A* j; k0 Q' Y
- 5 o( f8 j# \1 b c& Y
- /*区块全局样式*/
1 w! o- p7 L: c# C) V - .mobile .section {
+ y) `" k0 o- ^, a- C" E* G* Q8 d - background-color : #f6f6f6; /*背景颜色-#f6f6f6*/
" _. l' {- S, d; V7 B1 L; x - border : 2px solid #3f3f41; /*边缘样式-实线2px*/+ Q$ }$ C3 V! Y; \' w" u! U2 }
- border-radius : 3px; /*圆角幅度-3px*/
7 s& f! s7 l2 O( U9 m/ o+ R - margin : 8px 8px; /*上下间隔-8px*/
& Q4 e# G8 |+ k$ Y& B; G" F" N - display : flex;
5 c% R# z7 u& b8 } - flex-direction : column;- G* }5 |9 U. B7 @
- height: 77vh;
! z! a* g& x0 }, U* \ - }
复制代码
/ S% k& Z+ A+ g8 M3 s! M0 D+ k在模板里面的css部分,可以调节整个区块的大小,修改height后面的数值来调节。前面有.mobile的是对移动设备的设置。/ e4 Y: D: _: p* T! {
; @! [0 @* F n+ T1 z+ L你也可以把这个模板稍加修改就可以添加新概念后面的几本书。# c$ ^8 X2 I E1 A" g# o
1 k4 i) j/ n. V6 l
( ~6 X: q q" \* i$ U
# ?9 R! [5 x5 h! C( P注意,因为iOS版本的Anki不会自动重新加载js,所以到第二张卡片的时候就会按钮显示不出来,退到deck界面再进去就可以了。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?免费注册
x
评分
-
2
查看全部评分
-
|