TA的每日心情 | 慵懒 2021-9-1 08:46 |
---|
签到天数: 61 天 [LV.6]常住居民II
|
本帖最后由 zhangchaont 于 2021-2-20 10:53 编辑 - [7 P5 o4 d* r J
9 ~! `$ {: p8 K$ o" b) Q2 O) q
为了给孩子学习英语,我把单词做成了卡片放在Anki里,但是课文却一直没有什么好的方法,在电脑上用一个复读机软件给孩子们练习,但是Mac上没有什么好用的复读机软件,所以学来学去还在最开始的几课里面打转。我本来想自己写一个复读机APP的,但是考虑到水平有限,估计得花很多时间,而且最大的问题不能利用Anki里schedule安排学习。! ?* J& M; p: i+ Q @2 m
7 p2 I, H8 e, H( h) Q, Y. C
春节在家,我突然灵光一闪,Anki是基于PyQt5开发,而这个模块是支持一部分html、css和javascript的,如果用javascript读取字幕里面的时间戳,然后根据时间段来播放MP3,不就实现了一个简单的复读机了嘛。说干就干,因为没有javascript语言基础,都是需要什么就搜索,一步步的拼凑起来的,目前已经基本能用,成品在iOS上显示如下:
- \8 L9 r$ n" U& O/ A; w
5 I( s6 x* P0 A0 D0 CmacOS上的效果
7 l( I, A! R6 Y; ?, a- I) ^1 F
4 L" x5 U3 X2 k
4 W5 K2 y9 o$ M. O" p) @/ w& l& Ojs代码如下:
8 ?2 Q/ ^$ w6 D& m( @3 V- const lesson = document.getElementsByClassName("items")[0].innerText;
6 _) \9 [. e& t' k M: i - const button_next = document.createElement("button");
0 `9 t% E2 `6 M- Z0 d - button_next.innerHTML = '下一句';: f s3 k* ~5 u2 M* @
- button_next.setAttribute('row_count', "4");
1 q5 b4 G, B, z2 R/ [3 ~: ]" G - let section = document.getElementsByClassName("section")[0];" ?3 ]& }% k& [' t4 ]$ w& [) _0 H
- 4 Z) D# l" J. l l) V
- const button_repeat = document.createElement("button");
- n0 M6 G3 u6 F" j4 G2 N - button_repeat.innerHTML = '重复此句';3 V/ m, E7 C+ `/ K$ T7 j
; Q7 Z% w. V" N- const button_previous = document.createElement("button");
) {+ R" X: D: {( G - button_previous.innerHTML = '上一句';
8 x1 P, q7 P6 R( Z- p( V( B - 8 Q* ~$ x: w) b$ z
" b: a) E2 w4 x' W1 {9 h- let div = document.createElement('div');* f3 L5 }* I6 x
- div.setAttribute('class', 'text');' t- W# y1 ^. M3 [. `
- section.appendChild(div);
r4 D* ~+ O+ E M" k2 P4 R H& t% ~# ? - let p = document.createElement('p');. ]/ t3 [* U2 u# x; R7 P
- div.appendChild(p);( f$ M2 S) a/ C* n" p" `" U
/ L0 A F6 L9 Z8 H ^+ \3 s- buttons_div = document.createElement('div');
' {, n1 F6 d% r+ \# m# m - buttons_div.setAttribute('class', 'buttons'); o" q6 e5 e1 R" j; w6 [
- 2 X b# x1 V& |; Y, K$ j& K, L/ i" V* w
- section.appendChild(buttons_div);" a9 O r4 L6 t* Q* h! z2 H
- # p' \6 @( ^& R4 h ^% G
- buttons_div.appendChild(button_previous);
, C, Q( y( d! X5 b, o - buttons_div.appendChild(button_repeat);
; [) [" R# A1 d' O - buttons_div.appendChild(button_next);
9 `: r6 c2 d) a T( [
; V! M v3 i8 B6 m
\; l+ O: s# U, j! t$ H! w! C- button_next.onclick = next;; r; M7 W' k% ^/ b0 l$ f
- button_repeat.onclick = repeat;
! z# F* _) }' n. B - button_previous.onclick = previous;
4 o7 t% P1 H9 b8 v" h$ n - section.onload = play;
$ v/ |( T& c: F& i( i. L2 } - , R! k7 b+ u! Y
- function next() {
4 }4 u1 v, R2 D+ l - let index = parseInt(button_next.getAttribute('row_count'));! I' x. g! F0 S6 X5 @
- index += 1;
8 |8 p. {# `; H* N7 j - button_next.setAttribute('row_count', index.toString())4 v$ g, O2 w r/ x
- play().then(r => '');
6 K: I8 S3 b6 D( r9 K - }, h" k) }5 [+ a: A; _
6 S% L( R2 } P/ D V: i) M- function previous() {( c6 v1 ~6 q/ M
- let index = parseInt(button_next.getAttribute('row_count'));
$ u. ^1 j) ?) S& `8 h' X& m - index -= 1;. d1 B8 y2 n1 _/ }1 q" q
- button_next.setAttribute('row_count', index.toString())
1 n) h7 {0 t/ U. H - play().then(r => '');. m9 S; f7 K J
- } S6 v7 [: S0 V/ p* d5 t4 c0 I
- & h* `. n3 f! r9 S! S
- function repeat() {3 ^2 K& S( I- B+ `9 Z
- play().then(r => '');0 G6 ^ S( P) w- E! Q7 k7 A! N" V
- }$ n) h9 h# I7 S A1 r
- : Q) Q2 J1 J, x; c& L
- async function play() {1 a; y) S/ j4 t) P1 H* @8 \) `
- const file = "NCE1-" + lesson + ".lrc";( u4 H0 N0 j" J% V4 f3 G
- let myObject = await fetch(file);$ O" z0 k$ d+ H7 D
- let myText = (await myObject.text()).trim();
9 w0 \ k+ ^9 F; }! m' {8 M- ^ - let lines = myText.split('\n');' y. b; @ z6 X3 y# B6 \/ C5 p
- let index = parseInt(button_next.getAttribute('row_count'));7 }' b0 G7 \$ B5 N" K& m( D7 _
' v: s# ?' l; T; s- if (index < 4) {) w6 `/ X h6 @6 H' C! _$ a5 ]
- index = lines.length - 1;
; z# V; C6 r L# m - button_next.setAttribute('row_count', index.toString());
* r- _/ w! ~6 u2 Z1 \& g - }, k1 g ]* G% U4 ~1 w
- if (index > lines.length - 1) {
6 b$ t1 P* k, a6 [5 J - index = 4;$ ^% K4 o e/ k$ V3 h
- button_next.setAttribute('row_count', index.toString());& l' M P3 ]) W3 j* {) _
- }
) q" q; W2 Y! s0 m- v- x9 x# p - let current_line = lines[index];2 ^% }9 r' _+ m6 [$ ?
- let text = current_line.slice(10, current_line.length - 1);
2 [ j% ?4 T+ k, J7 }3 C5 b - p.innerText = text;/ j: V+ g+ n2 x0 D4 ^5 u
- if (index < (lines.length - 1)) {, f/ @8 W2 Y' o0 p9 o+ l
- let next_index = index + 1;0 f. d1 Y# i& E
- let next_line = lines[next_index];: _5 Y9 z8 |0 J4 Y: `7 o
- let current_time = current_line.slice(1, 9);: C% R; }1 J4 r1 `% p9 {
- let current_time_min_sec = current_time.split(':');
' z1 O) b1 n- [! m Q5 T - let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);+ r/ }, H7 X) Z4 ~6 @: w9 J. G1 X9 T
- let next_time = next_line.slice(1, 9);
& \1 E: d, z6 o2 Z# M: R( Z2 ` - let next_time_min_sec = next_time.split(':');6 C1 c% D* `0 B. D- ^, T+ Y! j
- let end = parseFloat(next_time_min_sec[0]) * 60 + parseFloat(next_time_min_sec[1]) - 0.25;
# J: ]# X5 U+ X. t( ^* w: Z1 G - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start + "," + end);
: m) N5 B9 A! v$ q, t - const play1 = audio.play();
. ?2 B" i4 I# i/ s - } else {
- k2 E, |# K# l" U9 ? - let current_time = current_line.slice(1, 9);0 V! d; w4 _( L8 a/ e
- let current_time_min_sec = current_time.split(':');$ ^3 V' q4 r# [3 d
- let start = parseFloat(current_time_min_sec[0]) * 60 + parseFloat(current_time_min_sec[1]);
# }6 z" q' G- A2 |; d R - let audio = new Audio("NCE1-" + lesson + ".mp3" + "#t=" + start);
/ Q& c) H7 J$ c" f - const play2 = audio.play();
. y! Q- p# s, k - }
6 d6 ]- @# x' p1 v: b/ }* |0 k - }
复制代码
$ ^! p# [. T+ `: n* ]! z+ \# o$ r: N; E' V4 Y8 a, Q# M4 F
使用的时候,把下面网盘链接里面的Anki卡片导入,然后把新概念的音频和字幕文件拷贝到Anki的collection.media文件夹里面,如果不知道media文件夹的位置在网上搜索一下。
5 @6 l/ u' F3 O) l @' C* j# y; ?; [ S3 G' L2 \% t
- /*区块全局样式*/& Q5 c* m3 E; O5 K* O5 r
- .section {
0 j1 p2 K4 i! F4 ~+ H - background-color : #f6f6f6; /*背景颜色-#f6f6f6*/
( g6 [7 C; p$ @8 ? - border : 2px solid #3f3f41; /*边缘样式-实线2px*/
/ |! E0 b( K; K/ `* x8 _ - border-radius : 3px; /*圆角幅度-3px*/6 ?3 g, j6 s0 A' H5 j3 J2 y/ O8 D+ G
- margin : 8px 8px; /*上下间隔-8px*/% k6 E/ |8 i0 J0 Q6 S6 U- }# }
- display : flex;
& V2 @/ } ]: Y! a( B# w$ ]5 p - flex-direction : column;, L/ n J' K1 g/ P
- height: 95vh;
5 Z' `( ]/ H$ M! j5 n* n7 | - }
( t0 { l# c Z! C+ I* n - 9 u, h( v* R$ W
- /*区块全局样式*/
c6 C0 f8 E* f- _+ o - .mobile .section {6 g) I. e8 R4 H6 }
- background-color : #f6f6f6; /*背景颜色-#f6f6f6*/) O; X& w Z8 g1 K/ [3 m
- border : 2px solid #3f3f41; /*边缘样式-实线2px*/
3 t$ T3 [- D9 u& Z, g( i - border-radius : 3px; /*圆角幅度-3px*/# Z. C' A# P; |2 D: q3 B
- margin : 8px 8px; /*上下间隔-8px*/
( V# O6 n! V4 S- r1 L9 r+ b - display : flex;' \2 I0 @; E6 Q, O! M. c! T
- flex-direction : column;
3 Q0 y# @/ u4 w1 Z2 k1 j - height: 77vh;' G+ [: z9 S( A$ O+ Q' k. I
- }
复制代码 . t$ b2 w& Q9 z+ h
在模板里面的css部分,可以调节整个区块的大小,修改height后面的数值来调节。前面有.mobile的是对移动设备的设置。
9 z5 j$ b: p, H" F
9 W% V0 f/ W3 H' H1 Q你也可以把这个模板稍加修改就可以添加新概念后面的几本书。8 R6 [- g8 V# |" S: v& Z* H2 m
! ? m# t# `( r( [9 p
( m* Q" p5 i7 u$ J* _# Q; N' o
注意,因为iOS版本的Anki不会自动重新加载js,所以到第二张卡片的时候就会按钮显示不出来,退到deck界面再进去就可以了。 |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?免费注册
x
评分
-
2
查看全部评分
-
|